diff --git a/src/CBot/CBotClass.h b/src/CBot/CBotClass.h index 2b151b0a..69f3605e 100644 --- a/src/CBot/CBotClass.h +++ b/src/CBot/CBotClass.h @@ -41,7 +41,8 @@ class CBotDefParam; /*! * \brief The CBotClass class Class to define new classes in the language CBOT - * for example to define the class CPoint (x, y). + * For example to define the class CPoint (x, y) see comments at end of this + * file. */ class CBotClass { @@ -77,8 +78,9 @@ public: bool intrinsic = false); /*! - * \brief AddFunction This call allows to add as external (**) new method - * used by the objects of this class. + * \brief AddFunction This call allows to add as external new method + * used by the objects of this class. See (**) at end of this file for + * more details. * \param name * \param rExec * \param rCompile @@ -339,3 +341,135 @@ private: //! Processes waiting for sync. CBotProgram* m_ProgInLock[5]; }; + +/* +(**) Note: + + To define an external function, proceed as follows: + + a) define a routine for compilation this routine receive list of parameters + (no values) and either returns a result type (CBotTyp... or 0 = void) + or an error number. + + b) define a routine for the execution this routine receive list of + parameters (with valeurs), a variable to store the result + (according to the given type at compile time) + + For example, a routine which calculates the mean of a parameter list + +int cMean(CBotVar* &pVar, CBotString& ClassName) +{ + if ( pVar == nullptr ) return 6001; // there is no parameter! + while ( pVar != nullptr ) + { + if ( pVar->GetType() > CBotTypDouble ) return 6002; // this is not a number + pVar = pVar -> GetNext(); + } + return CBotTypFloat; // the type of the result may depend on the parameters! +} + + +bool rMean(CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + float total = 0; + int nb = 0; + while (pVar != nullptr) + { + total += pVar->GetValFloat(); + pVar = pVar->GetNext(); + nb++; + } + pResult->SetValFloat(total/nb); // returns the mean value + return true; // operation fully completed +} + +//////////////////////////////////////////////////////////////////////////////// +// Examples of use +// Definition classes and functions + + +// define the global class CPoint +// -------------------------------- + m_pClassPoint = new CBotClass("CPoint", nullptr); + // adds the component ".x" + m_pClassPoint->AddItem("x", CBotTypResult(CBotTypFloat)); + // adds the component ".y" + m_pClassPoint->AddItem("y", CBotTypResult(CBotTypFloat)); + // the player can then use the instructions + // CPoint position; position.x = 12; position.y = -13.6 + +// define class CColobotObject +// -------------------------------- + // This class manages all the objects in the world of COLOBOT + // the "main" user program belongs to this class + m_pClassObject = new CBotClass("CColobotObject", m_pClassBase); + // adds the component ".position" + m_pClassObject->AddItem("position", m_pClassPoint); + // adds the component ".type" + m_pClassObject->AddItem("type", CBotTypResult(CBotTypShort)); + // adds a definition of constant + m_pClassObject->AddConst("ROBOT", CBotTypShort, 1); // ROBOT equivalent to the value 1 + // adds the FIND routine + m_pClassObject->AddFunction( rCompFind, rDoFind ); + // the player can now use the instructions + // CColobotObject chose; chose = FIND( ROBOT ) + +// define class CColobotRobot derived from CColobotObject +// --------------------------------------------------------- + // programs "main" associated with robots as a part of this class + m_pClassRobot = new CBotClass("CColobotRobot", m_pClassObject); + // add routine GOTO + m_pClassRobot->AddFunction( rCompGoto, rDoGoto ); + // the player can now use + // GOTO( FIND ( ROBOT ) ); + + +// creates an instance of the class Robot +// ------------------------------------ + // for example a new robot which has just been manufactured + CBotVar* m_pMonRobot = new CBotVar("MonRobot", m_pClassRobot); + + +// compiles the program by hand for this robot +// ------------------------------------------ + CString LeProgramme( "void main() {GOTO(0, 0); return 0;}" ); + if ( !m_pMonRobot->Compile( LeProgramme ) ) {error handling ...}; + +// build a stack for interpreter +// -------------------------------------- + CBotStack* pStack = new CBotStack(nullptr); + +// executes the main program +// ------------------------- + while( false = m_pMonRobot->Execute( "main", pStack )) + { + // program suspended + // could be pass a handle to another (safeguarding pstack for the robot one) + }; + // programme "main" finished ! + +// routine that implements the GOTO (CPoint pos) +bool rDoGoto( CBotVar* pVar, CBotVar* pResult, int& exception ) +{ + if (pVar->GetType() != CBotTypeClass || + pVar->IsElemOfClas("CPoint") ) { exception = 6522; return false; ) + // the parameter is not the right class? + // in fact the control is done to the routine of compilation + + m_PosToGo.Copy( pVar ); // keeps the target position (object type CBotVar) + + // or so + CBotVar* temp; + temp = pVar->GetItem("x"); // is necessary for the object of type CPoint + ASSERT (temp != nullptr && temp->GetType() == CBotTypFloat); + m_PosToGo.x = temp->GetValFloat(); + + temp = pVar->GetItem("y"); // is necessary for the object of type CPoint + ASSERT (temp != nullptr && temp->GetType() == CBotTypFloat); + m_PosToGo.y = temp->GetValFloat(); + + return (m_CurentPos == m_PosToGo); // makes true if the position is reached + // returns false if one had wait yet +} + +*/ diff --git a/src/CBot/CBotDefines.h b/src/CBot/CBotDefines.h index b1c73b38..93be12bb 100644 --- a/src/CBot/CBotDefines.h +++ b/src/CBot/CBotDefines.h @@ -118,6 +118,9 @@ #define CBotErrRead 6014 // error while reading #define CBotErrWrite 6015 // writing error +// other values ​​may be returned +// for example exceptions returned by external routines +// and " throw " with any number. // TODO: refactor & change to enum! diff --git a/src/CBot/CBotProgram.h b/src/CBot/CBotProgram.h index 88dd0741..98854b33 100644 --- a/src/CBot/CBotProgram.h +++ b/src/CBot/CBotProgram.h @@ -186,16 +186,16 @@ public: // /*! - * \brief AddFunction Call this to add externally (**) a new function used - * by the program CBoT. + * \brief AddFunction Call this to add externally a new function used + * by the program CBoT. See (**) at end of this file for more details. * \param name * \param rExec * \param rCompile * \return */ static bool AddFunction(const char* name, - bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser), - CBotTypResult rCompile (CBotVar* &pVar, void* pUser)); + bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser), + CBotTypResult rCompile (CBotVar* &pVar, void* pUser)); /*! * \brief DefineNum @@ -270,3 +270,46 @@ private: //! Associated identifier. long m_Ident; }; + +/* +(**) Note: + + To define an external function, proceed as follows: + + a) define a routine for compilation this routine receive list of parameters + (no values) and either returns a result type (CBotTyp... or 0 = void) + or an error number. + + b) define a routine for the execution this routine receive list of + parameters (with valeurs), a variable to store the result + (according to the given type at compile time) + + For example, a routine which calculates the mean of a parameter list + +int cMean(CBotVar* &pVar, CBotString& ClassName) +{ + if ( pVar == nullptr ) return 6001; // there is no parameter! + while ( pVar != nullptr ) + { + if ( pVar->GetType() > CBotTypDouble ) return 6002; // this is not a number + pVar = pVar -> GetNext(); + } + return CBotTypFloat; // the type of the result may depend on the parameters! +} + + +bool rMean(CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + float total = 0; + int nb = 0; + while (pVar != nullptr) + { + total += pVar->GetValFloat(); + pVar = pVar->GetNext(); + nb++; + } + pResult->SetValFloat(total/nb); // returns the mean value + return true; // operation fully completed +} + +*/