123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 |
- // Script Command Sequences
- //
- // -- jweier
- // this include must remain at the top of every Icarus CPP file
- #include "stdafx.h"
- #include "IcarusImplementation.h"
- #include "BlockStream.h"
- #include "Sequence.h"
- #define STL_ITERATE( a, b ) for ( a = b.begin(); a != b.end(); a++ )
- #define STL_INSERT( a, b ) a.insert( a.end(), b );
- inline CSequence::CSequence( void )
- {
- m_numCommands = 0;
- // m_numChildren = 0;
- m_flags = 0;
- m_iterations = 1;
- m_parent = NULL;
- m_return = NULL;
- }
- CSequence::~CSequence( void )
- {
- assert(!m_commands.size());
- //assert(!m_numChildren);
- }
- /*
- -------------------------
- Create
- -------------------------
- */
- CSequence *CSequence::Create( void )
- {
- CSequence *seq = new CSequence;
- //TODO: Emit warning
- assert(seq);
- if ( seq == NULL )
- return NULL;
- seq->SetFlag( SQ_COMMON );
- return seq;
- }
- /*
- -------------------------
- Delete
- -------------------------
- */
- void CSequence::Delete( CIcarus* icarus )
- {
- block_l::iterator bi;
- sequence_l::iterator si;
- //Notify the parent of the deletion
- if ( m_parent )
- {
- m_parent->RemoveChild( this );
- }
- //Clear all children
- if ( m_children.size() > 0 )
- {
- /*for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
- {
- (*iterSeq).second->SetParent( NULL );
- }*/
-
- for ( si = m_children.begin(); si != m_children.end(); si++ )
- {
- (*si)->SetParent( NULL );
- }
- }
- m_children.clear();
- //m_childrenMap.clear();
- //Clear all held commands
- for ( bi = m_commands.begin(); bi != m_commands.end(); bi++ )
- {
- (*bi)->Free(icarus);
- delete (*bi); //Free() handled internally -- not any more!!
- }
- m_commands.clear();
-
- }
- /*
- -------------------------
- AddChild
- -------------------------
- */
- void CSequence::AddChild( CSequence *child )
- {
- assert( child );
- if ( child == NULL )
- return;
- m_children.insert( m_children.end(), child );
- // m_childrenMap[ m_numChildren ] = child;
- // m_numChildren++;
- }
- /*
- -------------------------
- RemoveChild
- -------------------------
- */
- void CSequence::RemoveChild( CSequence *child )
- {
- assert( child );
- if ( child == NULL )
- return;
-
- m_children.remove( child );
- //Remove the child
- /* sequenceID_m::iterator iterSeq = m_childrenMap.find( child->GetID() );
- if ( iterSeq != m_childrenMap.end() )
- {
- m_childrenMap.erase( iterSeq );
- }
- m_numChildren--;*/
- }
- /*
- -------------------------
- HasChild
- -------------------------
- */
- bool CSequence::HasChild( CSequence *sequence )
- {
- sequence_l::iterator ci;
- for ( ci = m_children.begin(); ci != m_children.end(); ci++ )
- {
- if ( (*ci) == sequence )
- return true;
- if ( (*ci)->HasChild( sequence ) )
- return true;
- }
- /* sequenceID_m::iterator iterSeq = NULL;
- for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
- {
- if ( ((*iterSeq).second) == sequence )
- return true;
- if ( (*iterSeq).second->HasChild( sequence ) )
- return true;
- }*/
- return false;
- }
- /*
- -------------------------
- SetParent
- -------------------------
- */
- void CSequence::SetParent( CSequence *parent )
- {
- m_parent = parent;
- if ( parent == NULL )
- return;
- //Inherit the parent's properties (this avoids messy tree walks later on)
- if ( parent->m_flags & SQ_RETAIN )
- m_flags |= SQ_RETAIN;
- if ( parent->m_flags & SQ_PENDING )
- m_flags |= SQ_PENDING;
- }
- /*
- -------------------------
- PopCommand
- -------------------------
- */
- CBlock *CSequence::PopCommand( int type )
- {
- CBlock *command = NULL;
- //Make sure everything is ok
- assert( (type == POP_FRONT) || (type == POP_BACK) );
- if ( m_commands.empty() )
- return NULL;
- switch ( type )
- {
- case POP_FRONT:
- command = m_commands.front();
- m_commands.pop_front();
- m_numCommands--;
-
- return command;
- break;
- case POP_BACK:
- command = m_commands.back();
- m_commands.pop_back();
- m_numCommands--;
-
- return command;
- break;
- }
- //Invalid flag
- return NULL;
- }
- /*
- -------------------------
- PushCommand
- -------------------------
- */
- int CSequence::PushCommand( CBlock *block, int type )
- {
- //Make sure everything is ok
- assert( (type == PUSH_FRONT) || (type == PUSH_BACK) );
- assert( block );
- switch ( type )
- {
- case PUSH_FRONT:
-
- m_commands.push_front( block );
- m_numCommands++;
- return true;
- break;
- case PUSH_BACK:
- m_commands.push_back( block );
- m_numCommands++;
- return true;
- break;
- }
- //Invalid flag
- return false;
- }
- /*
- -------------------------
- SetFlag
- -------------------------
- */
- void CSequence::SetFlag( int flag )
- {
- m_flags |= flag;
- }
- /*
- -------------------------
- RemoveFlag
- -------------------------
- */
- void CSequence::RemoveFlag( int flag, bool children )
- {
- m_flags &= ~flag;
- if ( children )
- {
- /* sequenceID_m::iterator iterSeq = NULL;
- for ( iterSeq = m_childrenMap.begin(); iterSeq != m_childrenMap.end(); iterSeq++ )
- {
- (*iterSeq).second->RemoveFlag( flag, true );
- }*/
- sequence_l::iterator si;
- for ( si = m_children.begin(); si != m_children.end(); si++ )
- {
- (*si)->RemoveFlag( flag, true );
- }
- }
- }
- /*
- -------------------------
- HasFlag
- -------------------------
- */
- int CSequence::HasFlag( int flag )
- {
- return (m_flags & flag);
- }
- /*
- -------------------------
- SetReturn
- -------------------------
- */
- void CSequence::SetReturn ( CSequence *sequence )
- {
- assert( sequence != this );
- m_return = sequence;
- }
- /*
- -------------------------
- GetChildByID
- -------------------------
- */
- CSequence *CSequence::GetChildByID( int id )
- {
- if ( id < 0 )
- return NULL;
- //NOTENOTE: Done for safety reasons, I don't know what this template will return on underflow ( sigh... )
- /* sequenceID_m::iterator mi = m_childrenMap.find( id );
- if ( mi == m_childrenMap.end() )
- return NULL;
- return (*mi).second;*/
- sequence_l::iterator iterSeq;
- STL_ITERATE( iterSeq, m_children )
- {
- if ( (*iterSeq)->GetID() == id )
- return (*iterSeq);
- }
- return NULL;
- }
- /*
- -------------------------
- GetChildByIndex
- -------------------------
- */
- CSequence *CSequence::GetChildByIndex( int iIndex )
- {
- if ( iIndex < 0 || iIndex >= (int)m_children.size() )
- return NULL;
- sequence_l::iterator iterSeq = m_children.begin();
- for ( int i = 0; i < iIndex; i++ )
- {
- ++iterSeq;
- }
- return (*iterSeq);
- }
- /*
- -------------------------
- SaveCommand
- -------------------------
- */
- int CSequence::SaveCommand( CBlock *block )
- {
- CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
- unsigned char flags;
- int numMembers, bID, size;
- CBlockMember *bm;
- // Data saved here (IBLK):
- // Block ID.
- // Block Flags.
- // Number of Block Members.
- // Block Members:
- // - Block Member ID.
- // - Block Data Size.
- // - Block (Raw) Data.
- //Save out the block ID
- bID = block->GetBlockID();
- pIcarus->BufferWrite( &bID, sizeof ( bID ) );
- //Save out the block's flags
- flags = block->GetFlags();
- pIcarus->BufferWrite( &flags, sizeof ( flags ) );
- //Save out the number of members to read
- numMembers = block->GetNumMembers();
- pIcarus->BufferWrite( &numMembers, sizeof ( numMembers ) );
- for ( int i = 0; i < numMembers; i++ )
- {
- bm = block->GetMember( i );
- //Save the block id
- bID = bm->GetID();
- pIcarus->BufferWrite( &bID, sizeof ( bID ) );
-
- //Save out the data size
- size = bm->GetSize();
- pIcarus->BufferWrite( &size, sizeof ( size ) );
-
- //Save out the raw data
- pIcarus->BufferWrite( bm->GetData(), size );
- }
- return true;
- }
- int CSequence::LoadCommand( CBlock *block, CIcarus *icarus )
- {
- IGameInterface* game = icarus->GetGame();
- int bID, bSize;
- void *bData;
- unsigned char flags;
- int id, numMembers;
- // Data expected/loaded here (IBLK) (with the size as : 'IBSZ' ).
- // Block ID.
- // Block Flags.
- // Number of Block Members.
- // Block Members:
- // - Block Member ID.
- // - Block Data Size.
- // - Block (Raw) Data.
-
- //Get the block ID.
- icarus->BufferRead( &id, sizeof( id ) );
- block->Create( id );
- //Read the block's flags
- icarus->BufferRead( &flags, sizeof( flags ) );
- block->SetFlags( flags );
- //Get the number of block members
- icarus->BufferRead( &numMembers, sizeof( numMembers ) );
-
- for ( int j = 0; j < numMembers; j++ )
- {
- //Get the member ID
- icarus->BufferRead( &bID, sizeof( bID ) );
-
- //Get the member size
- icarus->BufferRead( &bSize, sizeof( bSize ) );
- //Get the member's data
- if ( ( bData = game->Malloc( bSize ) ) == NULL )
- return false;
- //Get the actual raw data
- icarus->BufferRead( bData, bSize );
- //Write out the correct type
- switch ( bID )
- {
- case CIcarus::TK_INT:
- {
- assert(0);
- int data = *(int *) bData;
- block->Write( CIcarus::TK_FLOAT, (float) data, icarus );
- }
- break;
- case CIcarus::TK_FLOAT:
- block->Write( CIcarus::TK_FLOAT, *(float *) bData, icarus );
- break;
- case CIcarus::TK_STRING:
- case CIcarus::TK_IDENTIFIER:
- case CIcarus::TK_CHAR:
- block->Write( CIcarus::TK_STRING, (char *) bData, icarus );
- break;
- case CIcarus::TK_VECTOR:
- case CIcarus::TK_VECTOR_START:
- block->Write( CIcarus::TK_VECTOR, *(vec3_t *) bData, icarus );
- break;
- case CIcarus::ID_TAG:
- block->Write( CIcarus::ID_TAG, (float) CIcarus::ID_TAG, icarus );
- break;
- case CIcarus::ID_GET:
- block->Write( CIcarus::ID_GET, (float) CIcarus::ID_GET, icarus );
- break;
- case CIcarus::ID_RANDOM:
- block->Write( CIcarus::ID_RANDOM, *(float *) bData, icarus );//(float) ID_RANDOM );
- break;
-
- case CIcarus::TK_EQUALS:
- case CIcarus::TK_GREATER_THAN:
- case CIcarus::TK_LESS_THAN:
- case CIcarus::TK_NOT:
- block->Write( bID, 0, icarus );
- break;
- default:
- assert(0);
- return false;
- break;
- }
-
- //Get rid of the temp memory
- game->Free( bData );
- }
- return true;
- }
- /*
- -------------------------
- Save
- -------------------------
- */
- int CSequence::Save()
- {
- // Data saved here.
- // Parent ID.
- // Return ID.
- // Number of Children.
- // Children.
- // - Child ID
- // Save Flags.
- // Save Iterations.
- // Number of Commands
- // - Commands (raw) data.
- CIcarus *pIcarus = (CIcarus *)IIcarusInterface::GetIcarus();
- block_l::iterator bi;
- int id;
- // Save the parent (by GUID).
- id = ( m_parent != NULL ) ? m_parent->GetID() : -1;
- pIcarus->BufferWrite( &id, sizeof( id ) );
- //Save the return (by GUID)
- id = ( m_return != NULL ) ? m_return->GetID() : -1;
- pIcarus->BufferWrite( &id, sizeof( id ) );
-
- //Save the number of children
- int iNumChildren = m_children.size();
- pIcarus->BufferWrite( &iNumChildren, sizeof( iNumChildren ) );
- //Save out the children (only by GUID)
- /*STL_ITERATE( iterSeq, m_childrenMap )
- {
- id = (*iterSeq).second->GetID();
- pIcarus->BufferWrite( &id, sizeof( id ) );
- }*/
- sequence_l::iterator iterSeq;
- STL_ITERATE( iterSeq, m_children )
- {
- id = (*iterSeq)->GetID();
- pIcarus->BufferWrite( &id, sizeof( id ) );
- }
- //Save flags
- pIcarus->BufferWrite( &m_flags, sizeof( m_flags ) );
- //Save iterations
- pIcarus->BufferWrite( &m_iterations, sizeof( m_iterations ) );
- //Save the number of commands
- pIcarus->BufferWrite( &m_numCommands, sizeof( m_numCommands ) );
- //Save the commands
- STL_ITERATE( bi, m_commands )
- {
- SaveCommand( (*bi) );
- }
- return true;
- }
- /*
- -------------------------
- Load
- -------------------------
- */
- int CSequence::Load( CIcarus* icarus )
- {
- CSequence *sequence;
- CBlock *block;
- int id;
- // Data expected/loaded here (ISEQ) (with the size as : 'ISSZ' ).
- // Parent ID.
- // Return ID.
- // Number of Children.
- // Children.
- // - Child ID
- // Save Flags.
- // Save Iterations.
- // Number of Commands
- // - Commands (raw) data.
- //Get the parent sequence
- icarus->BufferRead( &id, sizeof( id ) );
- m_parent = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
-
- //Get the return sequence
- icarus->BufferRead( &id, sizeof( id ) );
- m_return = ( id != -1 ) ? icarus->GetSequence( id ) : NULL;
- //Get the number of children
- int iNumChildren = 0;
- icarus->BufferRead( &iNumChildren, sizeof( iNumChildren ) );
- //Reload all children
- for ( int i = 0; i < iNumChildren; i++ )
- {
- //Get the child sequence ID
- icarus->BufferRead( &id, sizeof( id ) );
- //Get the desired sequence
- if ( ( sequence = icarus->GetSequence( id ) ) == NULL )
- return false;
-
- //Insert this into the list
- STL_INSERT( m_children, sequence );
- //Restore the connection in the child / ID map
- // m_childrenMap[ i ] = sequence;
- }
-
- //Get the sequence flags
- icarus->BufferRead( &m_flags, sizeof( m_flags ) );
- //Get the number of iterations
- icarus->BufferRead( &m_iterations, sizeof( m_iterations ) );
- int numCommands;
- //Get the number of commands
- icarus->BufferRead( &numCommands, sizeof( numCommands ) );
- //Get all the commands
- for ( i = 0; i < numCommands; i++ )
- {
- block = new CBlock;
- LoadCommand( block, icarus );
- //Save the block
- //STL_INSERT( m_commands, block );
- PushCommand( block, PUSH_BACK );
- }
- return true;
- }
|