diff options
Diffstat (limited to 'Source/Scripting/angelscript/add_on/serializer/serializer.cpp')
-rw-r--r-- | Source/Scripting/angelscript/add_on/serializer/serializer.cpp | 832 |
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 |