if defined AS_PROCESS_METADATA - CScriptBuilder crash on this script code:
std::string script = "class ";
Not Telling
FDsagizi hasn't added any contacts yet.
Posted by FDsagizi
on 26 September 2012 - 02:43 AM
Posted by FDsagizi
on 25 September 2012 - 04:08 AM
Posted by FDsagizi
on 01 July 2011 - 09:58 AM
ScriptReloader.h
http://www.everfall....hp?55dmnkzvxuzc
ScriptReloader.cpp
http://www.everfall....hp?3m8vcr75t0ty
//
// CScriptReloader
//
#ifndef SCRIPTRELOADER_H
#define SCRIPTRELOADER_H
#include <angelscript.h>
#include <vector>
#include <string>
BEGIN_AS_NAMESPACE
class CScriptReloader;
struct CScriptReloaderVariable
{
CScriptReloaderVariable(){
init();
}
CScriptReloaderVariable( CScriptReloaderVariable *_parent, std::string _name, void *_ref, int _typeId )
{
init();
name = _name;
reloader = _parent->reloader;
Store( _ref, _typeId );
}
void init(){
handle_ptr = restore_ptr = NULL;
type_id = 0;
is_init = false;
reloader = NULL;
}
// need to get engine, and module
CScriptReloader *reloader;
// if standard type ( int, float )...
int type_id;
// if its class, need save type str type - "string" "myClass" then next find by decl
std::string type_id_str;
// name variable
std::string name;
// is initialize
bool is_init;
// 'this' pointer to variable
void *ptr;
// where handle references
void *handle_ptr;
// new address object, ie address the restoration
void *restore_ptr;
// serialize data
std::vector<char> mem;
// if type == string
std::string txt_val;
// Child's, or if type == array, or handle data( if handle not found in global space )
std::vector<CScriptReloaderVariable> childs;
// save the object and its children
void Store(void *ref, int refTypeId );
//restore the object and its children
void Restore(void *ref);
// you first need to save all the objects before you can save references to objects
void StoreHandle();
// first restore the objects, then we have their new address, and we can restore the handle.
void RestoreHandle();
// set type to this var
void setType(int typeId );
// if it class, return obj type
asIObjectType *getType();
// Get child by name variable
CScriptReloaderVariable *child( std::string _name )
{
for( size_t i =0; i < childs.size(); i++ )
if( childs[i].name == _name )
return &childs[i];
return nullptr;
}
// get all ptrs of the child
void childsPtr( std::vector<void*> *_ptrs )
{
_ptrs->push_back( ptr );
for( size_t i=0; i < childs.size(); ++i )
childs[i].childsPtr( _ptrs );
}
// find variable by ptr
CScriptReloaderVariable *findByPtr( void *_ptr )
{
if( ptr == _ptr )
return this;
for( size_t i =0; i < childs.size(); i++ )
{
CScriptReloaderVariable *find = childs[i].findByPtr(_ptr );
if( find )
return find;
}
return nullptr;
}
// find variable by ptr but looking only at those in the references, which will create a new object
CScriptReloaderVariable *findByPtrInCreated( void *_ptr )
{
// if this handle created object
if( type_id & asTYPEID_OBJHANDLE && childs.size() == 1 )
{
if( childs[0].ptr == _ptr )
return this;
}
if( !(type_id & asTYPEID_OBJHANDLE ) )
{
for( size_t i =0; i < childs.size(); i++ )
{
CScriptReloaderVariable *find = childs[i].findByPtrInCreated(_ptr );
if( find )
return find;
}
}
return nullptr;
}
// may be that the two references refer to the same variable.
// But this variable is not available in the global list.
// According to this reference will be restores it.
// And so two links are not created 2 variables,
// it is necessary to cancel the creation of one of them.
void canselDublicate( CScriptReloaderVariable *_from );
};
// This class keeps a list of variables, then restores them after the reboot script.
// But you have to be careful with the change of signature classes, or
// changing the types of objects. You can remove or add variables, functions,
// methods. But you can not (yet) to change the variable type.
//
//You also need to understand that after a reboot you should get a new id
// FUNCTIONS, or class to call them from C + + code.
class CScriptReloader
{
public:
// then store all the variables
CScriptReloaderVariable root;
asIScriptEngine *engine;
asIScriptModule *mod;
// Store all global variables, and handles
void Store()
{
root.reloader = this;
// first store global variables
for( int i =0; i < mod->GetGlobalVarCount(); i++ )
{
const char *name;
int type_id;
mod->GetGlobalVar( i, &name, &type_id );
root.childs.push_back( CScriptReloaderVariable( &root, name, mod->GetAddressOfGlobalVar( i ), type_id ) );
}
// second store handles
root.StoreHandle();
}
// Retrieve all global variables after reload script.
void Restore()
{
// first restore global variables
int var_count = mod->GetGlobalVarCount();
for( int i =0; i < var_count; i++ )
{
const char *name;
mod->GetGlobalVar(i, &name );
CScriptReloaderVariable *v = root.child( name );
v->Restore( mod->GetAddressOfGlobalVar( i ) );
}
// up all handles to new ptr
root.RestoreHandle();
}
};
END_AS_NAMESPACE
#endif
#include "stdafx.h"
#include <assert.h>
#include <string.h> // strstr
#include <stdio.h> // sprintf
#include "scriptreloader.h"
#include "scriptstring.h"
#include "scriptarray.h"
using namespace std;
BEGIN_AS_NAMESPACE
void CScriptReloaderVariable::Store(void *ref, int _typeId)
{
is_init = true;
setType( _typeId );
ptr = ref;
if( type_id & asTYPEID_OBJHANDLE )
{
handle_ptr = *(void**)ref;
}
else if( type_id & asTYPEID_SCRIPTOBJECT )
{
asIScriptObject *obj = (asIScriptObject *)ref;
asIObjectType *type = obj->GetObjectType();
setType( type->GetTypeId() );
// Store childs
for(int i =0; i < type->GetPropertyCount(); i++ )
{
int child_id;
const char *child_name;
type->GetProperty( i, &child_name, &child_id );
childs.push_back( CScriptReloaderVariable( this, child_name, obj->GetAddressOfProperty( i ), child_id ) );
}
}
else
{
int size = reloader->engine->GetSizeOfPrimitiveType( type_id );
if( size == 0 )
{
if( type_id_str== "string" )
{
CScriptString *txt_ref = ((CScriptString*)ref);
txt_val = txt_ref->buffer;
}
else if( type_id_str == "array" )
{
CScriptArray *array = (CScriptArray*)ref;
for( int i =0; i < array->GetSize(); i++ )
childs.push_back( CScriptReloaderVariable( this, "", array->At( i ), array->GetElementTypeId() ) );
}
else if( getType() )
{
size = getType()->GetSize();
}
}
if( size )
{
mem.resize( size );
memcpy(&mem[0], ref, size);
}
}
}
void CScriptReloaderVariable::Restore(void *ref)
{
if( !this || !is_init || !ref )
return;
restore_ptr = ref;
if( type_id & asTYPEID_OBJHANDLE )
{
// if need create objects
if( childs.size() == 1 )
{
asIObjectType *type = childs[0].getType();
void *new_obejct = reloader->engine->CreateScriptObject( type->GetTypeId() );
childs[0].Restore( new_obejct );
}
}
else if( type_id & asTYPEID_SCRIPTOBJECT )
{
asIScriptObject *obj = (asIScriptObject *)ref;
asIObjectType *type = getType();
// Retrieve children s
for( int i =0; i < type->GetPropertyCount() ; i++ )
{
const char *name_property;
type->GetProperty(i, &name_property );
child( name_property )->Restore( obj->GetAddressOfProperty( i ) );
}
}
else
{
if( mem.size() )
memcpy( ref, &mem[0], mem.size());
else
{
if( type_id_str == "string" )
{
CScriptString *ref_txt = ((CScriptString*)ref);
ref_txt->buffer = txt_val;
}
else if( type_id_str == "array" )
{
CScriptArray *array = (CScriptArray*)ref;
array->Resize( childs.size() );
for( size_t i =0; i < childs.size(); ++i )
childs[i].Restore( array->At(i) );
}
}
}
}
void CScriptReloaderVariable::canselDublicate( CScriptReloaderVariable *from )
{
std::vector<void*> ptrs;
from->childsPtr( &ptrs );
for( size_t i=0; i < ptrs.size(); ++i )
{
CScriptReloaderVariable *find = reloader->root.findByPtrInCreated( ptrs[i] );
while( find )
{
// cancel create object
find->childs.clear();
// Find next link to this ptr
find = reloader->root.findByPtrInCreated( ptrs[i] );
}
}
}
void CScriptReloaderVariable::StoreHandle()
{
// Find to
if( handle_ptr )
{
CScriptReloaderVariable *handle_to = reloader->root.findByPtr( handle_ptr );
// if handle is not found in global space...
if( handle_to == nullptr )
{
asIObjectType *type = getType();
CScriptReloaderVariable need_create = CScriptReloaderVariable( this, name, handle_ptr, type->GetTypeId() );
canselDublicate( &need_create );
childs.push_back( need_create );
}
}
// Childs...
for( size_t i=0; i < childs.size(); ++i )
childs[i].StoreHandle();
}
void CScriptReloaderVariable::RestoreHandle()
{
CScriptReloaderVariable *handle_to = reloader->root.findByPtr( handle_ptr );
// Restore handle!
if( restore_ptr && handle_to && handle_to->restore_ptr )
*(void**)restore_ptr = handle_to->restore_ptr;
// Childs...
for( size_t i=0; i < childs.size(); ++i )
childs[i].RestoreHandle();
}
void CScriptReloaderVariable::setType( int _typeId )
{
type_id = _typeId;
asIObjectType *type = reloader->engine->GetObjectTypeById( type_id );
if( type )
type_id_str = type->GetName();
}
asIObjectType *CScriptReloaderVariable::getType()
{
if( !type_id_str.empty() )
{
int new_type_id = reloader->mod->GetTypeIdByDecl( type_id_str.c_str() );
return reloader->engine->GetObjectTypeById( new_type_id );
}
return nullptr;
}
END_AS_NAMESPACE
CScriptReloader reloader; reloader.engine = engine; reloader.mod = mod; reloader.Store (); // Reload scripts... reloader.Restore ();
Find content