Nebula2探秘08-对象序列化

本文介绍Nebula2框架中的对象序列化机制,包括序列化与反序列化的实现方式,以及如何创建可序列化的对象。通过示例代码展示了序列化流程及对象复制过程。

Nebula2探秘08-对象序列化

happykevins文

Nebula2的对象序列化系统的设计思路:
Nebula2的对象序列化操作是完全依赖于脚本服务存在的。其设计思路就是根据一个Nebula对象的属性生成一个能够重新生成该对象的脚本文件,这个脚本文件必须
需要知道该Nebula对象的类型信息(需要RTTI的支持),其反序列化的过程就是将这
个对象New出来,然后通过一系列的setXXX方法将该对象的属性设回到序列化之前的样子,所以只要脚本服务的接口提供了构造这个序列化脚本文件的接口,Nebula就可以完成序列化操作了。

创建可序列化对象:
如果想创建一个可以支持Nebula序列化的类,必须至少要继承自nObject类,因为序列化需要nObject层的RTTI和脚本支持,但是最好是继承自nRoot类,这样就可以轻易的实现深度序列化(通过NOH将所有子节点都序列化)。本例中的nPersistObj由于没有深度序列化的需求,所以只做了继承自nObject的实现。可以参考nPersistObj的实现来理解Nebula序列化的实现方法。

Nebula2的对象复制(Clone):
另外每一个继承自nObject的Nebula2对象都可以实现Clone的功能;其实这个Clone功能和序列化走的是同一流程,只是没生成脚本文件而直接生成了一个新的对象而已。

下面将创建一个支持序列化的Nebula2对象,该对象需要具备以下条件:

1.支持序列化的对象必须是nObject的子类(一般继承自nRoot)
2.重写SaveCmds方法实现序列化操作
3.在序列化操作中首先要调用父类的SaveCmds方法以确保序列化的完整性
4.支持序列化的对象需要为脚本接口提供相应的属性设置指令,以支持反序列化操作

/****************************************************************************/
/*Nebula2-Tutorial08*/
/*Persistence-Nebula2的对象序列化*/
/*author:happykevins*/
/****************************************************************************/
#pragmaonce
#include
"kernel/nobject.h"

///----------------------------------------------------------------------------
///+支持序列化的Nebula2对象
classnPersistObj:publicnObject
{
public:
nPersistObj(){}
~nPersistObj(){}

///----------------------------------------------------------------------------
///序列化的接口
///@note:saveobjecttopersistentstream
///----------------------------------------------------------------------------
virtualboolSaveCmds(nPersistServer*ps);

///----------------------------------------------------------------------------
///+支持脚本指令
///

///setint
voidSetI(inti)
{
m_i
=i;
}
///setfloat
voidSetF(floatf)
{
m_f
=f;
}
///setstring
voidSetS(constchar*str)
{
m_str
=n_strdup(str);
}

///
///+支持脚本指令
///----------------------------------------------------------------------------

///printlog
voidPrint()
{
n_printf(
"Int:%d Float:%f String:%s ",m_i,m_f,m_str);
}

private:
intm_i;
floatm_f;
char*m_str;
};
///
///-支持序列化的Nebula2对象
///----------------------------------------------------------------------------
//cpp文件
#include"npersistobj.h"
#include
"kernel/nkernelserver.h"
#include
"kernel/npersistserver.h"
#include
"../NebulaUtils/nutildefs.h"

///声明为支持脚本的Nebula2对象,继承自nObject
nNebulaScriptModule(nPersistObj,npersistobj,"nobject");

///设置类属性的指令,用于反序列化时的脚本调用
staticvoidn_seti(void*,nCmd*);
staticvoidn_setf(void*,nCmd*);
staticvoidn_sets(void*,nCmd*);

///向Nebula2对象注册脚本指令
voidnNebulaScriptInitCmds(npersistobj)(nClass*clazz)
{
clazz
->BeginCmds();
clazz
->AddCmd("v_seti_i",'SETI',n_seti);
clazz
->AddCmd("v_setf_f",'SETF',n_setf);
clazz
->AddCmd("v_sets_s",'SETS',n_sets);
clazz
->EndCmds();
}

///设置类属性的指令
staticvoidn_seti(void*self,nCmd*cmd)
{
nPersistObj
*slf=(nPersistObj*)self;
slf
->SetI(cmd->In()->GetI());
}

staticvoidn_setf(void*self,nCmd*cmd)
{
nPersistObj
*slf=(nPersistObj*)self;
slf
->SetF(cmd->In()->GetF());
}

staticvoidn_sets(void*self,nCmd*cmd)
{
nPersistObj
*slf=(nPersistObj*)self;
slf
->SetS(cmd->In()->GetS());
}

///序列化的接口
boolnPersistObj::SaveCmds(nPersistServer*ps)
{
if(nObject::SaveCmds(ps))
{
nCmd
*cmd;

cmd
=ps->GetCmd(this,'SETI');
cmd
->In()->SetI(this->m_i);
ps
->PutCmd(cmd);

cmd
=ps->GetCmd(this,'SETF');
cmd
->In()->SetF(this->m_f);
ps
->PutCmd(cmd);

cmd
=ps->GetCmd(this,'SETS');
cmd
->In()->SetS(this->m_str);
ps
->PutCmd(cmd);

returntrue;
}
returnfalse;
}

下面是控制序列化对象的代码:

///----------------------------------------------------------------------------
///+声明使用的Nebula2Package&Module
nNebulaUseModule(ntclserver);
nNebulaUseModule(npersistobj);
///-声明使用的Nebula2Package&Module
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+Application
intmain(intargc,constchar**argv)
{
///创建KernelServer
nKernelServer*ks=n_new(nKernelServer);

nNebulaAddModule(ntclserver);
nNebulaAddModule(npersistobj);

///创建TclServer作为脚本服务器
///Nebula2的对象持久化操作是通过脚本来实现的
ks->New("ntclserver","/sys/servers/script");

///获得PersistServer(对象持久化服务)
nPersistServer*ps=(nPersistServer*)ks->Lookup("/sys/servers/persist");

///初始化对象
n_printf("*****OriginalObject***** ");
nPersistObj
*obj=(nPersistObj*)ks->New("npersistobj");
obj
->SetI(521);
obj
->SetF(3.14159f);
obj
->SetS("HelloNebula2!");
obj
->Print();

///----------------------------------------------------------------------------
///+序列化到文件
///
n_printf("*****UnserialedObject***** ");

//指定持久化模式(FOLD)
ps->SetSaveMode(nPersistServer::SAVEMODE_FOLD);

//序列化到nPersistObj.n2文件
obj->SaveAs("bin:nPersistObj.n2");

//释放New的对象
obj->Release();

//从nPersistObj.n2文件反序列化
obj=(nPersistObj*)ks->Load("bin:nPersistObj.n2");
obj
->Print();

///
///-序列化到文件
///----------------------------------------------------------------------------

///----------------------------------------------------------------------------
///+对象Clone
///
n_printf("*****ClonedObject***** ");

//指定持久化模式(CLONE)
ps->SetSaveMode(nPersistServer::SAVEMODE_CLONE);

//执行Clone操作
obj->Clone();

//释放原始对象
obj->Release();

//获得Clone的对象
nPersistObj*cloned=(nPersistObj*)ps->GetClone();
cloned
->Print();

///
///-对象Clone
///----------------------------------------------------------------------------

///销毁KernelServer
n_delete(ks);

getchar();
return0;
}
///-Application
///----------------------------------------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值