Trigger.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include "Trigger.h"
  2. #include "Gegenstand.h"
  3. VarPointer::VarPointer( const char *name, Variable *var )
  4. {
  5. this->name = name;
  6. this->var = var;
  7. ref = 1;
  8. }
  9. VarPointer::~VarPointer()
  10. {
  11. if( var )
  12. var->release();
  13. }
  14. Text VarPointer::getName() const
  15. {
  16. return name;
  17. }
  18. void VarPointer::setVariable( Variable *var )
  19. {
  20. if( this->var )
  21. this->var->release();
  22. this->var = var;
  23. }
  24. Variable *VarPointer::getVariable() const
  25. {
  26. return var ? var->getThis() : 0;
  27. }
  28. Variable *VarPointer::zVariable() const
  29. {
  30. return var;
  31. }
  32. VarPointer::operator Variable *( ) const
  33. {
  34. return var;
  35. }
  36. VarPointer *VarPointer::getThis()
  37. {
  38. ref++;
  39. return this;
  40. }
  41. VarPointer *VarPointer::release()
  42. {
  43. if( !--ref )
  44. delete this;
  45. return 0;
  46. }
  47. LocalMemory::LocalMemory()
  48. {
  49. ref = 1;
  50. }
  51. LocalMemory::~LocalMemory()
  52. {}
  53. void LocalMemory::setVar( const char *name, Variable *var )
  54. {
  55. for( auto v = vars.getIterator(); v; v++ )
  56. {
  57. if( v->getName().istGleich( name ) )
  58. {
  59. v->setVariable( var );
  60. return;
  61. }
  62. }
  63. vars.add( new VarPointer( name, var ) );
  64. }
  65. Variable *LocalMemory::getVariable( const char *name )
  66. {
  67. for( auto v = vars.getIterator(); v; v++ )
  68. {
  69. if( v->getName().istGleich( name ) )
  70. return v->getVariable();
  71. }
  72. return 0;
  73. }
  74. Variable *LocalMemory::zVariable( const char *name )
  75. {
  76. for( auto v = vars.getIterator(); v; v++ )
  77. {
  78. if( v->getName().istGleich( name ) )
  79. return v->zVariable();
  80. }
  81. return 0;
  82. }
  83. LocalMemory *LocalMemory::getThis()
  84. {
  85. ref++;
  86. return this;
  87. }
  88. LocalMemory *LocalMemory::release()
  89. {
  90. if( !--ref )
  91. delete this;
  92. return 0;
  93. }
  94. ProgramCounter::ProgramCounter()
  95. {
  96. current.add( 0 );
  97. depth = 0;
  98. ref = 1;
  99. }
  100. ProgramCounter::~ProgramCounter()
  101. {}
  102. void ProgramCounter::stepIn()
  103. {
  104. depth++;
  105. if( current.getEintragAnzahl() <= depth )
  106. current.add( 0 );
  107. }
  108. void ProgramCounter::count()
  109. {
  110. current.set( current.get( depth ) + 1, depth );
  111. while( depth + 1 < current.getEintragAnzahl() )
  112. current.remove( depth + 1 );
  113. }
  114. void ProgramCounter::stepOut()
  115. {
  116. depth--;
  117. }
  118. Text ProgramCounter::getUniqueString() const
  119. {
  120. Text ret = "__";
  121. for( int i = 0; i < depth; i++ )
  122. ret += Text( current.get( i ) ) + "__";
  123. return ret;
  124. }
  125. int ProgramCounter::currentPosition() const
  126. {
  127. return current.get( depth );
  128. }
  129. ProgramCounter *ProgramCounter::getThis()
  130. {
  131. ref++;
  132. return this;
  133. }
  134. ProgramCounter *ProgramCounter::release()
  135. {
  136. if( !--ref )
  137. delete this;
  138. return 0;
  139. }
  140. Bedingung::Bedingung( Aktion *expression )
  141. {
  142. this->expression = expression;
  143. ref = 1;
  144. }
  145. Bedingung::~Bedingung()
  146. {
  147. if( expression )
  148. expression->release();
  149. }
  150. void Bedingung::setExpression( Aktion *expr )
  151. {
  152. if( expression )
  153. expression->release();
  154. expression = expr;
  155. }
  156. bool Bedingung::check( Spiel *zSpiel, Ereignis *zEreignis )
  157. {
  158. if( !expression )
  159. return 1;
  160. double wait;
  161. ProgramCounter c;
  162. LocalMemory m;
  163. while( !expression->runNext( zSpiel, zEreignis, &m, &c, wait ) );
  164. Variable *var = m.zVariable( "__return__" );
  165. return isTrue( var );
  166. }
  167. Bedingung *Bedingung::getThis()
  168. {
  169. ref++;
  170. return this;
  171. }
  172. Bedingung *Bedingung::release()
  173. {
  174. if( !--ref )
  175. delete this;
  176. return 0;
  177. }
  178. Trigger::Trigger( int id, const char *name, int ereignisAnzahl, EreignisTyp *ereignisse, RCArray< Bedingung > *bedingungen, RCArray< Aktion > *aktionen )
  179. : Variable( TRIGGER )
  180. {
  181. this->id = id;
  182. this->name = name;
  183. this->ereignisAnzahl = ereignisAnzahl;
  184. this->ereignisse = ereignisse;
  185. this->bedingungen = bedingungen;
  186. this->aktionen = aktionen;
  187. aktiv = 1;
  188. runCount = 0;
  189. }
  190. Trigger::~Trigger()
  191. {
  192. delete[]ereignisse;
  193. bedingungen->release();
  194. aktionen->release();
  195. }
  196. void Trigger::setAktiv( bool aktiv )
  197. {
  198. this->aktiv = aktiv;
  199. }
  200. bool Trigger::hatEreignis( EreignisTyp typ ) const
  201. {
  202. for( int i = 0; i < ereignisAnzahl; i++ )
  203. {
  204. if( ereignisse[ i ] == typ )
  205. return 1;
  206. }
  207. return 0;
  208. }
  209. int Trigger::getAktionAnzahl() const
  210. {
  211. return aktionen->getEintragAnzahl();
  212. }
  213. Aktion *Trigger::zAktion( int index ) const
  214. {
  215. return aktionen->z( index );
  216. }
  217. Aktion *Trigger::getAktion( int index ) const
  218. {
  219. return aktionen->get( index );
  220. }
  221. // return: 0, falls die bedingungen nicht erfüllt sind
  222. TriggerRun *Trigger::runTrigger( Ereignis *e, Spiel *zSpiel )
  223. {
  224. if( !aktiv )
  225. {
  226. e->release();
  227. return 0;
  228. }
  229. for( auto b = bedingungen->getIterator(); b; b++ )
  230. {
  231. if( !b->check( zSpiel, e ) )
  232. {
  233. e->release();
  234. return 0;
  235. }
  236. }
  237. runCount++;
  238. return new TriggerRun( (Trigger *)getThis(), e, zSpiel );
  239. }
  240. int Trigger::getId() const
  241. {
  242. return id;
  243. }
  244. int Trigger::getRuns() const
  245. {
  246. return runCount;
  247. }
  248. const char *Trigger::getName() const
  249. {
  250. return name.getText();
  251. }
  252. bool Trigger::istAktiv() const
  253. {
  254. return aktiv;
  255. }
  256. TriggerRun::TriggerRun( Trigger *trig, Ereignis *e, Spiel *zSpiel )
  257. {
  258. trigger = trig;
  259. ereignis = e;
  260. this->zSpiel = zSpiel;
  261. waitCount = 0;
  262. ref = 1;
  263. }
  264. TriggerRun::~TriggerRun()
  265. {
  266. trigger->release();
  267. ereignis->release();
  268. }
  269. // gibt 0 zurück, wenn der Auslöser vollständig durchgelaufen ist
  270. bool TriggerRun::runNext( double t )
  271. {
  272. if( waitCount > 0 )
  273. waitCount -= t;
  274. else
  275. {
  276. int current = counter.currentPosition();
  277. if( current >= trigger->getAktionAnzahl() )
  278. return 0;
  279. Aktion *ak = trigger->zAktion( current );
  280. if( !ak || ak->runNext( zSpiel, ereignis, &localMem, &counter, waitCount ) )
  281. counter.count();
  282. if( counter.currentPosition() >= trigger->getAktionAnzahl() )
  283. return 0;
  284. }
  285. return 1;
  286. }
  287. Trigger *TriggerRun::getTrigger() const
  288. {
  289. return (Trigger *)trigger->getThis();
  290. }
  291. TriggerRun *TriggerRun::getThis()
  292. {
  293. ref++;
  294. return this;
  295. }
  296. TriggerRun *TriggerRun::release()
  297. {
  298. if( !--ref )
  299. delete this;
  300. return 0;
  301. }