2 * LiveML - LiveML is screen(graphic) controling library using XML.
5 * Copyright (C) 2010 Nothan
6 * http://github.com/nothan/liveml/
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * private@nothan.xrea.jp
27 * http://tsuioku-denrai.xrea.jp/
30 #include "livemlrunner.h"
33 float LMLParameter::getFloat(size_t index)
35 DCODE(printf("LMLParameter::getFloat(%d)\n", index);)
36 return fixed_float_to_float(getFixedFloat(index));
39 int LMLParameter::getInteger(size_t index)
41 DCODE(printf("LMLParameter::getInteger(%d)\n", index);)
42 return fixed_float_to_int(getFixedFloat(index));
45 fixed_float LMLParameter::getFixedFloat(size_t index)
47 DCODE(printf("LMLParameter::getFloat(%d)\n", index);)
48 return calcu_decode((const char*)param->get(index), LiveMLRunner::variableNumericDecoder, (void*)this);
51 const char* LMLParameter::getText(size_t index)
53 DCODE(printf("LMLParameter::getText(%d)\n", index);)
54 return text_decode((const char*)param->get(index), LiveMLRunner::variableStringDecoder, (void*)this);
57 bool LMLParameter::has(size_t index)
59 DCODE(printf("LMLParameter::has(%d)\n", index);)
60 return param->has(index);
63 const void* LMLParameter::get(size_t index)
65 DCODE(printf("LMLParameter::getTag(%d)\n", index);)
66 return param->get(index);
69 Tag* LMLParameter::getTag(size_t index)
71 DCODE(printf("LMLParameter::getTag(%d)\n", index);)
72 return param->getTag(index);
75 const char* LMLParameter::getString(size_t index)
77 DCODE(printf("LMLParameter::getString(%d)\n", index);)
78 return param->getString(index);
82 fixed_float LiveMLRunner::variableNumericDecoder(variable_size id, void *work)
84 LMLParameter ¶m = *(LMLParameter*)work;
85 DCODE(printf("LiveMLRunner::variableNumeric(%d)\n", id);)
87 return param.getVariable(id)->getFixedFloat(id);
89 const char* LiveMLRunner::variableStringDecoder(variable_size id, void *work)
91 LMLParameter ¶m = *(LMLParameter*)work;
92 DCODE(printf("LiveMLRunner::variableString(%d)\n", id);)
94 return param.getVariable(id)->getString(id);
101 return LML_CMDRTN_NEXT;
104 LML_CMDFUNC(action_close)
106 DCODE(printf("\"%s\" action closed [address: %x]\n", param.getTag(0)->param.getString(0), param.actionStack->current());)
107 param.actionStack->close();
108 DCODE(printf("current address is %x[has: %d]\n", param.actionStack->current(), param.actionStack->has());)
110 return LML_CMDRTN_STOP | LML_CMDRTN_REACTION;
113 LML_CMDFUNC(event_close)
115 DCODE(printf("\"%s\" event closed [address: %x]\n", param.getTag(0)->param.getString(0), param.actionStack->current());)
116 param.actionStack->close();
117 DCODE(printf("current address is %x[has: %d]\n", param.actionStack->current(), param.actionStack->has());)
119 return LML_CMDRTN_STOP | LML_CMDRTN_REACTION;
124 printf(param.getText(0));
127 return LML_CMDRTN_NEXT;
132 DCODE(printf("active [%s]\n", param.getText(0));)
133 LMLActorObject *obj = param.runner->addActor(param.getText(0));
136 variable_size id = *(variable_size*)param.get(1);
137 size_t objId = param.runner->getActorObjectId(*obj);
139 param.getVariable(id)->setFixedFloat(id, int_to_fixed_float((int)objId));
142 return LML_CMDRTN_NEXT;
147 *param.actionStack->repeatCounter.push_back() = param.has(1) ? param.getInteger(1) : -1;
149 return LML_CMDRTN_NEXT;
152 LML_CMDFUNC(repeat_close)
154 unsigned int *counter = param.actionStack->repeatCounter.back();
157 param.actionStack->current()->tag = param.getTag(0);
158 if (param.getTag(0)->param.has(1)) (*counter)--;
160 else param.actionStack->repeatCounter.remove(counter);
162 return LML_CMDRTN_NEXT;
165 LML_CMDFUNC(rcontinue)
167 Tag **t = ¶m.actionStack->current()->tag;
168 *t = param.getTag(0)->param.getTag(0);
170 return LML_CMDRTN_NULL;
175 if (param.actionStack->repeatCounter.back() == NULL) return LML_CMDRTN_NEXT;
176 (*param.actionStack->repeatCounter.back()) = 0;
178 return rcontinue(param);
183 if (param.actionStack->waitCounter) param.actionStack->waitCounter--;
184 else param.actionStack->waitCounter = param.getInteger(0);
186 return param.actionStack->waitCounter ? LML_CMDRTN_STOP : LML_CMDRTN_NEXT;
191 param.runner->dropActor(*param.obj);
193 return LML_CMDRTN_STOP;
198 variable_size id = *(variable_size*)param.get(0);
199 DCODE(printf("var[%d] = ", id);)
200 param.getVariable(id)->setFixedFloat(id, param.getFixedFloat(1));
202 return LML_CMDRTN_NEXT;
205 LML_CMDFUNC(callAction)
207 DCODE(printf("callAction: %s\n", param.getText(0));)
211 obj = param.runner->getActorObject(param.getInteger(1));
218 if (!obj->setAction(param.getText(0)))
220 ActionParser *ap = param.runner->parser->actionContainer[param.getText(0)];
224 if(obj != param.obj && obj->activeActionStack.has())
226 LMLParameter p(NULL, param.runner, obj, &obj->activeActionStack);
227 LML_CMDRTN result = param.runner->runAction(p);
229 return LML_CMDRTN_NEXT;
232 return LML_CMDRTN_STOP | LML_CMDRTN_NEXT | LML_CMDRTN_REACTION;
235 LML_CMDFUNC(callEvent)
237 DCODE(printf("callEvent: %s\n", param.getText(0));)
241 obj = param.runner->getActorObject(param.getInteger(1));
248 if (param.obj != obj || ¶m.obj->activeActionStack == param.actionStack)
250 param.runner->callEvent(*obj, param.getText(0));
251 return LML_CMDRTN_NEXT;
254 obj->setEvent(param.getText(0));
256 return LML_CMDRTN_STOP | LML_CMDRTN_NEXT | LML_CMDRTN_REACTION;
260 LiveMLRunner::LiveMLRunner(LiveMLParser *p)
262 DCODE(printf("LiveMLRunner::LiveMLRunner() begin.\n");)
264 setMaxActors(1000); // unauthorised
265 text_decode_init(1024); // unauthorised
266 _commandFuncs.resize(parser->countTagType());
268 registerCommand("print", lmlCommand::print);
269 registerCommand("active", lmlCommand::active);
270 registerCommand("action", lmlCommand::action, lmlCommand::action_close);
271 registerCommand("event", NULL, lmlCommand::event_close);
272 registerCommand("repeat", lmlCommand::repeat, lmlCommand::repeat_close);
273 registerCommand("continue", lmlCommand::rcontinue);
274 registerCommand("break", lmlCommand::rbreak);
275 // registerCommand("if", lmlCommand::rif);
276 registerCommand("wait", lmlCommand::wait);
277 registerCommand("exit", lmlCommand::exit);
278 registerCommand("var", lmlCommand::var);
279 registerCommand("callAction", lmlCommand::callAction);
280 registerCommand("callEvent", lmlCommand::callEvent);
281 DCODE(printf("LiveMLRunner::LiveMLRunner() end.\n");)
284 LiveMLRunner::~LiveMLRunner()
286 text_decode_release();
289 bool LiveMLRunner::registerCommand(
291 LML_CMDRTN (*func)(LMLParameter&),
292 LML_CMDRTN (*closeFunc)(LMLParameter&)
295 tag_type id = parser->getTagTypeId(name);
296 if (id == UNameContainer<TagType>::NOTFOUND) return false;
298 _commandFuncs[id].func = func;
299 _commandFuncs[id].closeFunc = closeFunc;
304 LML_CMDRTN LiveMLRunner::runCommand(LMLParameter ¶m, Tag *tag)
306 LML_CMDRTN (*func)(LMLParameter&) = NULL;
307 TagType *rt = tag->type;
309 DCODE(printf("LiveMLRunner::runCommand()\n");)
313 rt = tag->param.getTag(0)->type;
314 func = _commandFuncs[rt->id].closeFunc;
318 func = _commandFuncs[rt->id].func;
321 LML_CMDRTN result = LML_CMDRTN_NEXT;
325 if (tag->type == NULL) printf("execute command: %s[close]\n", rt->getName().c_str());
326 else printf("execute command: %s\n", rt->getName().c_str());
328 param.param = &tag->param;
329 result = (*func)(param);
332 if (tag->type == NULL) printf("finish command: %s[close]\n", rt->getName().c_str());
333 else printf("finish command: %s\n", rt->getName().c_str());
336 DCODE(else printf(tag->type == NULL ? "not execute command: %s[id: %d][close]\n" : "not execute command: %s[id: %d]\n", rt->getName().c_str());)
341 LML_CMDRTN LiveMLRunner::runAction(LMLParameter& param)
343 LML_CMDRTN result = LML_CMDRTN_NULL;
344 ActiveAction *aa = param.actionStack->current();
346 DCODE(printf("LiveMLRunner::runAction()\n");)
348 if (aa == NULL) return result;
349 while (aa->tag != NULL)
351 result = runCommand(param, aa->tag);
353 if (result & LML_CMDRTN_NEXT) aa->tag = list_next(aa->tag);
354 if (result & LML_CMDRTN_STOP) break;
360 void LiveMLRunner::callEvent(LMLActorObject &obj, const char *name)
362 callEvent(obj, (event_type)parser->eventTypeContainer.getId(name));
365 void LiveMLRunner::callEvent(LMLActorObject &obj, event_type id)
367 obj.activeEventStack.clear();
368 if (!obj.setEvent(id)) return;
370 LMLParameter param(NULL, this, &obj, (ActiveActionStack*)&obj.activeEventStack);
373 LML_CMDRTN result = runAction(param);
375 if ((result & LML_CMDRTN_STOP) && !(result & LML_CMDRTN_REACTION)) break;
377 while (param.actionStack->has());
380 void LiveMLRunner::callEvent(event_type id)
382 LMLActorObject *actor = _actorList.front();
385 LMLActorObject *actorNext = list_next(actor);
386 callEvent((LMLActorObject&)*actor, id);
391 bool LiveMLRunner::runActiveActions(LMLActorObject &obj)
393 LMLParameter param(NULL, this, &obj, &obj.activeActionStack);
395 while (param.actionStack->has())
397 LML_CMDRTN result = runAction(param);
399 if ((result & LML_CMDRTN_STOP) && !(result & LML_CMDRTN_REACTION)) break;
402 return param.actionStack->has();
405 bool LiveMLRunner::runObject(LMLActorObject &obj)
407 return runActiveActions(obj);
410 LMLActorObject* LiveMLRunner::addActor(const char *name)
412 DCODE(printf("add actor: start\n");)
416 if (parser->actorContainer[name]->tag->param.has(1))
418 type = *(size_t*)parser->actorContainer[name]->tag->param.get(1);
421 obj = createActor(type);
422 obj->parser = parser->actorContainer[name];
423 obj->setAction((action_type)0);
424 callEvent(*obj, (event_type)0);
425 DCODE(printf("add actor: end[%x]\n", obj);)
430 void LiveMLRunner::dropActor(LMLActorObject &obj)
432 DCODE(printf("LiveMLRunner::dropActor(%x)\n", &obj);)
433 callEvent(obj, (event_type)1);
435 _actorList.remove(&obj);
438 bool LiveMLRunner::run(void)
440 bool running = false;
442 DCODE(printf("LiveMLRunner::run()\n");)
444 LMLActorObject *actor = _actorList.front();
445 LMLActorObject *actorPrev, *actorNext;
448 DCODE(printf("execute actor: start [%x]\n", actor);)
449 actorPrev = list_prev(actor);
450 actorNext = list_next(actor);
451 running |= runObject(*actor);
452 if (NULL == actorNext)
454 if ((LMLActorObject*)_actorList.allocator()->get_free() == actor)
460 actorNext = list_next(actor);
463 DCODE(printf("execute actor: end [%x]\n", actor);)
470 LMLActorObject* LiveMLRunner::getActorObject(size_t id)
472 return (*_actorList.allocator())[id];
475 size_t LiveMLRunner::getActorObjectId(LMLActorObject &obj)
477 return ((char*)&obj - (char*)_actorList.allocator()->pool()) / sizeof(list_item<LMLActorObject>);
480 void LiveMLRunner::setMaxActors(size_t size)
482 _repeatAllocator.resize(size * 10);
483 _actionAllocator.resize(size * 10);
484 _numericVariableAllocator.resize(size * VAR_SCOPE_MAX * 50);
486 variable.numericList.allocator(&_numericVariableAllocator);
488 while (aa = (ActiveAction*)_actionAllocator.add())
490 aa->variable.numericList.allocator(&_numericVariableAllocator);
492 _actionAllocator.clear();
494 _actorList.resize(size);
497 LMLActorObject *obj = _actorList.push_back();
498 if (obj == NULL) break;
500 setObjectAllocators(*obj);
502 _actorList.clear(true);
505 void LiveMLRunner::setObjectAllocators(LMLActorObject &obj)
507 DCODE(printf("LiveMLRunner::setObjectAllocators(%x)\n", &obj);)
508 obj.setVariableAllocator(&_numericVariableAllocator);
509 obj.activeActionStack.list.allocator(&_actionAllocator);
510 obj.activeEventStack.list.allocator(&_actionAllocator);
511 obj.setRepeatAllocator(&_repeatAllocator);
514 LMLActorObject* LiveMLRunner::createActor(size_t type)
521 obj = _actorList.push_back(false);
524 obj = _actorList.front();
525 if (NULL != obj && obj->parser->tag->param.has(1) && 1 == *(size_t*)obj->parser->tag->param.get(1))
529 obj = _actorList.push_front(false);
537 LMLVariable* LMLParameter::getVariable(variable_size id)
539 DCODE(printf("LiveMLRunner::getVariable(%d[%d])\n", id, VAR_SCOPE_TYPE(id));)
540 LMLVariable *v = &runner->variable;
541 switch (VAR_SCOPE_TYPE(id))
543 case VAR_SCOPE_LOCAL:
544 DCODE(printf("is local variable\n");)
545 v = &actionStack->current()->variable;
547 case VAR_SCOPE_MEMBER:
548 DCODE(printf("is member variable\n");)