科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Nebula2探秘08-对象序列化

Nebula2探秘08-对象序列化

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

介绍Nebula2对象序列化的来龙去脉...

作者:happykevins 来源:CSDN 2008年3月25日

关键字: 序列化 探秘 Nebula2 游戏 Linux

  • 评论
  • 分享微博
  • 分享邮件
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 - Tutorial 08                                                    */
/*  Persistence - Nebula2的对象序列化                                        */
/*  author: happykevins                                                        */
/****************************************************************************/
#pragma once
#include 
"kernel/nobject.h"

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

    
///----------------------------------------------------------------------------
    
/// 序列化的接口
    
/// @note:save object to persistent stream
    
///----------------------------------------------------------------------------
    virtual bool SaveCmds(nPersistServer* ps);

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

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

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

    
/// print log
    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;
}

 

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

///----------------------------------------------------------------------------
/// +声明使用的Nebula2 Package&Module
nNebulaUseModule(ntclserver);
nNebulaUseModule(npersistobj);
/// -声明使用的Nebula2 Package&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("*****Original Object***** ");
    nPersistObj
* obj = (nPersistObj*)ks->New("npersistobj");
    obj
->SetI(521);
    obj
->SetF(3.14159f);
    obj
->SetS("Hello Nebula2!");
    obj
->Print();

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

    
// 指定持久化模式(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("*****Cloned Object***** ");

    
// 指定持久化模式(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
///----------------------------------------------------------------------------
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章