bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) { unsigned short w, wi, prv, st; float ww; CBotString name, s; delete pVar; pVar = NULL; CBotVar* pNew = NULL; CBotVar* pPrev = NULL; while ( true ) // retrieves a list { if (!ReadWord(pf, w)) return false; // private or type? if ( w == 0 ) return true; CBotString defnum; if ( w == 200 ) { if (!ReadString(pf, defnum)) return false; // number with identifier if (!ReadWord(pf, w)) return false; // type } prv = 100; st = 0; if ( w >= 100 ) { prv = w; if (!ReadWord(pf, st)) return false; // static if (!ReadWord(pf, w)) return false; // type } if ( w == CBotTypClass ) w = CBotTypIntrinsic; // necessarily intrinsic if (!ReadWord(pf, wi)) return false; // init ? if (!ReadString(pf, name)) return false; // variable name CBotToken token(name, CBotString()); switch (w) { case CBotTypInt: case CBotTypBoolean: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadWord(pf, w)) return false; pNew->SetValInt(static_cast<short>(w), defnum); break; case CBotTypFloat: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadFloat(pf, ww)) return false; pNew->SetValFloat(ww); break; case CBotTypString: pNew = CBotVar::Create(&token, w); // creates a variable if (!ReadString(pf, s)) return false; pNew->SetValString(s); break; // returns an intrinsic object or element of an array case CBotTypIntrinsic: case CBotTypArrayBody: { CBotTypResult r; long id; if (!ReadType(pf, r)) return false; // complete type if (!ReadLong(pf, id) ) return false; // if (!ReadString(pf, s)) return false; { CBotVar* p = NULL; if ( id ) p = CBotVarClass::Find(id) ; pNew = new CBotVarClass(&token, r); // directly creates an instance // attention cptuse = 0 if ( !RestoreState(pf, (static_cast<CBotVarClass*>(pNew))->m_pVar)) return false; pNew->SetIdent(id); if ( p != NULL ) { delete pNew; pNew = p; // resume known element } } } break; case CBotTypPointer: case CBotTypNullPointer: if (!ReadString(pf, s)) return false; { pNew = CBotVar::Create(&token, CBotTypResult(w, s));// creates a variable // CBotVarClass* p = NULL; long id; ReadLong(pf, id); // if ( id ) p = CBotVarClass::Find(id); // found the instance (made by RestoreInstance) // returns a copy of the original instance CBotVar* pInstance = NULL; if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; (static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over // if ( p != NULL ) (static_cast<CBotVarPointer*>(pNew))->SetPointer( p ); // rather this one } break; case CBotTypArrayPointer: { CBotTypResult r; if (!ReadType(pf, r)) return false; pNew = CBotVar::Create(&token, r); // creates a variable // returns a copy of the original instance CBotVar* pInstance = NULL; if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; (static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over } break; default: ASM_TRAP(); } if ( pPrev != NULL ) pPrev->m_next = pNew; if ( pVar == NULL ) pVar = pNew; pNew->m_binit = wi; // pNew->SetInit(wi); pNew->SetStatic(st); pNew->SetPrivate(prv-100); pPrev = pNew; } return true; }
void CTestCBotDoc::OnTest() { CBotProgram::DefineNum("WingedGrabber", 1); CBotProgram::DefineNum("TrackedGrabber", 2); CBotProgram::DefineNum("WheeledGrabber", 3); CBotProgram::DefineNum("LeggedGrabber", 4); CBotProgram::DefineNum("WingedShooter", 5); CBotProgram::DefineNum("TrackedShooter", 6); CBotProgram::DefineNum("WheeledShooter", 7); CBotProgram::DefineNum("LeggedShooter", 8); CBotProgram::DefineNum("WingedOrgaShooter", 9); CBotProgram::DefineNum("TrackedOrgaShooter", 10); CBotProgram::DefineNum("WheeledOrgaShooter", 11); CBotProgram::DefineNum("LeggedOrgaShooter", 12); CBotProgram::DefineNum("WingedSniffer", 13); CBotProgram::DefineNum("TrackedSniffer", 14); CBotProgram::DefineNum("WheeledSniffer", 14); CBotProgram::DefineNum("LeggedSniffer", 15); CBotProgram::DefineNum("Thumper", 16); CBotProgram::DefineNum("PhazerShooter", 17); CBotProgram::DefineNum("Recycler", 18); CBotProgram::DefineNum("Shielder", 19); CBotProgram::DefineNum("Subber", 20); CBotProgram::DefineNum("Me", 21); CBotProgram::DefineNum("TypeMarkPath", 111); OnFileSave(); // CPerformDlg dlg; // dlg.m_Script = m_DocText; // dlg.DoModal(); // défini la routine RetObject CBotProgram::AddFunction( "Radar", rRetObject, cRetObject ); // ajoute une routine pour cette classe CBotProgram::AddFunction("Space", rSpace, cSpace); // défini la routine Test CBotProgram::AddFunction( "TEST", rTEST, cTEST ); CBotProgram::AddFunction( "F", rF, cF ); CBotProgram::AddFunction( "goto", rMove, cMove ); CBotProgram::AddFunction( "fire", rTurn, cTurn ); CBotProgram::AddFunction( "radar", rRadar, cRadar ); // crée une instance de la classe "Bot" pour ce robot CBotVar* pThisRobot = CBotVar::Create( "", CBotTypResult(CBotTypClass, "object") ); pThisRobot->SetUserPtr( (void*)1 ); pThisRobot->SetIdent( 1234 ); delete m_pProg; // crée un objet programme associé à cette instance m_pProg = new CBotProgram(pThisRobot); // compile le programme CString TextError; int code, start, end; m_pEdit->GetWindowText(m_DocText); if (!m_pProg->Compile(m_DocText, m_Liste, (void*) 44)) { m_pProg->GetError(code, start, end); delete m_pProg; m_pProg = NULL; delete pThisRobot; m_pEdit->SetSel( start, end ); m_pEdit->SetFocus(); // met en évidence la partie avec problème TextError = CBotProgram::GivErrorText( code ); AfxMessageBox( TextError ); m_pEdit->SetFocus(); return; } // exécute pour voir m_pProg->Start(m_Liste[0]); int mode = -1; if ( mode >= 0 ) { // sauve et restore à chaque pas possible while (!m_pProg->Run(NULL, 1)) { const char* FunctionName; int start1, end1; m_pProg->GetRunPos(FunctionName, start1, end1); if ( end1 <= 0 ) m_pProg->GetRunPos(FunctionName, start1, end1); m_pEdit->SetSel(start1, end1); if ( mode == 0 ) continue; FILE* pf; pf = fOpen( "TEST.CBO", "wb" ); CBotClass::SaveStaticState(pf); m_pProg->SaveState(pf); fClose(pf); if ( mode == 2 ) if (!m_pProg->Compile(m_DocText, m_Liste, (void*) 44)) { m_pProg->GetError(code, start, end); delete m_pProg; m_pProg = NULL; delete pThisRobot; m_pEdit->SetSel( start, end ); m_pEdit->SetFocus(); // met en évidence la partie avec problème TextError = CBotProgram::GivErrorText( code ); AfxMessageBox( TextError ); m_pEdit->SetFocus(); return; } pf = fOpen( "TEST.CBO", "rb" ); CBotClass::RestoreStaticState(pf); m_pProg->RestoreState(pf); fClose(pf); int start2, end2; m_pProg->GetRunPos(FunctionName, start2, end2); if ( end2 <= 0 ) m_pProg->GetRunPos(FunctionName, start2, end2); if ( start1 != start2 || end1 != end2 ) m_pProg->GetRunPos(FunctionName, start2, end2); m_pEdit->SetSel(start2, end2); } if (m_pProg->GetError(code, start, end)) { m_pEdit->SetSel(start, end); TextError = CBotProgram::GivErrorText(code); AfxMessageBox(TextError); } return;} while (!m_pProg->Run(NULL, 0)) { const char* FunctionName; int start, end; m_pProg->GetRunPos(FunctionName, start, end); m_pEdit->SetSel(start, end); if ( FunctionName == NULL ) continue; CString info (FunctionName); CString sep (":\n"); int level = 0; const char* Name; while ( TRUE ) { CBotVar* pVar = m_pProg->GivStackVars(Name, level--); if ( Name != FunctionName ) break; if ( pVar == NULL ) continue; // pVar->Maj(NULL, FALSE); while ( pVar != NULL ) { info += sep; info += pVar->GivName() + CBotString(" = ") + pVar->GivValString(); sep = ", "; pVar = pVar->GivNext(); } sep = "\n"; } if ( IDOK != AfxMessageBox(info, MB_OKCANCEL) ) break; if ( test == 1 ) { test = 0; FILE* pf; pf = fOpen( "TEST.CBO", "wb" ); m_pProg->SaveState(pf); fClose(pf); } if ( test == 2 ) { test = 0; FILE* pf; pf = fOpen( "TEST.CBO", "rb" ); m_pProg->RestoreState(pf); fClose(pf); } if ( test == 12 ) { test = 0; FILE* pf; pf = fOpen( "TEST.CBO", "wb" ); m_pProg->SaveState(pf); fClose(pf); pf = fOpen( "TEST.CBO", "rb" ); m_pProg->RestoreState(pf); fClose(pf); test = 13; } } if (m_pProg->GetError(code, start, end)) { m_pEdit->SetSel(start, end); TextError = CBotProgram::GivErrorText(code); AfxMessageBox(TextError); } delete pThisRobot; }