Nebula2探秘08-对象序列化

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 */
/* ************************************************************************** */
#pragma once
#include
" kernel/nobject.h "

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

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

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

/// setint
void SetI( int i)
{
m_i
= i;
}
/// setfloat
void SetF( float f)
{
m_f
= f;
}
/// setstring
void SetS( const char * str)
{
m_str
= n_strdup(str);
}

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

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

private :
int m_i;
float m_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 " );

/// 设置类属性的指令,用于反序列化时的脚本调用
static void n_seti( void * ,nCmd * );
static void n_setf( void * ,nCmd * );
static void n_sets( void * ,nCmd * );

/// 向Nebula2对象注册脚本指令
void nNebulaScriptInitCmds(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();
}

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

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

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

/// 序列化的接口
bool nPersistObj::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);

return true ;
}
return false ;
}

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

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

/// ----------------------------------------------------------------------------
/// +Application
int main( int argc, const char ** 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();
return 0 ;
}
/// -Application
/// ----------------------------------------------------------------------------

你可能感兴趣的:(设计模式,脚本,F#)