2015-11-15 16:37:53 +00:00
/*
* This file is part of the Colobot : Gold Edition source code
2021-09-11 13:52:34 +00:00
* Copyright ( C ) 2001 - 2021 , Daniel Roux , EPSITEC SA & TerranovaTeam
2015-11-15 16:37:53 +00:00
* http : //epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see http : //gnu.org/licenses
*/
# pragma once
2015-11-23 20:59:56 +00:00
# include "CBot/CBotDefines.h"
# include "CBot/CBotTypResult.h"
2015-12-21 22:07:40 +00:00
# include "CBot/CBotVar/CBotVar.h"
2015-11-17 20:06:25 +00:00
2015-12-20 15:19:10 +00:00
# include <string>
2015-12-31 15:11:19 +00:00
# include <deque>
2015-12-31 15:30:54 +00:00
# include <set>
2016-11-11 18:35:43 +00:00
# include <list>
2015-11-15 16:37:53 +00:00
2015-12-26 13:19:24 +00:00
namespace CBot
{
2015-11-22 15:42:51 +00:00
class CBotCallMethode ;
class CBotFunction ;
2015-11-17 20:06:25 +00:00
class CBotProgram ;
2015-11-22 15:42:51 +00:00
class CBotStack ;
class CBotDefParam ;
2015-12-20 15:19:10 +00:00
class CBotToken ;
class CBotCStack ;
2016-11-11 20:49:27 +00:00
class CBotExternalCallList ;
2015-11-17 20:06:25 +00:00
2015-12-22 15:32:51 +00:00
/**
* \ brief A CBot class definition
*
* \ section Examples Usage examples
*
* Define class " point " :
*
* \ code
* CBotClass * classPoint = new CBotClass ( " CPoint " , nullptr ) ;
* classPoint - > AddItem ( " x " , CBotTypResult ( CBotTypFloat ) ) ; // add ".x"
* classPoint - > AddItem ( " y " , CBotTypResult ( CBotTypFloat ) ) ; // add ".y"
*
* // This class can be used in CBot like so:
* // point position;
* // position.x = 12;
* // position.y = -13.6
* \ endcode
*
* Define readonly class " object " with members of type " point " and some methods :
* \ code
* CBotClass * classObject = new CBotClass ( " object " , nullptr ) ;
* classObject - > AddItem ( " category " , CBotTypResult ( CBotTypInt ) , CBotVar : : ProtectionType : : ReadOnly ) ;
* classObject - > AddItem ( " position " , CBotTypResult ( CBotTypClass , classPoint ) , CBotVar : : ProtectionType : : ReadOnly ) ;
* classObject - > AddFunction ( " func " , rFunc , cFunc ) ; // TODO: Document function format for class methods (different from standard CBotProgram::AddFunction()!)
2015-12-23 11:47:37 +00:00
*
2015-12-22 15:32:51 +00:00
* // This class can be used in CBot like so:
* // object item = radar(Me);
* // goto(item.position);
* // item.func();
* \ endcode
*
* Define class " robot " derrived from " object " :
* \ code
* CBotClass * classRobot = new CBotClass ( " object " , classObject ) ;
* classRobot - > AddItem ( " velocity " , CBotTypResult ( CBotTypClass , classPoint ) , CBotVar : : ProtectionType : : ReadOnly ) ;
* classRobot - > AddFunction ( " func2 " , rFunc2 , cFunc2 ) ;
*
* // This class can be used in CBot like so:
* // robot item = something();
* // goto(item.position); // can still access base class
* // item.func(); // can still call base class
* // item.func2(); // but also the derrived class
* \ endcode
*
* Create instance of the " robot " class :
* \ code
* CBotVar * var = new CBotVar ( " variableName " , classRobot ) ;
* \ endcode
*
* Access members of the " point " class :
* \ code
* CBotVar * varX = classInstance - > GetItem ( " x " ) ;
* float x = varX - > GetValFloat ( ) ;
* CBotVar * varY = classInstance - > GetItem ( " y " ) ;
* float y = varX - > GetValFloat ( ) ;
*
* // OR
*
* CBotVar * var = classInstance - > GetItemList ( ) ;
* float x = var - > GetValFloat ( ) ;
* var - > GetNext ( ) ;
* float y = var - > GetValFloat ( ) ;
* \ endcode
2015-11-15 16:37:53 +00:00
*/
2016-11-11 18:35:43 +00:00
class CBotClass
2015-11-15 16:37:53 +00:00
{
public :
/*!
* \ brief CBotClass Constructor . Once a class is created , it is known around
* CBot intrinsic mode gives a class that is not managed by pointers .
* \ param name
2015-12-31 15:30:54 +00:00
* \ param parent
2015-11-15 16:37:53 +00:00
* \ param bIntrinsic
*/
2015-12-20 15:19:10 +00:00
CBotClass ( const std : : string & name ,
2015-12-31 15:30:54 +00:00
CBotClass * parent ,
2015-12-20 15:19:10 +00:00
bool bIntrinsic = false ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief CBotClass Destructor .
*/
~ CBotClass ( ) ;
/*!
* \ brief Create
* \ param name
* \ param parent
* \ param intrinsic
* \ return
*/
2015-12-20 15:19:10 +00:00
static CBotClass * Create ( const std : : string & name ,
2015-11-15 16:37:53 +00:00
CBotClass * parent ,
bool intrinsic = false ) ;
/*!
2016-11-11 20:49:27 +00:00
* \ brief Add a function that can be called from CBot
* \ see CBotProgram : : AddFunction
2015-11-15 16:37:53 +00:00
*/
2015-12-20 15:19:10 +00:00
bool AddFunction ( const std : : string & name ,
bool rExec ( CBotVar * pThis , CBotVar * pVar , CBotVar * pResult , int & Exception , void * user ) ,
CBotTypResult rCompile ( CBotVar * pThis , CBotVar * & pVar ) ) ;
2015-11-15 16:37:53 +00:00
/*!
2015-12-31 15:54:13 +00:00
* \ brief SetUpdateFunc Defines routine to be called to update the elements
2015-11-15 16:37:53 +00:00
* of the class .
2016-01-05 12:04:15 +00:00
* \ param rUpdate
2015-11-15 16:37:53 +00:00
* \ return
*/
2015-12-31 15:54:13 +00:00
bool SetUpdateFunc ( void rUpdate ( CBotVar * thisVar , void * user ) ) ;
2015-11-15 16:37:53 +00:00
//
/*!
* \ brief AddItem Adds an element to the class .
* \ param name
* \ param type
* \ param mPrivate
* \ return
*/
2015-12-21 22:07:40 +00:00
bool AddItem ( std : : string name , CBotTypResult type ,
CBotVar : : ProtectionLevel mPrivate = CBotVar : : ProtectionLevel : : Public ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief AddItem Adds an item by passing the pointer to an instance of a
* variable the object is taken as is , so do not destroyed .
* \ param pVar
* \ return
*/
bool AddItem ( CBotVar * pVar ) ;
/*!
* \ brief GetName Gives the name of the class .
* \ return
*/
2018-04-06 13:02:06 +00:00
const std : : string & GetName ( ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief GetParent Gives the parent class ( or nullptr ) .
* \ return
*/
CBotClass * GetParent ( ) ;
/*!
* \ brief IsChildOf True if a class is derived ( Extends ) of another .
* \ param pClass
* \ return true also if the classes are identical
*/
bool IsChildOf ( CBotClass * pClass ) ;
/*!
* \ brief Find Trouve une classe d ' apr è s son nom
* \ param pToken
* \ return A class by it ' s its name .
*/
static CBotClass * Find ( CBotToken * & pToken ) ;
/*!
* \ brief Find
* \ param name
* \ return
*/
2015-12-20 15:19:10 +00:00
static CBotClass * Find ( const std : : string & name ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief GetVar Return the list of variables .
* \ return
*/
CBotVar * GetVar ( ) ;
/*!
* \ brief GetItem One of the variables according to its name .
* \ param name
* \ return
*/
2015-12-20 15:19:10 +00:00
CBotVar * GetItem ( const std : : string & name ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief GetItemRef
* \ param nIdent
* \ return
*/
CBotVar * GetItemRef ( int nIdent ) ;
2017-01-16 17:34:18 +00:00
/*!
* \ brief Check whether a variable is already defined in a class
* \ param name Name of the variable
* \ return True if a variable is defined in the class
*/
bool CheckVar ( const std : : string & name ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief CompileMethode Compiles a method associated with an instance of
* class the method can be declared by the user or AddFunction .
* \ param name
* \ param pThis
* \ param ppParams
* \ param pStack
* \ param nIdent
* \ return
*/
2016-11-11 20:49:27 +00:00
CBotTypResult CompileMethode ( CBotToken * name ,
2015-11-15 16:37:53 +00:00
CBotVar * pThis ,
CBotVar * * ppParams ,
CBotCStack * pStack ,
2016-11-11 20:49:27 +00:00
long & nIdent ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief ExecuteMethode Executes a method .
* \ param nIdent
* \ param name
* \ param pThis
* \ param ppParams
2016-11-11 20:49:27 +00:00
* \ param pResultType
2015-11-15 16:37:53 +00:00
* \ param pStack
* \ param pToken
* \ return
*/
2016-11-11 20:49:27 +00:00
bool ExecuteMethode ( long & nIdent , CBotVar * pThis , CBotVar * * ppParams , CBotTypResult pResultType ,
CBotStack * & pStack , CBotToken * pToken ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief RestoreMethode Restored the execution stack .
* \ param nIdent
* \ param name
* \ param pThis
* \ param ppParams
* \ param pStack
*/
2016-11-11 20:49:27 +00:00
void RestoreMethode ( long & nIdent ,
CBotToken * name ,
2015-11-15 16:37:53 +00:00
CBotVar * pThis ,
CBotVar * * ppParams ,
2016-11-11 20:49:27 +00:00
CBotStack * & pStack ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief Compile Compiles a class declared by the user .
* \ param p
* \ param pStack
* \ return
*/
static CBotClass * Compile ( CBotToken * & p ,
CBotCStack * pStack ) ;
/*!
2016-12-27 12:23:41 +00:00
* \ brief Pre - compile a new class
* \ param p [ in , out ] Pointer to first token of the class , will be updated to point to first token after the class definition
* \ param pStack Compile stack
*
* This function is used to find the beginning and end of class definition .
*
* If any errors in the code are detected , this function will set the error on compile stack and return nullptr .
*
* \ return Precompiled class , or nullptr in case of error
2015-11-15 16:37:53 +00:00
*/
static CBotClass * Compile1 ( CBotToken * & p ,
CBotCStack * pStack ) ;
2016-08-09 15:59:07 +00:00
/*!
* \ brief DefineClasses Calls CompileDefItem for each class in a list
* of classes , defining fields and pre - compiling methods .
2016-11-11 18:35:43 +00:00
* \ param pClassList List of classes
2016-08-09 15:59:07 +00:00
* \ param pStack
*/
2016-11-11 18:35:43 +00:00
static void DefineClasses ( std : : list < CBotClass * > pClassList , CBotCStack * pStack ) ;
2016-08-09 15:59:07 +00:00
2017-11-15 21:21:01 +00:00
/*!
* \ brief Get the list of user - defined methods in this class .
* \ return List of methods , can be empty .
*/
2020-07-05 13:14:29 +00:00
const std : : list < CBotFunction * > & GetFunctions ( ) const ;
2017-11-15 21:21:01 +00:00
2015-11-15 16:37:53 +00:00
/*!
* \ brief CompileDefItem
* \ param p
* \ param pStack
* \ param bSecond
* \ return
*/
bool CompileDefItem ( CBotToken * & p ,
CBotCStack * pStack ,
bool bSecond ) ;
/*!
* \ brief IsIntrinsic
* \ return
*/
bool IsIntrinsic ( ) ;
/*!
* \ brief Purge
*/
void Purge ( ) ;
/*!
* \ brief Free
*/
2015-12-31 15:30:54 +00:00
static void ClearPublic ( ) ;
2015-11-15 16:37:53 +00:00
/*!
2019-04-11 08:13:13 +00:00
* \ brief Save all static variables from each public class
* \ param ostr Output stream
* \ return true on success
2015-11-15 16:37:53 +00:00
*/
2019-04-11 08:13:13 +00:00
static bool SaveStaticState ( std : : ostream & ostr ) ;
2015-11-15 16:37:53 +00:00
/*!
2019-04-11 08:13:13 +00:00
* \ brief Restore all static variables in each public class
* \ param istr Input stream
* \ return true on success
2015-11-15 16:37:53 +00:00
*/
2019-04-11 08:13:13 +00:00
static bool RestoreStaticState ( std : : istream & istr ) ;
2015-11-15 16:37:53 +00:00
2015-12-31 15:11:19 +00:00
/**
* \ brief Request a lock on this class ( for " synchronized " keyword )
* \ param prog Program that requests the lock
* \ return true if lock was acquired , false if the lock is already taken
2015-11-15 16:37:53 +00:00
*/
2015-12-31 15:11:19 +00:00
bool Lock ( CBotProgram * prog ) ;
2015-11-15 16:37:53 +00:00
2015-12-31 15:11:19 +00:00
/**
* \ brief Release the lock acquired in Lock ( )
* If you call Lock ( ) multiple times for the same program , you have to call Unlock ( ) multiple times too
2015-11-15 16:37:53 +00:00
*/
void Unlock ( ) ;
2015-12-31 15:11:19 +00:00
/**
* \ brief Release all locks in all classes held by this program
* \ param prog Program to release the locks from
2015-11-15 16:37:53 +00:00
*/
2015-12-31 15:11:19 +00:00
static void FreeLock ( CBotProgram * prog ) ;
2015-11-15 16:37:53 +00:00
/*!
* \ brief CheckCall Test if a procedure name is already defined somewhere .
2015-12-25 19:47:30 +00:00
* \ param program
2015-11-15 16:37:53 +00:00
* \ param pToken
* \ param pParam
* \ return
*/
2015-12-24 11:36:09 +00:00
bool CheckCall ( CBotProgram * program , CBotDefParam * pParam , CBotToken * & pToken ) ;
2015-11-15 16:37:53 +00:00
2015-12-31 15:54:13 +00:00
void Update ( CBotVar * var , void * user ) ;
2015-11-15 16:37:53 +00:00
private :
2015-12-31 15:30:54 +00:00
//! List of all public classes
static std : : set < CBotClass * > m_publicClasses ;
2015-12-31 15:54:13 +00:00
//! true if this class is fully compiled, false if only precompiled
bool m_IsDef ;
//! Name of this class
2015-12-20 15:19:10 +00:00
std : : string m_name ;
2015-12-31 15:54:13 +00:00
//! Parent class
CBotClass * m_parent ;
//! Number of variables in the chain
2015-11-15 16:37:53 +00:00
int m_nbVar ;
2015-12-31 15:54:13 +00:00
//! Intrinsic class
2015-11-15 16:37:53 +00:00
bool m_bIntrinsic ;
2015-12-31 15:30:54 +00:00
//! Linked list of all class fields
CBotVar * m_pVar ;
//! Linked list of all class external calls
2016-11-11 20:49:27 +00:00
CBotExternalCallList * m_externalMethods ;
2016-11-11 18:35:43 +00:00
//! List of all class methods
std : : list < CBotFunction * > m_pMethod { } ;
2015-12-31 15:54:13 +00:00
void ( * m_rUpdate ) ( CBotVar * thisVar , void * user ) ;
2015-12-31 15:11:19 +00:00
2016-08-09 15:59:07 +00:00
CBotToken * m_pOpenblk ;
2015-12-31 15:11:19 +00:00
//! How many times the program currently holding the lock called Lock()
2015-12-31 15:30:54 +00:00
int m_lockCurrentCount = 0 ;
2016-01-23 20:33:58 +00:00
//! Programs waiting for lock. m_lockProg[0] is the program currently holding the lock, if any
2015-12-31 15:30:54 +00:00
std : : deque < CBotProgram * > m_lockProg { } ;
2015-12-26 13:19:24 +00:00
} ;
} // namespace CBot