Sequence.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. // Script Command Sequences
  2. //
  3. // -- jweier
  4. // this include must remain at the top of every Icarus CPP file
  5. #include "stdafx.h"
  6. #include "IcarusImplementation.h"
  7. #include "BlockStream.h"
  8. #include "Sequence.h"
  9. #define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); a++ )
  10. #define STL_INSERT( a, b ) a.insert( a.end(), b );
  11. inline CSequence::CSequence( void )
  12. {
  13. m_numCommands = 0;
  14. // m_numChildren = 0;
  15. m_flags = 0;
  16. m_iterations = 1;
  17. m_parent = NULL;
  18. m_return = NULL;
  19. }
  20. CSequence::~CSequence( void )
  21. {
  22. assert(!m_commands.size());
  23. //assert(!m_numChildren);
  24. }
  25. /*
  26. -------------------------
  27. Create
  28. -------------------------
  29. */
  30. CSequence *CSequence::Create( void )
  31. {
  32. CSequence *seq = new CSequence;
  33. //TODO: Emit warning
  34. assert(seq);
  35. if ( seq == NULL )
  36. return NULL;
  37. seq->SetFlag( SQ_COMMON );
  38. return seq;
  39. }
  40. /*
  41. -------------------------
  42. Delete
  43. -------------------------
  44. */
  45. void CSequence::Delete( CIcarus* icarus )
  46. {
  47. block_l::iterator bi;
  48. sequence_l::iterator si;
  49. //Notify the parent of the deletion
  50. if ( m_parent )
  51. {
  52. m_parent->RemoveChild( this );
  53. }
  54. //Clear all children
  55. if ( m_children.size() > 0 )
  56. {
  57. /*for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
  58. {
  59. (*iterSeq).second->SetParent( NULL );
  60. }*/
  61. for ( si = m_children.begin(); si != m_children.end(); si++ )
  62. {
  63. (*si)->SetParent( NULL );
  64. }
  65. }
  66. m_children.clear();
  67. //m_childrenMap.clear();
  68. //Clear all held commands
  69. for ( bi = m_commands.begin(); bi != m_commands.end(); bi++ )
  70. {
  71. (*bi)->Free(icarus);
  72. delete (*bi); //Free() handled internally -- not any more!!
  73. }
  74. m_commands.clear();
  75. }
  76. /*
  77. -------------------------
  78. AddChild
  79. -------------------------
  80. */
  81. void CSequence::AddChild( CSequence *child )
  82. {
  83. assert( child );
  84. if ( child == NULL )
  85. return;
  86. m_children.insert( m_children.end(), child );
  87. // m_childrenMap[ m_numChildren ] = child;
  88. // m_numChildren++;
  89. }
  90. /*
  91. -------------------------
  92. RemoveChild
  93. -------------------------
  94. */
  95. void CSequence::RemoveChild( CSequence *child )
  96. {
  97. assert( child );
  98. if ( child == NULL )
  99. return;
  100. m_children.remove( child );
  101. //Remove the child
  102. /* sequenceID_m::iterator iterSeq = m_childrenMap.find( child->GetID() );
  103. if ( iterSeq != m_childrenMap.end() )
  104. {
  105. m_childrenMap.erase( iterSeq );
  106. }
  107. m_numChildren--;*/
  108. }
  109. /*
  110. -------------------------
  111. HasChild
  112. -------------------------
  113. */
  114. bool CSequence::HasChild( CSequence *sequence )
  115. {
  116. sequence_l::iterator ci;
  117. for ( ci = m_children.begin(); ci != m_children.end(); ci++ )
  118. {
  119. if ( (*ci) == sequence )
  120. return true;
  121. if ( (*ci)->HasChild( sequence ) )
  122. return true;
  123. }
  124. /* sequenceID_m::iterator iterSeq = NULL;
  125. for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
  126. {
  127. if ( ((*iterSeq).second) == sequence )
  128. return true;
  129. if ( (*iterSeq).second->HasChild( sequence ) )
  130. return true;
  131. }*/
  132. return false;
  133. }
  134. /*
  135. -------------------------
  136. SetParent
  137. -------------------------
  138. */
  139. void CSequence::SetParent( CSequence *parent )
  140. {
  141. m_parent = parent;
  142. if ( parent == NULL )
  143. return;
  144. //Inherit the parent's properties (this avoids messy tree walks later on)
  145. if ( parent->m_flags & SQ_RETAIN )
  146. m_flags |= SQ_RETAIN;
  147. if ( parent->m_flags & SQ_PENDING )
  148. m_flags |= SQ_PENDING;
  149. }
  150. /*
  151. -------------------------
  152. PopCommand
  153. -------------------------
  154. */
  155. CBlock *CSequence::PopCommand( int type )
  156. {
  157. CBlock *command = NULL;
  158. //Make sure everything is ok
  159. assert( (type == POP_FRONT) || (type == POP_BACK) );
  160. if ( m_commands.empty() )
  161. return NULL;
  162. switch ( type )
  163. {
  164. case POP_FRONT:
  165. command = m_commands.front();
  166. m_commands.pop_front();
  167. m_numCommands--;
  168. return command;
  169. break;
  170. case POP_BACK:
  171. command = m_commands.back();
  172. m_commands.pop_back();
  173. m_numCommands--;
  174. return command;
  175. break;
  176. }
  177. //Invalid flag
  178. return NULL;
  179. }
  180. /*
  181. -------------------------
  182. PushCommand
  183. -------------------------
  184. */
  185. int CSequence::PushCommand( CBlock *block, int type )
  186. {
  187. //Make sure everything is ok
  188. assert( (type == PUSH_FRONT) || (type == PUSH_BACK) );
  189. assert( block );
  190. switch ( type )
  191. {
  192. case PUSH_FRONT:
  193. m_commands.push_front( block );
  194. m_numCommands++;
  195. return true;
  196. break;
  197. case PUSH_BACK:
  198. m_commands.push_back( block );
  199. m_numCommands++;
  200. return true;
  201. break;
  202. }
  203. //Invalid flag
  204. return false;
  205. }
  206. /*
  207. -------------------------
  208. SetFlag
  209. -------------------------
  210. */
  211. void CSequence::SetFlag( int flag )
  212. {
  213. m_flags |= flag;
  214. }
  215. /*
  216. -------------------------
  217. RemoveFlag
  218. -------------------------
  219. */
  220. void CSequence::RemoveFlag( int flag, bool children )
  221. {
  222. m_flags &= ~flag;
  223. if ( children )
  224. {
  225. /* sequenceID_m::iterator iterSeq = NULL;
  226. for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
  227. {
  228. (*iterSeq).second->RemoveFlag( flag, true );
  229. }*/
  230. sequence_l::iterator si;
  231. for ( si = m_children.begin(); si != m_children.end(); si++ )
  232. {
  233. (*si)->RemoveFlag( flag, true );
  234. }
  235. }
  236. }
  237. /*
  238. -------------------------
  239. HasFlag
  240. -------------------------
  241. */
  242. int CSequence::HasFlag( int flag )
  243. {
  244. return (m_flags & flag);
  245. }
  246. /*
  247. -------------------------
  248. SetReturn
  249. -------------------------
  250. */
  251. void CSequence::SetReturn ( CSequence *sequence )
  252. {
  253. assert( sequence != this );
  254. m_return = sequence;
  255. }
  256. /*
  257. -------------------------
  258. GetChildByID
  259. -------------------------
  260. */
  261. CSequence *CSequence::GetChildByID( int id )
  262. {
  263. if ( id < 0 )
  264. return NULL;
  265. //NOTENOTE: Done for safety reasons, I don't know what this template will return on underflow ( sigh... )
  266. /* sequenceID_m::iterator mi = m_childrenMap.find( id );
  267. if ( mi == m_childrenMap.end() )
  268. return NULL;
  269. return (*mi).second;*/
  270. sequence_l::iterator iterSeq;
  271. STL_ITERATE( iterSeq, m_children )
  272. {
  273. if ( (*iterSeq)->GetID() == id )
  274. return (*iterSeq);
  275. }
  276. return NULL;
  277. }
  278. /*
  279. -------------------------
  280. GetChildByIndex
  281. -------------------------
  282. */
  283. CSequence *CSequence::GetChildByIndex( int iIndex )
  284. {
  285. if ( iIndex < 0 || iIndex >= (int)m_children.size() )
  286. return NULL;
  287. sequence_l::iterator iterSeq = m_children.begin();
  288. for ( int i = 0; i < iIndex; i++ )
  289. {
  290. ++iterSeq;
  291. }
  292. return (*iterSeq);
  293. }
  294. /*
  295. -------------------------
  296. SaveCommand
  297. -------------------------
  298. */
  299. int CSequence::SaveCommand( CBlock *block )
  300. {
  301. CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
  302. unsigned char flags;
  303. int numMembers, bID, size;
  304. CBlockMember *bm;
  305. // Data saved here (IBLK):
  306. // Block ID.
  307. // Block Flags.
  308. // Number of Block Members.
  309. // Block Members:
  310. // - Block Member ID.
  311. // - Block Data Size.
  312. // - Block (Raw) Data.
  313. //Save out the block ID
  314. bID = block->GetBlockID();
  315. pIcarus->BufferWrite( &bID, sizeof ( bID ) );
  316. //Save out the block's flags
  317. flags = block->GetFlags();
  318. pIcarus->BufferWrite( &flags, sizeof ( flags ) );
  319. //Save out the number of members to read
  320. numMembers = block->GetNumMembers();
  321. pIcarus->BufferWrite( &numMembers, sizeof ( numMembers ) );
  322. for ( int i = 0; i < numMembers; i++ )
  323. {
  324. bm = block->GetMember( i );
  325. //Save the block id
  326. bID = bm->GetID();
  327. pIcarus->BufferWrite( &bID, sizeof ( bID ) );
  328. //Save out the data size
  329. size = bm->GetSize();
  330. pIcarus->BufferWrite( &size, sizeof ( size ) );
  331. //Save out the raw data
  332. pIcarus->BufferWrite( bm->GetData(), size );
  333. }
  334. return true;
  335. }
  336. int CSequence::LoadCommand( CBlock *block, CIcarus *icarus )
  337. {
  338. IGameInterface* game = icarus->GetGame();
  339. int bID, bSize;
  340. void *bData;
  341. unsigned char flags;
  342. int id, numMembers;
  343. // Data expected/loaded here (IBLK) (with the size as : 'IBSZ' ).
  344. // Block ID.
  345. // Block Flags.
  346. // Number of Block Members.
  347. // Block Members:
  348. // - Block Member ID.
  349. // - Block Data Size.
  350. // - Block (Raw) Data.
  351. //Get the block ID.
  352. icarus->BufferRead( &id, sizeof( id ) );
  353. block->Create( id );
  354. //Read the block's flags
  355. icarus->BufferRead( &flags, sizeof( flags ) );
  356. block->SetFlags( flags );
  357. //Get the number of block members
  358. icarus->BufferRead( &numMembers, sizeof( numMembers ) );
  359. for ( int j = 0; j < numMembers; j++ )
  360. {
  361. //Get the member ID
  362. icarus->BufferRead( &bID, sizeof( bID ) );
  363. //Get the member size
  364. icarus->BufferRead( &bSize, sizeof( bSize ) );
  365. //Get the member's data
  366. if ( ( bData = game->Malloc( bSize ) ) == NULL )
  367. return false;
  368. //Get the actual raw data
  369. icarus->BufferRead( bData, bSize );
  370. //Write out the correct type
  371. switch ( bID )
  372. {
  373. case CIcarus::TK_INT:
  374. {
  375. assert(0);
  376. int data = *(int *) bData;
  377. block->Write( CIcarus::TK_FLOAT, (float) data, icarus );
  378. }
  379. break;
  380. case CIcarus::TK_FLOAT:
  381. block->Write( CIcarus::TK_FLOAT, *(float *) bData, icarus );
  382. break;
  383. case CIcarus::TK_STRING:
  384. case CIcarus::TK_IDENTIFIER:
  385. case CIcarus::TK_CHAR:
  386. block->Write( CIcarus::TK_STRING, (char *) bData, icarus );
  387. break;
  388. case CIcarus::TK_VECTOR:
  389. case CIcarus::TK_VECTOR_START:
  390. block->Write( CIcarus::TK_VECTOR, *(vec3_t *) bData, icarus );
  391. break;
  392. case CIcarus::ID_TAG:
  393. block->Write( CIcarus::ID_TAG, (float) CIcarus::ID_TAG, icarus );
  394. break;
  395. case CIcarus::ID_GET:
  396. block->Write( CIcarus::ID_GET, (float) CIcarus::ID_GET, icarus );
  397. break;
  398. case CIcarus::ID_RANDOM:
  399. block->Write( CIcarus::ID_RANDOM, *(float *) bData, icarus );//(float) ID_RANDOM );
  400. break;
  401. case CIcarus::TK_EQUALS:
  402. case CIcarus::TK_GREATER_THAN:
  403. case CIcarus::TK_LESS_THAN:
  404. case CIcarus::TK_NOT:
  405. block->Write( bID, 0, icarus );
  406. break;
  407. default:
  408. assert(0);
  409. return false;
  410. break;
  411. }
  412. //Get rid of the temp memory
  413. game->Free( bData );
  414. }
  415. return true;
  416. }
  417. /*
  418. -------------------------
  419. Save
  420. -------------------------
  421. */
  422. int CSequence::Save()
  423. {
  424. // Data saved here.
  425. // Parent ID.
  426. // Return ID.
  427. // Number of Children.
  428. // Children.
  429. // - Child ID
  430. // Save Flags.
  431. // Save Iterations.
  432. // Number of Commands
  433. // - Commands (raw) data.
  434. CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
  435. block_l::iterator bi;
  436. int id;
  437. // Save the parent (by GUID).
  438. id = ( m_parent != NULL ) ? m_parent->GetID() : -1;
  439. pIcarus->BufferWrite( &id, sizeof( id ) );
  440. //Save the return (by GUID)
  441. id = ( m_return != NULL ) ? m_return->GetID() : -1;
  442. pIcarus->BufferWrite( &id, sizeof( id ) );
  443. //Save the number of children
  444. int iNumChildren = m_children.size();
  445. pIcarus->BufferWrite( &iNumChildren, sizeof( iNumChildren ) );
  446. //Save out the children (only by GUID)
  447. /*STL_ITERATE( iterSeq, m_childrenMap )
  448. {
  449. id = (*iterSeq).second->GetID();
  450. pIcarus->BufferWrite( &id, sizeof( id ) );
  451. }*/
  452. sequence_l::iterator iterSeq;
  453. STL_ITERATE( iterSeq, m_children )
  454. {
  455. id = (*iterSeq)->GetID();
  456. pIcarus->BufferWrite( &id, sizeof( id ) );
  457. }
  458. //Save flags
  459. pIcarus->BufferWrite( &m_flags, sizeof( m_flags ) );
  460. //Save iterations
  461. pIcarus->BufferWrite( &m_iterations, sizeof( m_iterations ) );
  462. //Save the number of commands
  463. pIcarus->BufferWrite( &m_numCommands, sizeof( m_numCommands ) );
  464. //Save the commands
  465. STL_ITERATE( bi, m_commands )
  466. {
  467. SaveCommand( (*bi) );
  468. }
  469. return true;
  470. }
  471. /*
  472. -------------------------
  473. Load
  474. -------------------------
  475. */
  476. int CSequence::Load( CIcarus* icarus )
  477. {
  478. CSequence *sequence;
  479. CBlock *block;
  480. int id;
  481. // Data expected/loaded here (ISEQ) (with the size as : 'ISSZ' ).
  482. // Parent ID.
  483. // Return ID.
  484. // Number of Children.
  485. // Children.
  486. // - Child ID
  487. // Save Flags.
  488. // Save Iterations.
  489. // Number of Commands
  490. // - Commands (raw) data.
  491. //Get the parent sequence
  492. icarus->BufferRead( &id, sizeof( id ) );
  493. m_parent = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
  494. //Get the return sequence
  495. icarus->BufferRead( &id, sizeof( id ) );
  496. m_return = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
  497. //Get the number of children
  498. int iNumChildren = 0;
  499. icarus->BufferRead( &iNumChildren, sizeof( iNumChildren ) );
  500. //Reload all children
  501. for ( int i = 0; i < iNumChildren; i++ )
  502. {
  503. //Get the child sequence ID
  504. icarus->BufferRead( &id, sizeof( id ) );
  505. //Get the desired sequence
  506. if ( ( sequence = icarus->GetSequence( id ) ) == NULL )
  507. return false;
  508. //Insert this into the list
  509. STL_INSERT( m_children, sequence );
  510. //Restore the connection in the child / ID map
  511. // m_childrenMap[ i ] = sequence;
  512. }
  513. //Get the sequence flags
  514. icarus->BufferRead( &m_flags, sizeof( m_flags ) );
  515. //Get the number of iterations
  516. icarus->BufferRead( &m_iterations, sizeof( m_iterations ) );
  517. int numCommands;
  518. //Get the number of commands
  519. icarus->BufferRead( &numCommands, sizeof( numCommands ) );
  520. //Get all the commands
  521. for ( i = 0; i < numCommands; i++ )
  522. {
  523. block = new CBlock;
  524. LoadCommand( block, icarus );
  525. //Save the block
  526. //STL_INSERT( m_commands, block );
  527. PushCommand( block, PUSH_BACK );
  528. }
  529. return true;
  530. }