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

Last change on this file since 276 was 276, checked in by Maciej Komosinski, 7 years ago

Empty stock objects for convenience

  • Property svn:eol-style set to native
File size: 7.3 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;}
63static const ExtObject& empty() { static const ExtObject& e((ParamInterface*)NULL); return e; }
64ExtObject(const ExtObject& src)      {src.incref();copyFrom(src);}
65void operator=(const ExtObject& src) {src.incref();decref();copyFrom(src);}
66bool makeUnique();//< @return false if nothing has changed
67
68bool operator==(const ExtObject& src) const;
69
70SString toString() const;
71SString serialize_inner() const;
72SString serialize() const;
73
74ExtObject(Param *p,void *o):subtype(2),object(o),param(p){}
75ExtObject(ParamInterface *p=0):subtype(0),object(0),paraminterface(p){}
76ExtObject(Param *p,DestrBase *o):subtype(1+2),dbobject(o),param(p){incref();}
77ExtObject(ParamInterface *p,DestrBase *o):subtype(1),dbobject(o),paraminterface(p){incref();}
78
79~ExtObject(){decref();}
80
81class Serialization
82{
83std::vector<ExtObject> refs;
84int level;
85  public:
86Serialization():level(0) {}
87void begin();
88void end();
89int add(const ExtObject& o);
90void replace(const ExtObject& o,const ExtObject& other);
91void remove(const ExtObject& o);
92const ExtObject* get(int ref);
93};
94
95static THREAD_LOCAL_DECL(Serialization,serialization);
96};
97
98class ExtValue
99{
100public:
101ExtPType type;
102#ifdef EXTVALUEUNION
103long data[(EXTVALUEUNIONSIZE+sizeof(long)-1)/sizeof(long)];
104paInt& idata() const {return (paInt&)data[0];};
105double& ddata() const {return *(double*)data;};
106ExtObject& odata() const {return *(ExtObject*)data;};
107SString& sdata() const {return *(SString*)data;};
108#else
109union {
110paInt i;
111double d;
112SString *s;
113ExtObject *o;
114};
115paInt& idata() const {return (paInt&)i;};
116double& ddata() const {return (double&)d;};
117ExtObject& odata() const {return *o;};
118SString& sdata() const {return *s;};
119#endif
120
121void* operator new(size_t s, void* mem) {return mem;}
122void* operator new(size_t s) {return ::operator new(s);}
123
124ExtValue():type(TUnknown){}
125~ExtValue() {setEmpty();}
126ExtValue(paInt v) {seti(v);}
127ExtValue(double v) {setd(v);}
128ExtValue(const SString &v) {sets(v);}
129ExtValue(const ExtObject &srco) {seto(srco);}
130static ExtValue invalid() {ExtValue v; v.setInvalid(); return v;}
131static const ExtValue& empty() { static const ExtValue v; return v; }
132int compare(const ExtValue& src) const;
133int operator==(const ExtValue& src) const;
134void operator+=(const ExtValue& src);
135void operator-=(const ExtValue& src);
136void operator*=(const ExtValue& src);
137void operator/=(const ExtValue& src);
138void operator%=(const ExtValue& src);
139void operator=(const ExtValue& src)
140        {setr(src);}
141ExtValue(const ExtValue& src)
142        :type(TUnknown) {set(src);}
143void setEmpty();
144void setInvalid() {setEmpty();type=TInvalid;}
145bool makeUnique() {return (type==TObj) && odata().makeUnique();} //< @return false if nothing has changed
146ExtPType getType() {return type;}
147void *getObjectTarget(const char* classname,bool warn=true) const;
148void setInt(paInt v) {if (type!=TInt) setri(v); else idata()=v;}
149void setDouble(double v) {if (type!=TDouble) setrd(v); else ddata()=v;}
150void setString(const SString &v) {if (type!=TString) setrs(v); else sdata()=v;}
151void setObject(const ExtObject &src) {if (type!=TObj) setro(src); else odata()=src;}
152static paInt getInt(const char* s);
153static double getDouble(const char* s);
154paInt getInt() const;
155double getDouble() const;
156SString getString() const;
157const SString* getStringPtr() const;//< @return pointer to the internal sstring object or NULL if the current type is not string
158SString serialize() const;
159ExtObject getObject() const;
160bool isNull() const {return (type==TUnknown)||((type==TObj)&&odata().isEmpty());}
161SString typeDescription() const;//< @return human readable type name (used in error messages)
162const char* parseNumber(const char* in);
163const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed
164const char* deserialize_inner(const char* in);
165static ParamInterface *findDeserializableClass(const char* name);
166static PtrListTempl<ParamInterface*> &getDeserializableClasses();
167template<typename T> class AddDeserializable
168{
169  public:
170AddDeserializable() {ExtValue::getDeserializableClasses()+=&T::getStaticParam();}
171};
172
173static SString format(SString& fmt,const ExtValue **values,int count);
174
175ExtValue getExtType();
176
177  private: // setrx - release and set, setx - assume released
178void setr(const ExtValue& src){setEmpty();set(src);}
179void set(const ExtValue& src);
180void setri(paInt v) {setEmpty();seti(v);}
181void setrd(double v) {setEmpty();setd(v);}
182void seti(paInt v) {type=TInt;idata()=v;}
183void setd(double v) {type=TDouble;ddata()=v;}
184#ifdef EXTVALUEUNION
185void setrs(const SString &v) {setEmpty();sets(v);}
186void setro(const ExtObject &src) {setEmpty();seto(src);}
187void sets(const SString &v) {type=TString;new(data) SString(v);}
188void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}
189#else
190void setrs(const SString &v) {setEmpty();sets(v);}
191void setro(const ExtObject &src) {setEmpty();seto(src);}
192void sets(const SString &v) {type=TString;s=new SString(v);}
193void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}
194#endif
195
196};
197
198#define REGISTER_DESERIALIZABLE(name) ExtValue::AddDeserializable<name> deserializable_autoinit_ ## name;
199
200#endif
Note: See TracBrowser for help on using the repository browser.