#pragma once // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 RESDATANODE_EXPORTS // 符号编译的。在使用此 DLL 的 // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将 // RESDATANODE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的 // 符号视为是被导出的。 #ifndef RESDATANODE_EXPORTS #ifdef _WIN64 #ifdef _DEBUG #pragma comment(lib, "ResDataNodeX64D.lib") #else #pragma comment(lib, "ResDataNodeX64.lib") #endif #else #ifdef _DEBUG #pragma comment(lib, "ResDataNodeD.lib") #else #pragma comment(lib, "ResDataNode.lib") #endif #endif #endif #ifdef RESDATANODE_EXPORTS #define RESDATANODE_API __declspec(dllexport) #define RESDATANODE_C_API extern "C" __declspec(dllexport) #else #define RESDATANODE_API __declspec(dllimport) #define RESDATANODE_C_API extern "C" __declspec(dllimport) #endif #include "LogicDevice.h" /* 因为资源的层太深的话,发通知会非常麻烦.(添加/删除/设置/读取...) 所以,规定的Rule是对象层最多2层,发通知最多2层结构,再深入的内容都作为Context处理. 一层结构:值对象, "KV":50. 更新POINT: key= "KV",Context="50" 二层结构:结构体对象, "APR": {"KV":50,"MA":20,...} 更新POINT: key= "APR",Context="KV:50" 二层结构:MAP对象 "DevMap":{"Dev1":"Driver","Dev2":"Device",....} 更新POINT: key= "DevMap",Context={"Dev1":"Driver"} 嵌套三层结构:MAP "AprMAP":{ "APR1":{"KV":50,"MA":20,...},"APR2":{"KV":50,"MA":20,...},...} 更新POINT: (作为2层结构处理,就算只有一个KV节点变更,也要把整个对象发送过去.) key= "AprMAP",Context=""APR1":{"KV":50,"MA":20,...}" */ class RESDATANODE_API ResDataNode; //for read/update use class RESDATANODE_API ResDataSubNodeContext { ResDataNode *m_pParent; vector *m_pKeyDepth; public: ResDataSubNodeContext(ResDataNode *Parent); virtual ~ResDataSubNodeContext(); //get context operator int(); operator unsigned int(); operator INT64(); operator UINT64(); operator float(); operator double(); operator const char*(); operator ResDataObject(); ResDataSubNodeContext operator [](const char *pKey); //set context ResDataSubNodeContext& operator = (const int tValue); ResDataSubNodeContext& operator = (const unsigned int tValue); ResDataSubNodeContext& operator = (const INT64 tValue); ResDataSubNodeContext& operator = (const UINT64 tValue); ResDataSubNodeContext& operator = (const float tValue); ResDataSubNodeContext& operator = (const double tValue); ResDataSubNodeContext& operator = (const char* pVal); ResDataSubNodeContext& operator = (const ResDataSubNodeContext &tValue); }; class RESDATANODE_API ResDataNode : public CcosLock { friend class ResDataSubNodeContext; protected: LogicDevice *m_pDevice; string *m_pMainKey;//主KEY跟CONTEXT要分离开来. ResDataObject m_Data;//动态CONTEXT ResDataObject m_StaticDescript;//静态CONTEXT //静态属性相关------------------------------------ //添加 bool AddStaticDesc(const char *pkey, ResDataObject &Context); bool AddStaticDesc(const char *pKey, const char *pDesc); bool AddStaticDesc(const char *pKey, FLOAT CellDesc); bool AddStaticDesc(const char *pKey, INT CellDesc); bool AddStaticDesc(const char *pkey, double CellDesc); bool AddStaticDesc(const char *pkey, INT64 CellDesc); public: ResDataNode(); ResDataNode(const char *pkey);//init with key virtual ~ResDataNode(void); size_t Size(); void SetLogicDevice(LogicDevice *pDevice); virtual const char *GetKey();//get key virtual void SetKey(const char *pKey);//set key ResDataObject &GetStaticDescript(); //GET---------- operator int(); operator unsigned int(); operator INT64(); operator UINT64(); operator float(); operator double(); operator const char*(); operator ResDataObject(); virtual ResDataSubNodeContext operator [](const char* pkey); virtual ResDataSubNodeContext operator [](size_t Idx);//for vector //SET---------- virtual ResDataNode& operator = (int tValue); virtual ResDataNode& operator = (unsigned int tValue); virtual ResDataNode& operator = (INT64 tValue); virtual ResDataNode& operator = (UINT64 tValue); virtual ResDataNode& operator = (float tValue); virtual ResDataNode& operator = (double tValue); virtual ResDataNode& operator = (const char* pVal); virtual ResDataNode& operator = (ResDataNode &tValue); virtual ResDataNode& operator = (ResDataObject &tValue); virtual ResDataNode& operator = (ResDataSubNodeContext &tValue); //UPDATE:use ResDataSubNodeContext::operator [] function. //ADD---------- virtual bool Add(ResDataObject &NodeObject); virtual bool Add(const char *pkey, ResDataObject &Context); //DEL---------- virtual bool Del(const char *pkey); virtual bool Del(size_t Idx);//for vector }; #define RES_CLASS_TYPE ("CLASS") typedef enum _RES_CLASS { RES_CLASS_VALUE, RES_CLASS_STRUCT, RES_CLASS_VECTOR, RES_CLASS_MAP, RES_CLASS_MAX }RESCLASS; #define RES_CONTEXT_TYPE ("CONTEXTTYPE") #define RES_SUBCONTEXT_TYPE ("SUBCONTEXTTYPE") typedef enum _RES_CONTEXT_TYPE { RES_CONTEXT_EMPTY, RES_CONTEXT_INT, RES_CONTEXT_FLOAT, RES_CONTEXT_STRING, RES_CONTEXT_VALUE, RES_CONTEXT_STRUCT, RES_CONTEXT_VECTOR, RES_CONTEXT_MAP, RES_CONTEXT_MAX }RESCONTEXT; //------------------------VALUE 模板定义------------------------------ /* T类型必须是ResDataObject能解析的类型 */ class RESDATANODE_API ResValue : public ResDataNode { public: ResValue(); virtual ~ResValue(void); //SET---------- virtual ResValue& operator = (int tValue); virtual ResValue& operator = (unsigned int tValue); virtual ResValue& operator = (INT64 tValue); virtual ResValue& operator = (UINT64 tValue); virtual ResValue& operator = (float tValue); virtual ResValue& operator = (double tValue); virtual ResValue& operator = (const char* pVal); virtual ResValue& operator = (ResDataNode &tValue); virtual ResValue& operator = (ResDataObject &tValue); virtual ResValue& operator = (ResDataSubNodeContext &tValue); //GET----------:使用下标不要 virtual ResDataSubNodeContext operator [](const char* pkey); virtual ResDataSubNodeContext operator [](size_t Idx); //ADD----------:不要 virtual bool Add(ResDataObject &NodeObject); virtual bool Add(const char *pkey, ResDataObject &Context); //DEL----------:不要 virtual bool Del(const char *pkey); virtual bool Del(size_t Idx); }; // //class KV : public ResValue //{ //public: // KV() // { // SetKey("KV"); // AddStaticDesc(RES_CONTEXT_TYPE, RES_CONTEXT_FLOAT); // AddStaticDesc(RES_SUBCONTEXT_TYPE, RES_CONTEXT_EMPTY); // }; // virtual ~KV(void) // { // // }; // //}; //------------------------STRUCT 定义------------------------------ class RESDATANODE_API ResStruct : public ResDataNode { public: ResStruct(); virtual ~ResStruct(void); //FULL GET:use ResDataNode::GetContext //FULL SET ResStruct& operator = (ResStruct &Val); //get: use operator [] //ADD&DEL不支持 //ADD----------:不要 virtual bool Add(ResDataObject &NodeObject); virtual bool Add(const char *pkey, ResDataObject &Context); //DEL----------:不要 virtual bool Del(const char *pkey); virtual bool Del(size_t Idx); }; // //class APR : public ResStruct //{ //public: // APR() // { // SetKey("APR"); // // Add("WS", 1); // Add("KV", 0.0f); // Add("MA", 0.0f); // Add("POSTKV", 0.0f); // Add("POSTMA", 0.0f); // Add("PATIENT", ""); // // // ResDataObject ContextType; // ContextType.add("WS", RES_CONTEXT_INT); // ContextType.add("KV", RES_CONTEXT_FLOAT); // ContextType.add("MA", RES_CONTEXT_FLOAT); // ContextType.add("POSTKV", RES_CONTEXT_FLOAT); // ContextType.add("POSTMA", RES_CONTEXT_FLOAT); // ContextType.add("PATIENT", RES_CONTEXT_STRING); // AddStaticDesc(RES_CONTEXT_TYPE, ContextType); // // AddStaticDesc(RES_SUBCONTEXT_TYPE, RES_CONTEXT_EMPTY); // }; // virtual ~APR(void) // { // // }; // //}; //------------------------MAP 定义------------------------------ /* 注意:KEY是唯一的 */ class RESDATANODE_API ResMap : public ResDataNode { public: ResMap(); virtual ~ResMap(void); }; //class AprMap : public ResMap //{ //public: // AprMap(){ // SetKey("APRMAP"); // // AddStaticDesc(RES_CONTEXT_TYPE, RES_CONTEXT_STRUCT); // // APR apr; // AddStaticDesc(RES_SUBCONTEXT_TYPE, apr.GetStaticDescript()[RES_CONTEXT_TYPE]); // // }; // virtual ~AprMap(void) // { // }; // // // // //}; //------------------------VECTOR 定义------------------------------ /* vector保存内容为[INT,FLOAT,STRING]的一种, 如果是保存的内容为对象的情况,跟ResMap没有区别了,所以vector除了保存基础信息以外意义不大. 重要:另一个问题是vector的存储内容不能重复,因为这样通知就非常暧昧,接收方不知道该更新哪个节点,后续有重复情况的时候需要再检讨. 所以,数组的节点必须是唯一的. 可以GETCONTEXT/SETCONTEXT,ADD,DEL 不要Update:Update操作调整为 DEL/ADD operator[](const char *pkey) 会失败且异常. */ /* 以下原因暂时不支持VECTOR,后续的技术调整成功后会做出VECTOR. 1.第一个最重要的原因是Boost库以XML文件形式读写JSON对象的时候,不支持JSON数组. 2.现在版本用下标访问的地方太多,要一个一个排查. 如果对象中有数组的话,在资源内容传递过程中,中间一个环节用字符串下标访问数组会直接崩溃. 3.ResDataObject现在还没有实现数组的套用,得做技术可行性分析,后续解决了套用数组的话,再考虑. 4.现阶段只有驱动服务和总线驱动会受到影响,问题不大. 目前纯粹的基础数据表格,设备层还没有太大的必要. */ template class ResVector : public ResDataNode { public: ResVector() { AddStaticDesc(RES_CLASS_TYPE, RES_CLASS_VECTOR); }; virtual ~ResVector(void) { }; //GET:用基类的. //UPDATE:不要 virtual bool Update(const char *pkey, ResDataObject &Context) { return false; }; virtual bool Update(const char *pkey, const char* pCell) { return false; }; virtual bool Update(const char *pkey, FLOAT CellDesc) { return false; }; virtual bool Update(const char *pkey, INT CellIdx) { return false; }; //ADD---------- virtual bool Add(const char *pkey, ResDataObject &Context) { throw ResDataObjectExption("deserted function for ResVector::Add1"); return false; }; virtual bool Add(const char *pkey, const char* pCell) { throw ResDataObjectExption("deserted function for ResVector::Add2"); return false; }; virtual bool Add(const char *pkey, FLOAT CellDesc) { throw ResDataObjectExption("deserted function for ResVector::Add3"); return false; }; virtual bool Add(const char *pkey, INT CellIdx) { throw ResDataObjectExption("deserted function for ResVector::Add4"); return false; }; virtual bool Add(const char* pCell) { assert(0);//not finished yet return false; }; virtual bool Add(FLOAT CellDesc) { assert(0);//not finished yet return false; }; virtual bool Add(INT CellIdx) { assert(0);//not finished yet return false; }; //下标字符串DEL不要 virtual bool Del(const char *pkey) { throw ResDataObjectExption("deserted function for ResVector::Del[str]"); return false; }; };