Im Gonna start by saying this question is a preview over about 500+ lines of code (including the default code in CSerializer.h and .cpp) So please ask if something doesnt make sense.
Struct node
{
vec o, vec rot; //vector 3 position and rotation repectively.
asIScriptObject *ctrl; //script controler aka user code
CSerializeObject *savedata;
void store()
{
if (!c) c = asScript->serializer->storenode(this);
}
}
This is my base object that needs to be added to the angel script code. This object and all of asObjectType list of members, need to saved to the file.
When serializing this object this is how it its done right now.
int CSerialnode::nodeID = -1; //changed at init to the id of Node set by the engine
int CSerialvec::nodeID = -1; //changed at init to the id of Vec set by the engine
CSerializedValue * CSerializer::storenode(node *g)
{
if (!m_engine)return NULL;
if(!g)return NULL;
CSerializedValue *c = new CSerializedValue(&m_root, "SERIAL_OBJECT" , "", g, CSerialnode::nodeID);
m_root.m_children.push_back(c);
return c;
}
//NOTE CSerialnode and CSerialvec inherients CUserType
void CSerialnode::Store(CSerializedValue *val, void *ptr)
{
node *g = (node *)ptr;
vec *o = new vec(g->o);
vec *rot = new vec(g->rot);
val->m_children.push_back(new CSerializedValue(val, "pos", "", new vec(g->o), CSerialVec::getID())); //store vec o
val->m_children.push_back(new CSerializedValue(val, "rot", "", new vec(g->rot), CSerialVec::getID())); // store vec rot
val->m_children.push_back(new CSerializedValue(val, "ctrl", "", g->ctrl, g->ctrl->GetTypeId())); //store the controler for this element
}
void CSerialnode::Restore(CSerializedValue *val, void *ptr)
{
node *g = (node *)ptr;
val->m_children[0]->Restore(&g->o, CSerialVec::getID());
val->m_children[1]->Restore(&g->rot, CSerialVec::getID());
if (val->m_children[2]) val->m_children[2]->Restore(g->ctrl->object, g->ctrl->object->GetTypeId());
}
bool node::restore()
{
if (!c) return false; //if no c then object wasnt saved, so delete object.
c->Restore(this,CSerialnode::getID());
}
This kinda works sometimes I feel like there is some kinda error here when passing the pointers around ??
When Writting to file, The code looks as follows.
The concept here is Get all the Namespaces Types, and names in the tree. Then store each object using an ID for each of the before (namespaceID, typeID, nameID). Then first store the vector of strings with the data, then list all the objects using IDs to reference the spot in the vector. This code works almost flawlessly. The question is how do i Reinitialize the object.
void CSerializer::save(stream *f)
{
if (!m_engine) SetEngine(asScript->asEngine); //force the engine only using one engine so this should nv call.
names.shrink(0);
types.shrink(0);
namespaces.shrink(0);
saveddata.shrink(0);
names.put("__ERROR__");
m_root.save();
PUTLILVECTOR(namespaces);
PUTLILVECTOR(types);
PUTLILVECTOR(names);
f->putlil<uint>(saveddata.length());
loopv(saveddata)
saveddata[i]->write(f);
}
void CSerializer::load(stream *f)
{
if (!m_engine) SetEngine(asScript->asEngine);
m_root.ClearChildren();
names.shrink(0);
types.shrink(0);
namespaces.shrink(0);
saveddata.shrink(0);
PULLLILVECTOR(namespaces);
PULLLILVECTOR(types);
PULLLILVECTOR(names);
uint size = f->getlil<uint>();
//conoutf("%d", size);
loopi(size)saveddata.put(DataHold::read(f));
loopv(saveddata)
{
DataHold &sd = *saveddata[i];
sd.print();
}
m_root.m_typeId = 0;
m_root.m_name = "root";
m_root.m_nameSpace = "";
m_root.m_isInit = true;
m_root.load(0);
//return;
loopi(m_root.m_children.size())
{
//what do I put here.
//can i just put
node *n = new node();
m_root[i].restore(*n, Serialnode::getId());
world.addnode(n);
}
}
//this is where I load up the tree.
void CSerializedValue::load(uint index)
{
loopioff( 1, saveddata.length())
{
DataHold &sd = *saveddata[i];
CSerializedValue *child;
str name = names[VECTOROVERLOADCHECK(names, sd.nameID)];
str tname = types[VECTOROVERLOADCHECK(types, sd.typeID - (asTYPEID_DOUBLE + 1))];
str nameSP = namespaces[VECTOROVERLOADCHECK(namespaces, sd.namespaceID)];
asIObjectType *ot;
if (sd.typeID > asTYPEID_DOUBLE)
{
if (tname == str("__ERROR__")) tname = "void";
ot = asScript->asEngine->GetObjectTypeByName(tname.c_str());
if (!ot)
{
asScript->recompilemodule(tname.c_str());
asIScriptModule *mod = asScript->asEngine->GetModule(tname.c_str());
if (!mod){ conoutf("ERROR!!! no mod"); return; }
ot = mod->GetObjectTypeByName(tname.c_str());
}
}
else continue; //handle globals here
if (ot)
{
int typeID = ot->GetTypeId();
void * newptr = asScript->asEngine->CreateUninitializedScriptObject(ot);
child = new CSerializedValue(this, name, nameSP, newptr, typeID);
this->m_children.push_back(child);
}
else conoutf("ooops");
i = sd.count(i)-1;//jump to next asObject type
}
}
As of right now, it goes between not creating the object to, throwing a nullpointer error when loading the nodes. inside that last section where I actually create the object and add it to the scene.
Any help would be great. Sorrie If it seems a bit of a a mess. Im trying to reduce the amount of code to make it easier to read.
chasester