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

Last change on this file since 215 was 205, checked in by Maciej Komosinski, 11 years ago

Easier way to get an invalid ExtValue?

  • 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) 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 PtrListTempl<ParamInterface*> deserializable_classes;
163static ParamInterface *findDeserializableClass(const char* name);
164static void initDeserializableClasses();
165static SString format(SString& fmt,const ExtValue **values,int count);
166
167ExtValue getExtType();
168
169  private: // setrx - release and set, setx - assume released
170void setr(const ExtValue& src){setEmpty();set(src);}
171void set(const ExtValue& src);
172void setri(long v) {setEmpty();seti(v);}
173void setrd(double v) {setEmpty();setd(v);}
174void seti(long v) {type=TInt;idata()=v;}
175void setd(double v) {type=TDouble;ddata()=v;}
176#ifdef EXTVALUEUNION
177void setrs(const SString &v) {setEmpty();sets(v);}
178void setro(const ExtObject &src) {setEmpty();seto(src);}
179void sets(const SString &v) {type=TString;new(data) SString(v);}
180void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}
181#else
182void setrs(const SString &v) {setEmpty();sets(v);}
183void setro(const ExtObject &src) {setEmpty();seto(src);}
184void sets(const SString &v) {type=TString;s=new SString(v);}
185void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}
186#endif
187
188};
189
190
191#endif
Note: See TracBrowser for help on using the repository browser.