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

Last change on this file since 144 was 144, checked in by sz, 10 years ago

Param and ExtValue? improvements (better control on conversions, "load" returns the number of loaded fields)

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-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) 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);}
129long compare(const ExtValue& src) const;
130int operator==(const ExtValue& src) const;
131void operator+=(const ExtValue& src);
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)
137        {setr(src);}
138ExtValue(const ExtValue& src)
139        :type(TUnknown) {set(src);}
140void setEmpty();
141void setInvalid() {setEmpty();type=TInvalid;}
142bool makeUnique() {return (type==TObj) && odata().makeUnique();} //< @return false if nothing has changed
143ExtPType getType() {return type;}
144void *getObjectTarget(const char* classname) {return (type==TObj)?getObject().getTarget(classname):0;}
145void setInt(long v) {if (type!=TInt) setri(v); else idata()=v;}
146void setDouble(double v) {if (type!=TDouble) setrd(v); else ddata()=v;}
147void setString(const SString &v) {if (type!=TString) setrs(v); else sdata()=v;}
148void setObject(const ExtObject &src) {if (type!=TObj) setro(src); else odata()=src;}
149static long getInt(const char* s);
150static double getDouble(const char* s);
151long getInt() const;
152double getDouble() const;
153SString getString() const;
154const SString* getStringPtr() const;//< @return pointer to the internal sstring object or NULL if the current type is not string
155SString serialize() const;
156ExtObject getObject() const;
157bool isNull() const {return (type==TUnknown)||((type==TObj)&&odata().isEmpty());}
158const char* parseNumber(const char* in);
159const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed
160const char* deserialize_inner(const char* in);
161static PtrListTempl<ParamInterface*> deserializable_classes;
162static ParamInterface *findDeserializableClass(const char* name);
163static void initDeserializableClasses();
164static SString format(SString& fmt,const ExtValue **values,int count);
165
166ExtValue getExtType();
167
168  private: // setrx - release and set, setx - assume released
169void setr(const ExtValue& src){setEmpty();set(src);}
170void set(const ExtValue& src);
171void setri(long v) {setEmpty();seti(v);}
172void setrd(double v) {setEmpty();setd(v);}
173void seti(long v) {type=TInt;idata()=v;}
174void setd(double v) {type=TDouble;ddata()=v;}
175#ifdef EXTVALUEUNION
176void setrs(const SString &v) {setEmpty();sets(v);}
177void setro(const ExtObject &src) {setEmpty();seto(src);}
178void sets(const SString &v) {type=TString;new(data) SString(v);}
179void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}
180#else
181void setrs(const SString &v) {setEmpty();sets(v);}
182void setro(const ExtObject &src) {setEmpty();seto(src);}
183void sets(const SString &v) {type=TString;s=new SString(v);}
184void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}
185#endif
186
187};
188
189
190#endif
Note: See TracBrowser for help on using the repository browser.