Trigger.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. wait = 0;
  165. Variable *var = m.zVariable( "__return__" );
  166. return isTrue( var );
  167. }
  168. Bedingung *Bedingung::getThis()
  169. {
  170. ref++;
  171. return this;
  172. }
  173. Bedingung *Bedingung::release()
  174. {
  175. if( !--ref )
  176. delete this;
  177. return 0;
  178. }
  179. Trigger::Trigger( int id, const char *name, int ereignisAnzahl, EreignisTyp *ereignisse, RCArray< Bedingung > *bedingungen, RCArray< Aktion > *aktionen )
  180. : Variable( TRIGGER )
  181. {
  182. this->id = id;
  183. this->name = name;
  184. this->ereignisAnzahl = ereignisAnzahl;
  185. this->ereignisse = ereignisse;
  186. this->bedingungen = bedingungen;
  187. this->aktionen = aktionen;
  188. aktiv = 1;
  189. runCount = 0;
  190. }
  191. Trigger::~Trigger()
  192. {
  193. delete[]ereignisse;
  194. bedingungen->release();
  195. aktionen->release();
  196. }
  197. void Trigger::setAktiv( bool aktiv )
  198. {
  199. this->aktiv = aktiv;
  200. }
  201. bool Trigger::hatEreignis( EreignisTyp typ ) const
  202. {
  203. for( int i = 0; i < ereignisAnzahl; i++ )
  204. {
  205. if( ereignisse[ i ] == typ )
  206. return 1;
  207. }
  208. return 0;
  209. }
  210. int Trigger::getAktionAnzahl() const
  211. {
  212. return aktionen->getEintragAnzahl();
  213. }
  214. Aktion *Trigger::zAktion( int index ) const
  215. {
  216. return aktionen->z( index );
  217. }
  218. Aktion *Trigger::getAktion( int index ) const
  219. {
  220. return aktionen->get( index );
  221. }
  222. // return: 0, falls die bedingungen nicht erfüllt sind
  223. TriggerRun *Trigger::runTrigger( Ereignis *e, Spiel *zSpiel )
  224. {
  225. if( !aktiv )
  226. {
  227. e->release();
  228. return 0;
  229. }
  230. for( auto b = bedingungen->getIterator(); b; b++ )
  231. {
  232. if( !b->check( zSpiel, e ) )
  233. {
  234. e->release();
  235. return 0;
  236. }
  237. }
  238. runCount++;
  239. return new TriggerRun( (Trigger *)getThis(), e, zSpiel );
  240. }
  241. int Trigger::getId() const
  242. {
  243. return id;
  244. }
  245. int Trigger::getRuns() const
  246. {
  247. return runCount;
  248. }
  249. const char *Trigger::getName() const
  250. {
  251. return name.getText();
  252. }
  253. bool Trigger::istAktiv() const
  254. {
  255. return aktiv;
  256. }
  257. TriggerRun::TriggerRun( Trigger *trig, Ereignis *e, Spiel *zSpiel )
  258. {
  259. trigger = trig;
  260. ereignis = e;
  261. this->zSpiel = zSpiel;
  262. waitCount = 0;
  263. ref = 1;
  264. }
  265. TriggerRun::~TriggerRun()
  266. {
  267. trigger->release();
  268. ereignis->release();
  269. }
  270. // gibt 0 zurück, wenn der Auslöser vollständig durchgelaufen ist
  271. bool TriggerRun::runNext( double t )
  272. {
  273. if( waitCount > 0 )
  274. waitCount -= t;
  275. else
  276. {
  277. int current = counter.currentPosition();
  278. if( current >= trigger->getAktionAnzahl() )
  279. return 0;
  280. Aktion *ak = trigger->zAktion( current );
  281. if( !ak || ak->runNext( zSpiel, ereignis, &localMem, &counter, waitCount ) )
  282. counter.count();
  283. if( counter.currentPosition() >= trigger->getAktionAnzahl() )
  284. return 0;
  285. }
  286. return 1;
  287. }
  288. Trigger *TriggerRun::getTrigger() const
  289. {
  290. return (Trigger *)trigger->getThis();
  291. }
  292. TriggerRun *TriggerRun::getThis()
  293. {
  294. ref++;
  295. return this;
  296. }
  297. TriggerRun *TriggerRun::release()
  298. {
  299. if( !--ref )
  300. delete this;
  301. return 0;
  302. }