Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Scripting/angelscript/add_on/serializer/serializer.cpp')
-rw-r--r--Source/Scripting/angelscript/add_on/serializer/serializer.cpp832
1 files changed, 377 insertions, 455 deletions
diff --git a/Source/Scripting/angelscript/add_on/serializer/serializer.cpp b/Source/Scripting/angelscript/add_on/serializer/serializer.cpp
index a359fcdd..ad3856d8 100644
--- a/Source/Scripting/angelscript/add_on/serializer/serializer.cpp
+++ b/Source/Scripting/angelscript/add_on/serializer/serializer.cpp
@@ -6,8 +6,8 @@
//
#include <assert.h>
-#include <string.h> // strstr
-#include <stdio.h> // sprintf
+#include <string.h> // strstr
+#include <stdio.h> // sprintf
#include "serializer.h"
using namespace std;
@@ -16,533 +16,455 @@ BEGIN_AS_NAMESPACE
///////////////////////////////////////////////////////////////////////////////////
-CSerializer::CSerializer()
-{
- m_engine = 0;
+CSerializer::CSerializer() {
+ m_engine = 0;
}
-CSerializer::~CSerializer()
-{
- // Extra objects need to be released, since they are not stored in
- // the module and we cannot rely on the application releasing them
- for( size_t i = 0; i < m_extraObjects.size(); i++ )
- {
- SExtraObject &o = m_extraObjects[i];
- for( size_t i2 = 0; i2 < m_root.m_children.size(); i2++ )
- {
- if( m_root.m_children[i2]->m_originalPtr == o.originalObject && m_root.m_children[i2]->m_restorePtr )
- reinterpret_cast<asIScriptObject*>(m_root.m_children[i2]->m_restorePtr)->Release();
- }
- }
-
- // Clean the serialized values before we remove the user types
- m_root.Uninit();
-
- // Delete the user types
- std::map<std::string, CUserType*>::iterator it;
- for( it = m_userTypes.begin(); it != m_userTypes.end(); it++ )
- delete it->second;
-
- if( m_engine )
- m_engine->Release();
+CSerializer::~CSerializer() {
+ // Extra objects need to be released, since they are not stored in
+ // the module and we cannot rely on the application releasing them
+ for (size_t i = 0; i < m_extraObjects.size(); i++) {
+ SExtraObject &o = m_extraObjects[i];
+ for (size_t i2 = 0; i2 < m_root.m_children.size(); i2++) {
+ if (m_root.m_children[i2]->m_originalPtr == o.originalObject && m_root.m_children[i2]->m_restorePtr)
+ reinterpret_cast<asIScriptObject *>(m_root.m_children[i2]->m_restorePtr)->Release();
+ }
+ }
+
+ // Clean the serialized values before we remove the user types
+ m_root.Uninit();
+
+ // Delete the user types
+ std::map<std::string, CUserType *>::iterator it;
+ for (it = m_userTypes.begin(); it != m_userTypes.end(); it++)
+ delete it->second;
+
+ if (m_engine)
+ m_engine->Release();
}
-void CSerializer::AddUserType(CUserType *ref, const std::string &name)
-{
- m_userTypes[name] = ref;
+void CSerializer::AddUserType(CUserType *ref, const std::string &name) {
+ m_userTypes[name] = ref;
}
-int CSerializer::Store(asIScriptModule *mod)
-{
- m_mod = mod;
-
- // The engine must not be destroyed before we're completed, so we'll hold on to a reference
- mod->GetEngine()->AddRef();
- if( m_engine ) m_engine->Release();
- m_engine = mod->GetEngine();
-
- m_root.m_serializer = this;
-
- // First store global variables
- asUINT i;
- for( i = 0; i < mod->GetGlobalVarCount(); i++ )
- {
- const char *name, *nameSpace;
- int typeId;
- mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
- m_root.m_children.push_back(new CSerializedValue(&m_root, name, nameSpace, mod->GetAddressOfGlobalVar(i), typeId));
- }
-
- // Second store extra objects
- for( i = 0; i < m_extraObjects.size(); i++ )
- m_root.m_children.push_back(new CSerializedValue(&m_root, "", "", m_extraObjects[i].originalObject, m_extraObjects[i].originalTypeId));
-
- // For the handles that were stored, we need to substitute the stored pointer
- // that is still pointing to the original object to an internal reference so
- // it can be restored later on.
- m_root.ReplaceHandles();
-
- return 0;
+int CSerializer::Store(asIScriptModule *mod) {
+ m_mod = mod;
+
+ // The engine must not be destroyed before we're completed, so we'll hold on to a reference
+ mod->GetEngine()->AddRef();
+ if (m_engine) m_engine->Release();
+ m_engine = mod->GetEngine();
+
+ m_root.m_serializer = this;
+
+ // First store global variables
+ asUINT i;
+ for (i = 0; i < mod->GetGlobalVarCount(); i++) {
+ const char *name, *nameSpace;
+ int typeId;
+ mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
+ m_root.m_children.push_back(new CSerializedValue(&m_root, name, nameSpace, mod->GetAddressOfGlobalVar(i), typeId));
+ }
+
+ // Second store extra objects
+ for (i = 0; i < m_extraObjects.size(); i++)
+ m_root.m_children.push_back(new CSerializedValue(&m_root, "", "", m_extraObjects[i].originalObject, m_extraObjects[i].originalTypeId));
+
+ // For the handles that were stored, we need to substitute the stored pointer
+ // that is still pointing to the original object to an internal reference so
+ // it can be restored later on.
+ m_root.ReplaceHandles();
+
+ return 0;
}
// Retrieve all global variables after reload script.
-int CSerializer::Restore(asIScriptModule *mod)
-{
- m_mod = mod;
-
- // The engine must not be destroyed before we're completed, so we'll hold on to a reference
- mod->GetEngine()->AddRef();
- if( m_engine ) m_engine->Release();
- m_engine = mod->GetEngine();
-
- // First restore extra objects, i.e. the ones that are not directly seen from the module's global variables
- asUINT i;
- for( i = 0; i < m_extraObjects.size(); i++ )
- {
- SExtraObject &o = m_extraObjects[i];
- asITypeInfo *type = m_mod->GetTypeInfoByName( o.originalClassName.c_str() );
- if( type )
- {
- for( size_t i2 = 0; i2 < m_root.m_children.size(); i2++ )
- {
- if( m_root.m_children[i2]->m_originalPtr == o.originalObject )
- {
- // Create a new script object, but don't call its constructor as we will initialize the members.
- // Calling the constructor may have unwanted side effects if for example the constructor changes
- // any outside entities, such as setting global variables to point to new objects, etc.
- void *newPtr = m_engine->CreateUninitializedScriptObject( type );
- m_root.m_children[i2]->Restore( newPtr, type->GetTypeId() );
- }
- }
- }
- }
-
- // Second restore the global variables
- asUINT varCount = mod->GetGlobalVarCount();
- for( i = 0; i < varCount; i++ )
- {
- const char *name, *nameSpace;
- int typeId;
- mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
-
- CSerializedValue *v = m_root.FindByName(name, nameSpace);
- if( v )
- v->Restore(mod->GetAddressOfGlobalVar(i), typeId);
- }
-
- // The handles that were restored needs to be
- // updated to point to their final objects.
- m_root.RestoreHandles();
-
- return 0;
+int CSerializer::Restore(asIScriptModule *mod) {
+ m_mod = mod;
+
+ // The engine must not be destroyed before we're completed, so we'll hold on to a reference
+ mod->GetEngine()->AddRef();
+ if (m_engine) m_engine->Release();
+ m_engine = mod->GetEngine();
+
+ // First restore extra objects, i.e. the ones that are not directly seen from the module's global variables
+ asUINT i;
+ for (i = 0; i < m_extraObjects.size(); i++) {
+ SExtraObject &o = m_extraObjects[i];
+ asITypeInfo *type = m_mod->GetTypeInfoByName(o.originalClassName.c_str());
+ if (type) {
+ for (size_t i2 = 0; i2 < m_root.m_children.size(); i2++) {
+ if (m_root.m_children[i2]->m_originalPtr == o.originalObject) {
+ // Create a new script object, but don't call its constructor as we will initialize the members.
+ // Calling the constructor may have unwanted side effects if for example the constructor changes
+ // any outside entities, such as setting global variables to point to new objects, etc.
+ void *newPtr = m_engine->CreateUninitializedScriptObject(type);
+ m_root.m_children[i2]->Restore(newPtr, type->GetTypeId());
+ }
+ }
+ }
+ }
+
+ // Second restore the global variables
+ asUINT varCount = mod->GetGlobalVarCount();
+ for (i = 0; i < varCount; i++) {
+ const char *name, *nameSpace;
+ int typeId;
+ mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
+
+ CSerializedValue *v = m_root.FindByName(name, nameSpace);
+ if (v)
+ v->Restore(mod->GetAddressOfGlobalVar(i), typeId);
+ }
+
+ // The handles that were restored needs to be
+ // updated to point to their final objects.
+ m_root.RestoreHandles();
+
+ return 0;
}
-void *CSerializer::GetPointerToRestoredObject(void *ptr)
-{
- return m_root.GetPointerToRestoredObject( ptr );
+void *CSerializer::GetPointerToRestoredObject(void *ptr) {
+ return m_root.GetPointerToRestoredObject(ptr);
}
-void CSerializer::AddExtraObjectToStore( asIScriptObject *object )
-{
- if( !object )
- return;
+void CSerializer::AddExtraObjectToStore(asIScriptObject *object) {
+ if (!object)
+ return;
- // Check if the object hasn't been included already
- for( size_t i=0; i < m_extraObjects.size(); i++ )
- if( m_extraObjects[i].originalObject == object )
- return;
+ // Check if the object hasn't been included already
+ for (size_t i = 0; i < m_extraObjects.size(); i++)
+ if (m_extraObjects[i].originalObject == object)
+ return;
- SExtraObject o;
- o.originalObject = object;
- o.originalClassName = object->GetObjectType()->GetName();
- o.originalTypeId = object->GetTypeId();
+ SExtraObject o;
+ o.originalObject = object;
+ o.originalClassName = object->GetObjectType()->GetName();
+ o.originalTypeId = object->GetTypeId();
- m_extraObjects.push_back( o );
+ m_extraObjects.push_back(o);
}
-
///////////////////////////////////////////////////////////////////////////////////
-CSerializedValue::CSerializedValue()
-{
- Init();
+CSerializedValue::CSerializedValue() {
+ Init();
}
-CSerializedValue::CSerializedValue(CSerializedValue *parent, const std::string &name, const std::string &nameSpace, void *ref, int typeId)
-{
- Init();
+CSerializedValue::CSerializedValue(CSerializedValue *parent, const std::string &name, const std::string &nameSpace, void *ref, int typeId) {
+ Init();
- m_name = name;
- m_nameSpace = nameSpace;
- m_serializer = parent->m_serializer;
- Store(ref, typeId);
+ m_name = name;
+ m_nameSpace = nameSpace;
+ m_serializer = parent->m_serializer;
+ Store(ref, typeId);
}
-void CSerializedValue::Init()
-{
- m_handlePtr = 0;
- m_restorePtr = 0;
- m_typeId = 0;
- m_isInit = false;
- m_serializer = 0;
- m_userData = 0;
- m_originalPtr = 0;
+void CSerializedValue::Init() {
+ m_handlePtr = 0;
+ m_restorePtr = 0;
+ m_typeId = 0;
+ m_isInit = false;
+ m_serializer = 0;
+ m_userData = 0;
+ m_originalPtr = 0;
}
-void CSerializedValue::Uninit()
-{
- m_isInit = false;
+void CSerializedValue::Uninit() {
+ m_isInit = false;
- ClearChildren();
+ ClearChildren();
- if( m_userData )
- {
- CUserType *type = m_serializer->m_userTypes[m_typeName];
- if( type )
- type->CleanupUserData(this);
- m_userData = 0;
- }
+ if (m_userData) {
+ CUserType *type = m_serializer->m_userTypes[m_typeName];
+ if (type)
+ type->CleanupUserData(this);
+ m_userData = 0;
+ }
}
-void CSerializedValue::ClearChildren()
-{
- // If this value is for an object handle that created an object during the restore
- // then it is necessary to release the handle here, so we won't get a memory leak
- if( (m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1 && m_children[0]->m_restorePtr )
- {
- m_serializer->m_engine->ReleaseScriptObject(m_children[0]->m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_children[0]->m_typeId));
- }
-
- for( size_t n = 0; n < m_children.size(); n++ )
- delete m_children[n];
- m_children.clear();
+void CSerializedValue::ClearChildren() {
+ // If this value is for an object handle that created an object during the restore
+ // then it is necessary to release the handle here, so we won't get a memory leak
+ if ((m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1 && m_children[0]->m_restorePtr) {
+ m_serializer->m_engine->ReleaseScriptObject(m_children[0]->m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_children[0]->m_typeId));
+ }
+
+ for (size_t n = 0; n < m_children.size(); n++)
+ delete m_children[n];
+ m_children.clear();
}
-CSerializedValue::~CSerializedValue()
-{
- Uninit();
+CSerializedValue::~CSerializedValue() {
+ Uninit();
}
-CSerializedValue *CSerializedValue::FindByName(const std::string &name, const std::string &nameSpace)
-{
- for( size_t i = 0; i < m_children.size(); i++ )
- if( m_children[i]->m_name == name &&
- m_children[i]->m_nameSpace == nameSpace )
- return m_children[i];
+CSerializedValue *CSerializedValue::FindByName(const std::string &name, const std::string &nameSpace) {
+ for (size_t i = 0; i < m_children.size(); i++)
+ if (m_children[i]->m_name == name &&
+ m_children[i]->m_nameSpace == nameSpace)
+ return m_children[i];
- return 0;
+ return 0;
}
-void CSerializedValue::GetAllPointersOfChildren(std::vector<void*> *ptrs)
-{
- ptrs->push_back(m_originalPtr);
+void CSerializedValue::GetAllPointersOfChildren(std::vector<void *> *ptrs) {
+ ptrs->push_back(m_originalPtr);
- for( size_t i = 0; i < m_children.size(); ++i )
- m_children[i]->GetAllPointersOfChildren(ptrs);
+ for (size_t i = 0; i < m_children.size(); ++i)
+ m_children[i]->GetAllPointersOfChildren(ptrs);
}
-CSerializedValue *CSerializedValue::FindByPtr(void *ptr)
-{
- if( m_originalPtr == ptr )
- return this;
+CSerializedValue *CSerializedValue::FindByPtr(void *ptr) {
+ if (m_originalPtr == ptr)
+ return this;
- for( size_t i = 0; i < m_children.size(); i++ )
- {
- CSerializedValue *find = m_children[i]->FindByPtr(ptr);
- if( find )
- return find;
- }
+ for (size_t i = 0; i < m_children.size(); i++) {
+ CSerializedValue *find = m_children[i]->FindByPtr(ptr);
+ if (find)
+ return find;
+ }
- return 0;
+ return 0;
}
-void *CSerializedValue::GetPointerToRestoredObject(void *ptr)
-{
- if( m_originalPtr == ptr )
- return m_restorePtr;
+void *CSerializedValue::GetPointerToRestoredObject(void *ptr) {
+ if (m_originalPtr == ptr)
+ return m_restorePtr;
- for( size_t i = 0; i < m_children.size(); ++i )
- {
- void *ret = m_children[i]->GetPointerToRestoredObject(ptr);
- if( ret )
- return ret;
- }
+ for (size_t i = 0; i < m_children.size(); ++i) {
+ void *ret = m_children[i]->GetPointerToRestoredObject(ptr);
+ if (ret)
+ return ret;
+ }
- return 0;
+ return 0;
}
// find variable by ptr but looking only at those in the references, which will create a new object
-CSerializedValue *CSerializedValue::FindByPtrInHandles(void *ptr)
-{
- // if this handle created object
- if( (m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1 )
- {
- if( m_children[0]->m_originalPtr == ptr )
- return this;
- }
-
- if( !(m_typeId & asTYPEID_OBJHANDLE) )
- {
- for( size_t i = 0; i < m_children.size(); i++ )
- {
- CSerializedValue *find = m_children[i]->FindByPtrInHandles(ptr);
- if( find )
- return find;
- }
- }
-
- return 0;
+CSerializedValue *CSerializedValue::FindByPtrInHandles(void *ptr) {
+ // if this handle created object
+ if ((m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1) {
+ if (m_children[0]->m_originalPtr == ptr)
+ return this;
+ }
+
+ if (!(m_typeId & asTYPEID_OBJHANDLE)) {
+ for (size_t i = 0; i < m_children.size(); i++) {
+ CSerializedValue *find = m_children[i]->FindByPtrInHandles(ptr);
+ if (find)
+ return find;
+ }
+ }
+
+ return 0;
}
-void CSerializedValue::Store(void *ref, int typeId)
-{
- m_isInit = true;
- SetType(typeId);
- m_originalPtr = ref;
-
- if( m_typeId & asTYPEID_OBJHANDLE )
- {
- m_handlePtr = *(void**)ref;
- }
- else if( m_typeId & asTYPEID_SCRIPTOBJECT )
- {
- asIScriptObject *obj = (asIScriptObject *)ref;
- asITypeInfo *type = obj->GetObjectType();
- SetType(type->GetTypeId());
-
- // Store children
- for( asUINT i = 0; i < type->GetPropertyCount(); i++ )
- {
- int childId;
- const char *childName;
- type->GetProperty(i, &childName, &childId);
-
- m_children.push_back(new CSerializedValue(this, childName, "", obj->GetAddressOfProperty(i), childId));
- }
- }
- else
- {
- int size = m_serializer->m_engine->GetSizeOfPrimitiveType(m_typeId);
-
- if( size == 0 )
- {
- // if it is user type( string, array, etc ... )
- if( m_serializer->m_userTypes[m_typeName] )
- m_serializer->m_userTypes[m_typeName]->Store(this, m_originalPtr);
- else
- {
- // POD-types can be stored without need for user type
- asITypeInfo *type = GetType();
- if( type && (type->GetFlags() & asOBJ_POD) )
- size = GetType()->GetSize();
-
- // It is not necessary to report an error here if it is not a POD-type as that will be done when restoring
- }
- }
-
- if( size )
- {
- m_mem.resize(size);
- memcpy(&m_mem[0], ref, size);
- }
- }
+void CSerializedValue::Store(void *ref, int typeId) {
+ m_isInit = true;
+ SetType(typeId);
+ m_originalPtr = ref;
+
+ if (m_typeId & asTYPEID_OBJHANDLE) {
+ m_handlePtr = *(void **)ref;
+ } else if (m_typeId & asTYPEID_SCRIPTOBJECT) {
+ asIScriptObject *obj = (asIScriptObject *)ref;
+ asITypeInfo *type = obj->GetObjectType();
+ SetType(type->GetTypeId());
+
+ // Store children
+ for (asUINT i = 0; i < type->GetPropertyCount(); i++) {
+ int childId;
+ const char *childName;
+ type->GetProperty(i, &childName, &childId);
+
+ m_children.push_back(new CSerializedValue(this, childName, "", obj->GetAddressOfProperty(i), childId));
+ }
+ } else {
+ int size = m_serializer->m_engine->GetSizeOfPrimitiveType(m_typeId);
+
+ if (size == 0) {
+ // if it is user type( string, array, etc ... )
+ if (m_serializer->m_userTypes[m_typeName])
+ m_serializer->m_userTypes[m_typeName]->Store(this, m_originalPtr);
+ else {
+ // POD-types can be stored without need for user type
+ asITypeInfo *type = GetType();
+ if (type && (type->GetFlags() & asOBJ_POD))
+ size = GetType()->GetSize();
+
+ // It is not necessary to report an error here if it is not a POD-type as that will be done when restoring
+ }
+ }
+
+ if (size) {
+ m_mem.resize(size);
+ memcpy(&m_mem[0], ref, size);
+ }
+ }
}
-void CSerializedValue::Restore(void *ref, int typeId)
-{
- if( !this || !m_isInit || !ref )
- return;
-
- // Verify that the stored type matched the new type of the value being restored
- if( typeId <= asTYPEID_DOUBLE && typeId != m_typeId ) return; // TODO: We may try to do a type conversion for primitives
- if( (typeId & ~asTYPEID_MASK_SEQNBR) ^ (m_typeId & ~asTYPEID_MASK_SEQNBR) ) return;
- asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
- if( type && m_typeName != type->GetName() ) return;
-
- // Set the new pointer and type
- m_restorePtr = ref;
- SetType(typeId);
-
- // Restore the value
- if( m_typeId & asTYPEID_OBJHANDLE )
- {
- // if need create objects
- if( m_children.size() == 1 )
- {
- asITypeInfo *ctype = m_children[0]->GetType();
-
- if( ctype->GetFactoryCount() == 0 )
- {
- // There are no factories, so assume the same pointer is going to be used
- m_children[0]->m_restorePtr = m_handlePtr;
-
- // Increase the refCount for the object as it will be released upon clean-up
- m_serializer->m_engine->AddRefScriptObject(m_handlePtr, ctype);
- }
- else
- {
- // Create a new script object, but don't call its constructor as we will initialize the members.
- // Calling the constructor may have unwanted side effects if for example the constructor changes
- // any outside entities, such as setting global variables to point to new objects, etc.
- void *newObject = m_serializer->m_engine->CreateUninitializedScriptObject(ctype);
- m_children[0]->Restore(newObject, ctype->GetTypeId());
- }
- }
- }
- else if( m_typeId & asTYPEID_SCRIPTOBJECT )
- {
- asIScriptObject *obj = (asIScriptObject *)ref;
-
- // Retrieve children
- for( asUINT i = 0; i < type->GetPropertyCount() ; i++ )
- {
- const char *nameProperty;
- int ptypeId;
- type->GetProperty(i, &nameProperty, &ptypeId);
-
- CSerializedValue *var = FindByName(nameProperty, "");
- if( var )
- var->Restore(obj->GetAddressOfProperty(i), ptypeId);
- }
- }
- else
- {
- if( m_mem.size() )
- {
- // POD values can be restored with direct copy
- memcpy(ref, &m_mem[0], m_mem.size());
- }
- else if( m_serializer->m_userTypes[m_typeName] )
- {
- // user type restore
- m_serializer->m_userTypes[m_typeName]->Restore(this, m_restorePtr);
- }
- else
- {
- std::string str = "Cannot restore type '";
- str += type->GetName();
- str += "'";
- m_serializer->m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.c_str());
- }
- }
+void CSerializedValue::Restore(void *ref, int typeId) {
+ if (!this || !m_isInit || !ref)
+ return;
+
+ // Verify that the stored type matched the new type of the value being restored
+ if (typeId <= asTYPEID_DOUBLE && typeId != m_typeId) return; // TODO: We may try to do a type conversion for primitives
+ if ((typeId & ~asTYPEID_MASK_SEQNBR) ^ (m_typeId & ~asTYPEID_MASK_SEQNBR)) return;
+ asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
+ if (type && m_typeName != type->GetName()) return;
+
+ // Set the new pointer and type
+ m_restorePtr = ref;
+ SetType(typeId);
+
+ // Restore the value
+ if (m_typeId & asTYPEID_OBJHANDLE) {
+ // if need create objects
+ if (m_children.size() == 1) {
+ asITypeInfo *ctype = m_children[0]->GetType();
+
+ if (ctype->GetFactoryCount() == 0) {
+ // There are no factories, so assume the same pointer is going to be used
+ m_children[0]->m_restorePtr = m_handlePtr;
+
+ // Increase the refCount for the object as it will be released upon clean-up
+ m_serializer->m_engine->AddRefScriptObject(m_handlePtr, ctype);
+ } else {
+ // Create a new script object, but don't call its constructor as we will initialize the members.
+ // Calling the constructor may have unwanted side effects if for example the constructor changes
+ // any outside entities, such as setting global variables to point to new objects, etc.
+ void *newObject = m_serializer->m_engine->CreateUninitializedScriptObject(ctype);
+ m_children[0]->Restore(newObject, ctype->GetTypeId());
+ }
+ }
+ } else if (m_typeId & asTYPEID_SCRIPTOBJECT) {
+ asIScriptObject *obj = (asIScriptObject *)ref;
+
+ // Retrieve children
+ for (asUINT i = 0; i < type->GetPropertyCount(); i++) {
+ const char *nameProperty;
+ int ptypeId;
+ type->GetProperty(i, &nameProperty, &ptypeId);
+
+ CSerializedValue *var = FindByName(nameProperty, "");
+ if (var)
+ var->Restore(obj->GetAddressOfProperty(i), ptypeId);
+ }
+ } else {
+ if (m_mem.size()) {
+ // POD values can be restored with direct copy
+ memcpy(ref, &m_mem[0], m_mem.size());
+ } else if (m_serializer->m_userTypes[m_typeName]) {
+ // user type restore
+ m_serializer->m_userTypes[m_typeName]->Restore(this, m_restorePtr);
+ } else {
+ std::string str = "Cannot restore type '";
+ str += type->GetName();
+ str += "'";
+ m_serializer->m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.c_str());
+ }
+ }
}
-void CSerializedValue::CancelDuplicates(CSerializedValue *from)
-{
- std::vector<void*> ptrs;
- from->GetAllPointersOfChildren(&ptrs);
+void CSerializedValue::CancelDuplicates(CSerializedValue *from) {
+ std::vector<void *> ptrs;
+ from->GetAllPointersOfChildren(&ptrs);
- for( size_t i = 0; i < ptrs.size(); ++i )
- {
- CSerializedValue *find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
+ for (size_t i = 0; i < ptrs.size(); ++i) {
+ CSerializedValue *find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
- while( find )
- {
- // cancel create object
- find->ClearChildren();
+ while (find) {
+ // cancel create object
+ find->ClearChildren();
- // Find next link to this ptr
- find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
- }
- }
+ // Find next link to this ptr
+ find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
+ }
+ }
}
-void CSerializedValue::ReplaceHandles()
-{
- if( m_handlePtr )
- {
- // Find the object that the handle is referring to
- CSerializedValue *handle_to = m_serializer->m_root.FindByPtr(m_handlePtr);
-
- // If the object hasn't been stored yet...
- if( handle_to == 0 )
- {
- // Store the object now
- asITypeInfo *type = GetType();
- CSerializedValue *need_create = new CSerializedValue(this, m_name, m_nameSpace, m_handlePtr, type->GetTypeId());
-
- // Make sure all other handles that point to the same object
- // are updated, so we don't end up creating duplicates
- CancelDuplicates(need_create);
-
- m_children.push_back(need_create);
- }
- }
-
- // Replace the handles in the children too
- for( size_t i = 0; i < m_children.size(); ++i )
- m_children[i]->ReplaceHandles();
+void CSerializedValue::ReplaceHandles() {
+ if (m_handlePtr) {
+ // Find the object that the handle is referring to
+ CSerializedValue *handle_to = m_serializer->m_root.FindByPtr(m_handlePtr);
+
+ // If the object hasn't been stored yet...
+ if (handle_to == 0) {
+ // Store the object now
+ asITypeInfo *type = GetType();
+ CSerializedValue *need_create = new CSerializedValue(this, m_name, m_nameSpace, m_handlePtr, type->GetTypeId());
+
+ // Make sure all other handles that point to the same object
+ // are updated, so we don't end up creating duplicates
+ CancelDuplicates(need_create);
+
+ m_children.push_back(need_create);
+ }
+ }
+
+ // Replace the handles in the children too
+ for (size_t i = 0; i < m_children.size(); ++i)
+ m_children[i]->ReplaceHandles();
}
-void CSerializedValue::RestoreHandles()
-{
- if( m_typeId & asTYPEID_OBJHANDLE )
- {
- if( m_handlePtr )
- {
- // Find the object the handle is supposed to point to
- CSerializedValue *handleTo = m_serializer->m_root.FindByPtr(m_handlePtr);
-
- if( m_restorePtr && handleTo && handleTo->m_restorePtr )
- {
- asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(m_typeId);
-
- // If the handle is already pointing to something it must be released first
- if( *(void**)m_restorePtr )
- m_serializer->m_engine->ReleaseScriptObject(*(void**)m_restorePtr, type);
-
- // Update the internal pointer
- *(void**)m_restorePtr = handleTo->m_restorePtr;
-
- // Increase the reference
- m_serializer->m_engine->AddRefScriptObject(handleTo->m_restorePtr, type);
- }
- }
- else
- {
- // If the handle is pointing to something, we must release it to restore the null pointer
- if( m_restorePtr && *(void**)m_restorePtr )
- {
- m_serializer->m_engine->ReleaseScriptObject(*(void**)m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_typeId));
- *(void**)m_restorePtr = 0;
- }
- }
- }
-
- // Do the same for the children
- for( size_t i = 0; i < m_children.size(); ++i )
- m_children[i]->RestoreHandles();
+void CSerializedValue::RestoreHandles() {
+ if (m_typeId & asTYPEID_OBJHANDLE) {
+ if (m_handlePtr) {
+ // Find the object the handle is supposed to point to
+ CSerializedValue *handleTo = m_serializer->m_root.FindByPtr(m_handlePtr);
+
+ if (m_restorePtr && handleTo && handleTo->m_restorePtr) {
+ asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(m_typeId);
+
+ // If the handle is already pointing to something it must be released first
+ if (*(void **)m_restorePtr)
+ m_serializer->m_engine->ReleaseScriptObject(*(void **)m_restorePtr, type);
+
+ // Update the internal pointer
+ *(void **)m_restorePtr = handleTo->m_restorePtr;
+
+ // Increase the reference
+ m_serializer->m_engine->AddRefScriptObject(handleTo->m_restorePtr, type);
+ }
+ } else {
+ // If the handle is pointing to something, we must release it to restore the null pointer
+ if (m_restorePtr && *(void **)m_restorePtr) {
+ m_serializer->m_engine->ReleaseScriptObject(*(void **)m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_typeId));
+ *(void **)m_restorePtr = 0;
+ }
+ }
+ }
+
+ // Do the same for the children
+ for (size_t i = 0; i < m_children.size(); ++i)
+ m_children[i]->RestoreHandles();
}
-void CSerializedValue::SetType(int typeId)
-{
- m_typeId = typeId;
+void CSerializedValue::SetType(int typeId) {
+ m_typeId = typeId;
- asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
+ asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
- if( type )
- m_typeName = type->GetName();
+ if (type)
+ m_typeName = type->GetName();
}
-asITypeInfo *CSerializedValue::GetType()
-{
- if( !m_typeName.empty() )
- {
- int newTypeId = m_serializer->m_mod->GetTypeIdByDecl(m_typeName.c_str());
- return m_serializer->m_engine->GetTypeInfoById(newTypeId);
- }
+asITypeInfo *CSerializedValue::GetType() {
+ if (!m_typeName.empty()) {
+ int newTypeId = m_serializer->m_mod->GetTypeIdByDecl(m_typeName.c_str());
+ return m_serializer->m_engine->GetTypeInfoById(newTypeId);
+ }
- return 0;
+ return 0;
}
-void CSerializedValue::SetUserData(void *data)
-{
- m_userData = data;
+void CSerializedValue::SetUserData(void *data) {
+ m_userData = data;
}
-void *CSerializedValue::GetUserData()
-{
- return m_userData;
+void *CSerializedValue::GetUserData() {
+ return m_userData;
}
END_AS_NAMESPACE