OSDN Git Service

modified child node execution way
[liveml/LiveML.git] / src / livemlrunner.h
1 /** * LiveML - LiveML is screen(graphic) controling library using XML.
2  *
3  * LGPL License
4  * Copyright (C) 2010 Nothan
5  * http://github.com/nothan/liveml/
6  * All rights reserved.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Library General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Library General Public
19  *  License along with this library; if not, write to the Free
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  * Nothan
23  * private@nothan.xrea.jp
24  *
25  * Tsuioku Denrai
26  * http://tsuioku-denrai.xrea.jp/
27  */
28
29 #ifndef __LIVEMLRUNNER_H__
30 #define __LIVEMLRUNNER_H__
31
32 #include "livemlparser.h"
33 #include "list.hpp"
34 #include "bool_list.hpp"
35
36 #define LML_CMDFUNC(name) LML_CMDRTN name(LMLParameter &param)
37
38 typedef int LML_CMDRTN;
39 enum
40 {
41   LML_CMDRTN_NULL = 0x00,
42   LML_CMDRTN_STOP = 0x01,
43   LML_CMDRTN_NEXT = 0x02,
44   LML_CMDRTN_REACTION = 0x04,
45   LML_CMDRTN_CHILD = 0x08
46 };
47
48 class LiveMLRunner;
49
50 struct NumericVariable
51 {
52   variable_size id;
53   fixed_float value;
54 };
55
56 class LMLVariable
57 {
58   fixed_float* getNumeric(variable_size id)
59   {
60     DCODE(printf("LMLVariable::getNumeric(%d)\n", id);)
61     id = VAR_LOCAL_ID(id);
62     NumericVariable *v = numericList.front();
63
64     while (v)
65     {
66       if (v->id == id)
67       {
68         numericList.chain_front(v);
69         break;
70       }
71       v = list_next(v);
72     }
73
74     if (v == NULL)
75     {
76       DCODE(printf("added variable %d\n", id);)
77       v = numericList.push_front();
78             v->id = id;
79     }
80
81     return &v->value;
82   }
83
84 public:
85   list<NumericVariable> numericList;
86
87   void clear(void)
88   {
89     numericList.clear(true);
90   }
91
92   void setFixedFloat(variable_size id, fixed_float v)
93   {
94     DCODE(printf("LMLVariable::setFixedFloat(%d) = %d\n", id, v);)
95     *getNumeric(id) = v;
96   }
97
98   void setString(variable_size id, const char *v)
99   {
100   }
101
102   fixed_float getFixedFloat(variable_size id)
103   {
104     DCODE(printf("LMLVariable::getFixedFloat(%d) = %d\n", id, *getNumeric(id));)
105     return *getNumeric(id);
106   }
107
108   const char* getString(variable_size id)
109   {
110     return "";
111   }
112 };
113
114 template <class T>
115 class ActiveStack
116 {
117 public:
118   list<T> list;
119
120   T* current(void)
121   {
122     return list.back();
123   }
124
125   T* front(void)
126   {
127     return list.front();
128   }
129
130   T* add(void)
131   {
132     return list.push_back(false);
133   }
134
135   void close(T *item)
136   {
137     item->clear();
138     list.remove(item);
139   }
140
141   void close()
142   {
143     close(current());
144   }
145
146   void clear(void)
147   {
148     T *item = front();
149     while (item != NULL)
150     {
151        item->clear();
152        item = list_next(item);
153     }
154     list.clear(true);
155   }
156
157   bool has(void)
158   {
159     return current() != NULL;
160   }
161 };
162
163 class ResumeTagStack : public ActiveStack<XMLElement*>
164 {
165 public:
166   void close(void)
167   {
168     list.remove(current());
169   }
170
171   void clear(void)
172   {
173     list.clear(true);
174   }
175 };
176
177 class ChildAction
178 {
179 public:
180   ActionParser *action;
181   XMLElement *tag;
182   ResumeTagStack resumeTagStack;
183   // local variable
184   LMLVariable variable;
185
186   void clear(void)
187   {
188     resumeTagStack.clear();
189     variable.clear();
190   }
191 };
192
193 class ChildActionStack : public ActiveStack<ChildAction>
194 {
195 };
196
197 class ActiveAction
198 {
199 public:
200   ChildActionStack childActionStack;
201   unsigned int waitCounter;
202   ::list<unsigned int> repeatCounter;
203
204   void clear(void)
205   {
206     childActionStack.clear();
207     waitCounter = 0;
208     repeatCounter.clear(true);
209   }
210
211   void close(void)
212   {
213     childActionStack.close();
214   }
215
216   bool has(void)
217   {
218     return childActionStack.has();
219   }
220
221   ChildAction* current(void)
222   {
223     return childActionStack.current();
224   }
225
226   ChildAction* front(void)
227   {
228      return childActionStack.front();
229   }
230
231   ChildAction* add()
232   {
233     return childActionStack.add();
234   }
235
236   bool add(ActionParser *action)
237   {
238     if (action == NULL) return false;
239
240     ChildAction *ab = add();
241     ab->action = action;
242     ab->tag = action->tag;
243
244     return true;
245   }
246 };
247
248 class ActiveActionStack : public ActiveStack<ActiveAction>
249 {
250 public:
251   void clear(void)
252   {
253     ActiveStack<ActiveAction>::clear();
254   }
255
256   ActiveAction* add(ActionParser *action)
257   {
258     ActiveAction *aa = NULL;
259     
260     if (action->unionId != UNameContainer<UNameItem>::NOTFOUND)
261     {
262       aa = current();
263       while (aa != NULL)
264       {
265         if (aa->front()->action->unionId == action->unionId)
266         {
267           if (aa->front()->action == action) return aa;
268           aa->clear();
269           break;
270         }
271         aa = list_prev(aa);
272       }
273     }
274     if (aa == NULL)
275     {
276       aa = ActiveStack<ActiveAction>::add();
277     }
278     aa->add(action);
279
280     DCODE(printf("added action[address: %x]\n", aa));
281
282     return aa;
283   }
284 };
285
286 class ActiveEventStack : public ActiveStack<ActiveAction>
287 {
288 public:
289   ActiveAction* add(ActionParser *action)
290   {
291     ActiveAction *aa = ActiveStack<ActiveAction>::add();
292     aa->add(action);
293
294     DCODE(printf("added action[address: %x]\n", aa));
295
296     return aa;
297   }
298 };
299
300 class LMLActorObject
301 {
302 public:
303   ActiveActionStack activeActionStack;
304   ActiveEventStack activeEventStack;
305   TagAct *parser;
306   // member variable
307   LMLVariable variable;
308
309   LMLActorObject(void)
310   {
311   }
312
313   ~LMLActorObject()
314   {
315     release();
316   }
317
318   void release(void)
319   {
320     parser = NULL;
321     variable.clear();
322     activeActionStack.clear();
323     activeEventStack.clear();
324   }
325
326   void setVariableAllocator(list_allocator<NumericVariable> *alloc)
327   {
328     variable.numericList.allocator(alloc);
329   }
330
331   bool addAction(ActionParser *action)
332   {
333     DCODE(printf("LMLActorObject::setAction(%x)\n", action);)
334     if (action == NULL) return false;
335
336     activeActionStack.add(action);
337
338     return true;
339   }
340   bool addAction(action_type type)
341   {
342     DCODE(printf("LMLActorObject::setAction(%d)\n", type);)
343     ActionParser *action = parser->actionContainer[type];
344     if (action->tag == NULL) return false;
345
346     addAction(action);
347     return true;
348   }
349   bool addAction(const char *name)
350   {
351     DCODE(printf("LMLActorObject::setActionByName(%s)\n", name);)
352     return addAction(parser->actionContainer[name]);
353   }
354
355   bool setEvent(EventParser *event)
356   {
357     DCODE(printf("LMLActorObject::setEvent(%x)\n", event);)
358     if (event == NULL) return false;
359
360     activeEventStack.add((ActionParser*)event);
361
362     return true;
363   }
364
365   bool setEvent(event_type type)
366   {
367     DCODE(printf("LMLActorObject::setEvent(%d)\n", type);)
368     EventParser *event = parser->eventContainer[type];
369           if (event->tag == NULL) return false;
370
371     return setEvent(event);
372   }
373
374   bool setEvent(const char *name)
375   {
376     DCODE(printf("LMLActorObject::setActionByName(%s)\n", name);)
377     return setEvent(parser->eventContainer[name]);
378   }
379
380   void endAction(const char *name)
381   {
382     ActiveAction *aa = activeActionStack.current();
383     while (aa)
384     {
385       if (!strcmp(aa->front()->action->getName(), name))
386       {
387         activeActionStack.close(aa);
388         return;
389       }
390       aa = list_prev(aa);
391     }
392   }
393 };
394
395 class LMLParameter
396 {
397   friend class LiveMLRunner;
398   Parameter *param;
399 public:
400   LiveMLRunner *runner;
401   LMLActorObject *obj;
402   ActiveAction *action;
403   bool close;
404
405   LMLParameter(Parameter *param, LiveMLRunner *runner, LMLActorObject *obj, ActiveAction *action)
406   {
407     this->param = param;
408     this->runner = runner;
409     this->obj = obj;
410     this->action = action;
411     this->close = false;
412   }
413
414   LMLVariable* getVariable(variable_size);
415
416   bool has(size_t);
417   XMLParameter* get(size_t);
418 };
419
420 class LiveMLRunner
421 {
422   struct FuncPtr
423   {
424     LML_CMDRTN (*func)(LMLParameter&);
425   };
426
427   list<LMLActorObject> _actorList;
428   vector<FuncPtr> _commandFuncs;
429
430   list_allocator<ChildAction> _childActionAllocator;
431   list_allocator<ActiveAction> _actionAllocator;
432   list_allocator<unsigned int> _repeatAllocator;
433   list_allocator<NumericVariable> _numericVariableAllocator;
434   list_allocator<XMLElement*> _tagPtrAllocator;
435
436   void setObjectAllocators(LMLActorObject&);
437
438 public:
439   LiveMLParser *parser;
440   // global variable
441   LMLVariable variable;
442
443   LiveMLRunner(LiveMLParser*);
444   virtual ~LiveMLRunner();
445
446   bool registerCommand(
447     const char*,
448     LML_CMDRTN (*)(LMLParameter&)
449   );
450
451   void setMaxActors(size_t);
452   LMLActorObject* addActor(const char*);
453   void dropActor(LMLActorObject&);
454
455   LML_CMDRTN runCommand(LMLParameter&, XMLElement*);
456   LML_CMDRTN runChildAction(LMLParameter&);
457   LML_CMDRTN runAction(LMLParameter&);
458   void callEvent(LMLActorObject&, event_type);
459   void callEvent(LMLActorObject&, const char*);
460   void callEvent(event_type);
461   void callEvent(EventType*);
462   bool runActiveActions(LMLActorObject&);
463   bool runObject(LMLActorObject&);
464   bool run(void);
465   LMLActorObject* getActorObject(size_t);
466   size_t getActorObjectId(LMLActorObject&);
467
468   virtual LMLActorObject* createActor(size_t);
469
470   static fixed_float calcuDecode(const char**, void*);
471   static const char* variableStringDecoder(variable_size, void*);
472 };
473
474 #endif // __LIVEMLRUNNER_H__