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

Last change on this file since 257 was 257, checked in by Maciej Komosinski, 9 years ago
  • added strmove(): strcpy() for overlapping strings
  • ExtObject? operator== can handle NULL arguments
  • source formatting and improved genetic operator messages
  • Property svn:eol-style set to native
File size: 7.1 KB
RevLine 
[121]1// This file is a part of the Framsticks GDK.
[197]2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
[109]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;}
[171]60void* getTarget(const char* classname, bool through_barrier=true, bool warn=true) const;
[109]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
[257]67bool operator==(const ExtObject& src) const;
[109]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)];
[247]103paInt& idata() const {return (paInt&)data[0];};
[109]104double& ddata() const {return *(double*)data;};
105ExtObject& odata() const {return *(ExtObject*)data;};
106SString& sdata() const {return *(SString*)data;};
107#else
108union {
[247]109paInt i;
[109]110double d;
111SString *s;
112ExtObject *o;
113};
[247]114paInt& idata() const {return (paInt&)i;};
[109]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();}
[247]125ExtValue(paInt v) {seti(v);}
[109]126ExtValue(double v) {setd(v);}
127ExtValue(const SString &v) {sets(v);}
128ExtValue(const ExtObject &srco) {seto(srco);}
[205]129static ExtValue invalid() {ExtValue v; v.setInvalid(); return v;}
[247]130int compare(const ExtValue& src) const;
[109]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;}
[171]145void *getObjectTarget(const char* classname,bool warn=true) const;
[247]146void setInt(paInt v) {if (type!=TInt) setri(v); else idata()=v;}
[109]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;}
[247]150static paInt getInt(const char* s);
[144]151static double getDouble(const char* s);
[247]152paInt getInt() const;
[109]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;
[144]158bool isNull() const {return (type==TUnknown)||((type==TObj)&&odata().isEmpty());}
[228]159SString typeDescription() const;//< @return human readable type name (used in error messages)
[109]160const char* parseNumber(const char* in);
161const char* deserialize(const char* in);//< @return first character after the succesfully parsed string or NULL if failed
162const char* deserialize_inner(const char* in);
163static ParamInterface *findDeserializableClass(const char* name);
[222]164static PtrListTempl<ParamInterface*> &getDeserializableClasses();
165template<typename T> class AddDeserializable
166{
167  public:
168AddDeserializable() {ExtValue::getDeserializableClasses()+=&T::getStaticParam();}
169};
170
[109]171static SString format(SString& fmt,const ExtValue **values,int count);
172
173ExtValue getExtType();
174
175  private: // setrx - release and set, setx - assume released
176void setr(const ExtValue& src){setEmpty();set(src);}
177void set(const ExtValue& src);
[247]178void setri(paInt v) {setEmpty();seti(v);}
[109]179void setrd(double v) {setEmpty();setd(v);}
[247]180void seti(paInt v) {type=TInt;idata()=v;}
[109]181void setd(double v) {type=TDouble;ddata()=v;}
182#ifdef EXTVALUEUNION
183void setrs(const SString &v) {setEmpty();sets(v);}
184void setro(const ExtObject &src) {setEmpty();seto(src);}
185void sets(const SString &v) {type=TString;new(data) SString(v);}
186void seto(const ExtObject &src) {type=TObj;new(data) ExtObject(src);}
187#else
188void setrs(const SString &v) {setEmpty();sets(v);}
189void setro(const ExtObject &src) {setEmpty();seto(src);}
190void sets(const SString &v) {type=TString;s=new SString(v);}
191void seto(const ExtObject &src) {type=TObj;o=new ExtObject(src);}
192#endif
193
194};
195
[222]196#define REGISTER_DESERIALIZABLE(name) ExtValue::AddDeserializable<name> deserializable_autoinit_ ## name;
[109]197
198#endif
Note: See TracBrowser for help on using the repository browser.