hi,
I registered a class and methods that should serialize and de-serialize a angelscript dictionary object (addon) from C++.
In order to do that, I should be able to iterate on dictionary structure, identify each item type, and get it's value. And then recurse if an item is a dictionary,. That's the goal.
For serialization (which I will think better after) I will need to create the objects used in angelscript and insert them into dictionary from C++ side.
I'm having trouble to manipulate dictionary class using CScriptDictionary::CIterator at C++ side.
Some constructors methods are protected, and I could not use CIterator properly.
Already tried some changes on CScriptDictionary, without success, and I think maybe there is a way whithout changing anything.
So, I need help.
Serializing and de-serializing dictionary
For those with similar problem: I ended up using CScriptDictionary::GetKeys() wich returns a CScriptArray*, and then loop through it.
Also I found that the CScriptArray addon interface documentation gives good clues on creating an instance from C++ side.
In the code sample below, Pack() is the serializer method and has an overload for each type.
void WebsocketClient::Pack(const CScriptDictionary& dictionary)
{
if (dictionary.IsEmpty())
return;
CScriptArray* keys = dictionary.GetKeys();
asUINT size = dictionary.GetSize();
PackMap(size);
for (asUINT i = 0; i < size; i++)
{
dictKey_t key(*(dictKey_t*)keys->At(i));
int type_id = dictionary[key]->GetTypeId();
const void* value = dictionary[key]->GetAddressOfValue();
if (!value)
PackNil();
Pack(key);
switch (type_id)
{
case asTYPEID_DOUBLE:
Pack(*(double*)value);
break;
case asTYPEID_FLOAT:
Pack(*(float*)value);
break;
case asTYPEID_INT64:
Pack(*(int64_t*)value);
break;
case asTYPEID_INT32:
Pack(*(int32_t*)value);
break;
case asTYPEID_INT16:
Pack(*(int16_t*)value);
break;
case asTYPEID_INT8:
Pack(*(int8_t*)value);
break;
case asTYPEID_UINT64:
Pack(*(uint64_t*)value);
break;
case asTYPEID_UINT32:
Pack(*(uint32_t*)value);
break;
case asTYPEID_UINT16:
Pack(*(uint16_t*)value);
break;
case asTYPEID_UINT8:
Pack(*(uint8_t*)value);
break;
case asTYPEID_BOOL:
Pack(*(bool*)value);
break;
// if it is not a const value, use cached type_id (type_id defined at AS engine runtime)
default:
if (type_id == m_string_type_id)
Pack(*(std::string*)value);
else if (type_id == m_vector2_type_id)
Pack(*(Vector2*)value);
else if (type_id == m_vector3_type_id)
Pack(*(Vector3*)value);
// check if type_id match with any of the template specialization
else if (isCScriptArray(type_id))
Pack(*(CScriptArray*)value);
else if (type_id == m_dictionary_type_id)
Pack(*(CScriptDictionary*)value);
}
}
}
If you still want to use the iterator, it works like this:
void foo(CScriptDictionary *dict)
{
for (auto it : *dict)
{
std::string keyName = it.GetKey();
int typeId = it.GetTypeId();
const void *addressOfValue = it.GetAddressOfValue();
// serialize the key and value pair the same way you already do
}
}
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement