source: cpp/frams/util/extvalue.h @ 222

Last change on this file since 222 was 222, checked in by Maciej Komosinski, 10 years ago

"Distributed" deserializable class registry, so that ExtValue? does not depend on so many other classes

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#ifndef _EXTVALUE_H_
6#define _EXTVALUE_H_
7
8#include "sstring.h"
9#include <frams/param/param.h>
10#include <common/nonstd_stl.h>
11#include <common/threads.h>
12
13#define EXTVALUEUNION
14template <int A,int B> struct CompileTimeMax {enum {val=A>B?A:B}; };
15#define EXTVALUEUNIONSIZE CompileTimeMax<sizeof(ExtObject),sizeof(SString)>::val
16
17enum ExtPType
18{TUnknown=0,TInt,TDouble,TString,TObj,TInvalid};
19
20/**
21   destructable object
22 */
23class DestrBase
24{
25public:
26int refcount;
27DestrBase():refcount(0) {}
28void incref() {refcount++;}
29void decref() {refcount--; if (refcount==0) delete this;}
30virtual ~DestrBase() {}
31};
32
33/**
34   object reference.
35 */
36class ExtObject
37{
38int subtype;                    //< 0/1=Generic/DPC Object,  0/2=Standalone/Shared Param
39void incref() const;
40void decref() const;
41  public:
42union { void* object;           //< generic object, will use param
43DestrBase *dbobject;};  //< object with refcounting, will be deleted if refcount goes to 0
44union { Param* param;           //< if object!=0
45        ParamInterface *paraminterface;}; //< if object==0
46
47void copyFrom(const ExtObject& src)  {subtype=src.subtype;object=src.object;param=src.param;}
48
49void* operator new(size_t s, void* mem) {return mem;}
50#ifdef _MSC_VER
51void operator delete(void* mem,void* t) {}
52#endif
53void* operator new(size_t s) {return malloc(sizeof(ExtObject));}
54void operator delete(void* mem) {free(mem);}
55///@param tmp_param can be used for temporary storage, the result ParamInterface* is only valid for as long as tmp_param is valid
56ParamInterface *getParamInterface(Param &tmp_param) const  {if(subtype&2){tmp_param.setParamTab(param->getParamTab());tmp_param.select(object);return &tmp_param;} return paraminterface;}
57const char* interfaceName() const {if (isEmpty()) return "Empty"; return (subtype&2)?param->getName():paraminterface->getName();}
58bool matchesInterfaceName(ParamInterface* pi) const {return !strcmp(interfaceName(),pi->getName());}
59void* getTarget() const {return (subtype&1)?dbobject:object;}
60void* getTarget(const char* classname, bool through_barrier=true, bool warn=true) const;
61void setEmpty() {decref();subtype=0;param=NULL;object=NULL;}
62int isEmpty() const {return !param;}
63ExtObject(const ExtObject& src)      {src.incref();copyFrom(src);}
64void operator=(const ExtObject& src) {src.incref();decref();copyFrom(src);}
65bool makeUnique();//< @return false if nothing has changed
66
67int operator==(const ExtObject& src) const {if (object!=src.object) return 0; return (object==0)?(!strcmp(param->getName(),src.param->getName())):1;}
68
69SString toString() const;
70SString serialize_inner() const;
71SString serialize() const;
72
73ExtObject(Param *p,void *o):subtype(2),object(o),param(p){}
74ExtObject(ParamInterface *p=0):subtype(0),object(0),paraminterface(p){}
75ExtObject(Param *p,DestrBase *o):subtype(1+2),dbobject(o),param(p){incref();}
76ExtObject(ParamInterface *p,DestrBase *o):subtype(1),dbobject(o),paraminterface(p){incref();}
77
78~ExtObject(){decref();}
79
80class Serialization
81{
82std::vector<ExtObject> refs;
83int level;
84  public:
85Serialization():level(0) {}
86void begin();
87void end();
88int add(const ExtObject& o);
89void replace(const ExtObject& o,const ExtObject& other);
90void remove(const ExtObject& o);
91const ExtObject* get(int ref);
92};
93
94static THREAD_LOCAL_DECL(Serialization,serialization);
95};
96
97class ExtValue
98{
99public:
100ExtPType type;
101#ifdef EXTVALUEUNION
102long data[(EXTVALUEUNIONSIZE+sizeof(long)-1)/sizeof(long)];
103long& idata() const {return (long&)data[0];};
104double& ddata() const {return *(double*)data;};
105ExtObject& odata() const {return *(ExtObject*)data;};
106SString& sdata() const {return *(SString*)data;};
107#else
108union {
109long i;
110double d;
111SString *s;
112ExtObject *o;
113};
114long& idata() const {return (long&)i;};
115double& ddata() const {return (double&)d;};
116ExtObject& odata() const {return *o;};
117SString& sdata() const {return *s;};
118#endif
119
120void* operator new(size_t s, void* mem) {return mem;}
121void* operator new(size_t s) {return ::operator new(s);}
122
123ExtValue():type(TUnknown){}
124~ExtValue() {setEmpty();}
125ExtValue(long v) {seti(v);}
126ExtValue(double v) {setd(v);}
127ExtValue(const SString &v) {sets(v);}
128ExtValue(const ExtObject &srco) {seto(srco);}
129static ExtValue invalid() {ExtValue v; v.setInvalid(); return v;}
130long compare(const ExtValue& src) const;
131int operator==(const ExtValue& src) const;
132void operator+=(const ExtValue& src);
133void operator-=(const ExtValue& src);
134void operator*=(const ExtValue& src);
135void operator/=(const ExtValue& src);
136void operator%=(const ExtValue& src);
137void operator=(const ExtValue& src)
138        {setr(src);}
139ExtValue(const ExtValue& src)
140        :type(TUnknown) {set(src);}
141void setEmpty();
142void setInvalid() {setEmpty();type=TInvalid;}
143bool makeUnique() {return (type==TObj) && odata().makeUnique();} //< @return false if nothing has changed
144ExtPType getType() {return type;}
145void *getObjectTarget(const char* classname,bool warn=true) const;
146void setInt(long v) {if (type!=TInt) setri(v); else idata()=v;}
147void setDouble(double v) {if (type!=TDouble) setrd(v); else ddata()=v;}
148void setString(const SString &v) {if (type!=TString) setrs(v); else sdata()=v;}
149void setObject(const ExtObject &src) {if (type!=TObj) setro(src); else odata()=src;}
150static long getInt(const char* s);
151static double getDouble(const char* s);
152long getInt() const;
153double getDouble() const;
154SString getString() const;
155const SString* getStringPtr() const;//< @return pointer to the internal sstring object or NULL if the current type is not string
156SString serialize() const;
157ExtObject getObject() const;
158bool isNull() const {return (type==TUnknown)||((type==TObj)&&odata().isEmpty());}
159const char* parseNumber(const char* in);
160const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed
161const char* deserialize_inner(const char* in);
162static ParamInterface *findDeserializableClass(const char* name);
163static PtrListTempl<ParamInterface*> &getDeserializableClasses();
164template<typename T> class AddDeserializable
165{
166  public:
167AddDeserializable() {ExtValue::getDeserializableClasses()+=&T::getStaticParam();}
168};
169
170static SString format(SString& fmt,const ExtValue **values,int count);
171
172ExtValue getExtType();
173
174  private: // setrx - release and set, setx - assume released
175void setr(const ExtValue& src){setEmpty();set(src);}
176void set(const ExtValue& src);
177void setri(long v) {setEmpty();seti(v);}
178void setrd(double v) {setEmpty();setd(v);}
179void seti(long v) {type=TInt;idata()=v;}
180void setd(double v) {type=TDouble;ddata()=v;}
181#ifdef EXTVALUEUNION
182void setrs(const SString &v) {setEmpty();sets(v);}
183void setro(const ExtObject &src) {setEmpty();seto(src);}
184void sets(const SString &v) {type=TString;new(data) SString(v);}
185void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}
186#else
187void setrs(const SString &v) {setEmpty();sets(v);}
188void setro(const ExtObject &src) {setEmpty();seto(src);}
189void sets(const SString &v) {type=TString;s=new SString(v);}
190void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}
191#endif
192
193};
194
195#define REGISTER_DESERIALIZABLE(name) ExtValue::AddDeserializable<name> deserializable_autoinit_ ## name;
196
197#endif
Note: See TracBrowser for help on using the repository browser.