v 0. Pasted by Anonymous as cpp at 2011-07-01 19:54:06 MSK and set expiration to never.

Paste will expire never.

  1. //
  2. // CScriptReloader
  3. //
  4.  
  5. #ifndef SCRIPTRELOADER_H
  6. #define SCRIPTRELOADER_H
  7.  
  8. #include <angelscript.h>
  9. #include <vector>
  10. #include <string>
  11.  
  12. BEGIN_AS_NAMESPACE
  13.  
  14. class CScriptReloader;
  15.  
  16. struct CScriptReloaderVariable
  17. {
  18.     CScriptReloaderVariable(){
  19.         init();
  20.     }
  21.     CScriptReloaderVariable( CScriptReloaderVariable *_parent, std::string _name,  void *_ref, int _typeId )
  22.     {
  23.         init();
  24.  
  25.         name = _name;
  26.         reloader = _parent->reloader;
  27.         Store( _ref, _typeId );
  28.     }
  29.  
  30.     void init(){
  31.         handle_ptr = restore_ptr = NULL;
  32.         type_id = 0;
  33.         is_init = false;
  34.         reloader = NULL;
  35.     }
  36.  
  37.     // need to get engine, and module
  38.     CScriptReloader *reloader;
  39.  
  40.     //  if standard type ( int, float )...
  41.     int type_id;
  42.  
  43.     // if its class, need save type str type - "string" "myClass" then next find by decl
  44.     std::string type_id_str;
  45.    
  46.     // name variable
  47.     std::string name;
  48.  
  49.     // is initialize
  50.     bool is_init;
  51.  
  52.     // 'this' pointer to variable
  53.     void *ptr;
  54.  
  55.     // where handle references
  56.     void *handle_ptr;
  57.  
  58.     // new address object, ie address the restoration
  59.     void *restore_ptr;
  60.  
  61.     // serialize data
  62.     std::vector<char> mem;
  63.  
  64.     // if type == string
  65.     std::string txt_val;
  66.  
  67.     // Child's, or if type == array, or handle data( if handle not found in global space )
  68.     std::vector<CScriptReloaderVariable> childs;
  69.  
  70.     // save the object and its children
  71.     void Store(void *ref, int refTypeId );
  72.  
  73.     //restore the object and its children
  74.     void Restore(void *ref);
  75.  
  76.     // you first need to save all the objects before you can save references to objects
  77.     void StoreHandle();
  78.  
  79.     // first restore the objects, then we have their new address, and we can restore the handle.
  80.     void RestoreHandle();
  81.  
  82.     // set type to this var
  83.     void setType(int typeId );
  84.  
  85.     // if it class, return obj type
  86.     asIObjectType *getType();
  87.  
  88.     // Get child by name variable
  89.     CScriptReloaderVariable *child( std::string _name )
  90.     {
  91.         for( size_t i =0; i < childs.size(); i++ )
  92.             if( childs[i].name == _name )
  93.                 return &childs[i];
  94.  
  95.         return nullptr;
  96.     }
  97.  
  98.     // get all ptrs of the child
  99.     void  childsPtr( std::vector<void*> *_ptrs )
  100.     {
  101.         _ptrs->push_back( ptr );
  102.  
  103.         for( size_t i=0; i < childs.size(); ++i )
  104.             childs[i].childsPtr( _ptrs );
  105.     }
  106.  
  107.     // find variable by ptr
  108.     CScriptReloaderVariable *findByPtr( void *_ptr )
  109.     {
  110.         if( ptr == _ptr )
  111.             return this;
  112.  
  113.         for( size_t i =0; i < childs.size(); i++ )
  114.         {
  115.             CScriptReloaderVariable *find = childs[i].findByPtr(_ptr );
  116.             if( find )
  117.                 return find;
  118.         }
  119.  
  120.         return nullptr;
  121.     }
  122.  
  123.     // find variable by ptr but looking only at those in the references, which will create a new object
  124.     CScriptReloaderVariable *findByPtrInCreated( void *_ptr )
  125.     {
  126.         // if this handle created object
  127.         if( type_id & asTYPEID_OBJHANDLE && childs.size() == 1 )
  128.         {
  129.             if( childs[0].ptr == _ptr )
  130.                 return this;
  131.         }
  132.  
  133.         if(  !(type_id & asTYPEID_OBJHANDLE ) )
  134.         {
  135.             for( size_t i =0; i < childs.size(); i++ )
  136.             {
  137.                 CScriptReloaderVariable *find = childs[i].findByPtrInCreated(_ptr );
  138.                 if( find )
  139.                     return find;
  140.             }
  141.         }
  142.  
  143.         return nullptr;
  144.     }
  145.  
  146.     // may be that the two references refer to the same variable.
  147.     // But this variable is not available in the global list.
  148.     // According to this reference will be restores it.
  149.     // And so two links are not created 2 variables,
  150.     // it is necessary to cancel the creation of one of them.
  151.     void canselDublicate( CScriptReloaderVariable *_from );
  152. };
  153.  
  154.  
  155. // This class keeps a list of variables, then restores them after the reboot script.
  156. // But you have to be careful with the change of signature classes, or
  157. // changing the types of objects. You can remove or add variables, functions,
  158. // methods. But you can not (yet) to change the variable type.
  159. //
  160. //You also need to understand that after a reboot you should get a new id
  161. // FUNCTIONS, or class to call them from C + + code.
  162. class CScriptReloader
  163. {
  164.  
  165. public:
  166.    
  167.     // then store all the variables
  168.     CScriptReloaderVariable root;
  169.  
  170.     asIScriptEngine *engine;
  171.  
  172.     asIScriptModule *mod;
  173.  
  174.     // Store all global variables, and handles
  175.     void Store()
  176.     {
  177.         root.reloader = this;
  178.  
  179.         // first store global variables
  180.         for( int i =0; i < mod->GetGlobalVarCount(); i++ )
  181.         {
  182.             const char *name;
  183.             int type_id;
  184.             mod->GetGlobalVar( i, &name, &type_id );
  185.             root.childs.push_back( CScriptReloaderVariable( &root, name,  mod->GetAddressOfGlobalVar( i ), type_id ) );
  186.         }
  187.  
  188.         // second store handles
  189.         root.StoreHandle();
  190.     }
  191.  
  192.     // Retrieve all global variables after reload script.
  193.     void Restore()
  194.     {
  195.         // first restore global variables
  196.         int var_count = mod->GetGlobalVarCount();
  197.         for( int i =0; i < var_count; i++ )
  198.         {
  199.             const char *name;
  200.             mod->GetGlobalVar(i, &name );
  201.  
  202.             CScriptReloaderVariable *v = root.child( name );
  203.             v->Restore( mod->GetAddressOfGlobalVar( i ) );
  204.         }
  205.  
  206.         // up all handles to new ptr
  207.         root.RestoreHandle();
  208.     }
  209.  
  210. };
  211.  
  212.  
  213. END_AS_NAMESPACE
  214.  
  215. #endif