source: cpp/frams/param/mutableparam.cpp @ 535

Last change on this file since 535 was 535, checked in by Maciej Komosinski, 8 years ago
  • More strict type description checking when adding a property in mutableparam
  • Error message when the param property could not be added for some reason
  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "mutableparam.h"
6#include <frams/util/extvalue.h>
7
8#define FIELDSTRUCT MutableParam
9ParamEntry MutableParam::pe_tab[]=
10{
11{"clear",0,PARAM_DONTSAVE | PARAM_USERHIDDEN,"remove all properties","p",PROCEDURE(p_clear),},
12{"add",0,PARAM_DONTSAVE | PARAM_USERHIDDEN,"add property (id,type,name,help)","p",PROCEDURE(p_addprop),},
13{"remove",0,PARAM_DONTSAVE | PARAM_USERHIDDEN,"remove property (index)","p",PROCEDURE(p_remprop),},
14{"addGroup",0,PARAM_DONTSAVE | PARAM_USERHIDDEN,"add group (name)","p",PROCEDURE(p_addgroup),},
15{"removeGroup",0,PARAM_DONTSAVE | PARAM_USERHIDDEN,"remove group (index)","p",PROCEDURE(p_remgroup),},
16{"changedProperty",0,PARAM_DONTSAVE | PARAM_USERHIDDEN | PARAM_READONLY,"last changed property #","d",FIELD(changed),},
17{"changedPropertyId",0,PARAM_DONTSAVE | PARAM_USERHIDDEN | PARAM_READONLY,"last changed property id","s",GETONLY(changedname),},
18};
19#undef FIELDSTRUCT
20
21MutableParam::MutableParam(const char*n,const char*g,int gr0)
22        :SimpleAbstractParam(this,n),persistgroup0(gr0),grprefix(g)
23{
24if (persistgroup0)
25        addGroup(grprefix,1);
26}
27
28int MutableParam::findGroup(const SString name,int ignoreprefix)
29{
30int skipprefix=grprefix.len()?grprefix.len()+2:0;
31for (int i=0;i<groups.size();i++)
32        {
33        if (ignoreprefix)
34                {
35      const char *noprefix=groupname(i).c_str();
36      if ((int)strlen(noprefix) < skipprefix) continue;
37                noprefix+=skipprefix;
38                if (!strcmp(noprefix,name.c_str())) return i;
39                }
40                else
41                        if (groupname(i)==name) return i;
42        }
43return -1;
44}
45
46int MutableParam::addGroup(const SString& gname,int noprefix)
47{
48SString tmp;
49if (noprefix)
50        tmp=gname;
51else
52        {
53        tmp=grprefix;
54        if (tmp.len()) tmp+=": ";
55        tmp+=gname;
56        }
57groups+=new SString(tmp);
58int position=groups.size()-1;
59ongroupadd.action(position);
60return position;
61}
62
63void MutableParam::removeGroup(int g)
64{
65if ((g<0)||(g>=MutableParam::getGroupCount())) return;
66ParamEntry *e;
67for (int i=MutableParam::getPropCount()-1;i>=staticprops;i--)
68        {
69        e=entry(i);
70        if (g==e->group)
71                removeProperty(i);
72        }
73SString *s=(SString *)groups(g);
74if (s) delete s;
75groups-=g;
76ongroupdelete.action(g);
77}
78
79int MutableParam::grmember(int g,int a)
80{
81if (g==0)
82        {
83        if (getGroupCount()<2)
84                return (a<getPropCount())?a:-9999;
85        if (a<staticprops) return a;
86        a-=staticprops;
87        }
88ParamEntry *e;
89for (int i=staticprops;e=entry(i);i++)
90        if (g==e->group)
91                if (!a--) return i;
92return -9999;
93}
94
95int MutableParam::addProperty(ParamEntry *pe,int position)
96{
97DB(printf("MutableParam::add(%s)\n",pe->id));
98if (position<0)
99        position=entries.size()+staticprops;
100entries.insert(position-staticprops,pe);
101
102if (pe->offset)
103        pe->flags &= ~MUTPARAM_ALLOCDATA;
104else
105        {
106        pe->flags |= MUTPARAM_ALLOCDATA;
107        void *d=0;
108        switch(pe->type[0])
109                {
110                case 'd': d=new paInt(); *((paInt*)d)=0; break;
111                case 'f': d=new double(); *((double*)d)=0; break;
112                case 's': d=new SString(); break;
113                case 'x': d=new ExtValue(); break;
114                case 'o': d=new ExtObject(); break;
115                }
116        pe->offset=(intptr_t)d;
117        }
118onadd.action(position);
119return position;
120}
121
122ParamEntry * MutableParam::removeProperty(ParamEntry *pe)
123{
124   int index=entries.find(pe);
125   if (index>=0) return removeProperty(index); else return pe;
126}
127
128ParamEntry * MutableParam::removeProperty(int i)
129{
130ParamEntry *pe=(ParamEntry *)entries(i-staticprops);
131DB(printf("MutableParam::remove(%d)\n",i));
132void *d=(void*)pe->offset;
133if (d && (pe->flags & MUTPARAM_ALLOCDATA))
134        switch(pe->type[0])
135                {
136                case 'd': delete (paInt*)d; break;
137                case 'f': delete (double*)d; break;
138                case 's': delete (SString*)d; break;
139                case 'x': delete (ExtValue*)d; break;
140                case 'o': delete (ExtObject*)d; break;
141                }
142entries-=i-staticprops;
143if (pe->flags & MUTPARAM_ALLOCENTRY)
144        {
145        if (pe->name) free((void*)pe->name);
146        if (pe->id) free((void*)pe->id);
147        if (pe->help) free((void*)pe->help);
148        if (pe->type) free((void*)pe->type);
149        delete pe;
150        }
151ondelete.action(i);
152return pe;
153}
154
155void MutableParam::clear(int everything)
156{
157DB(printf("MutableParam::clear\n"));
158for (int i=entries.size()-1;i>=0;i--)
159        removeProperty(i+staticprops);
160int lastgroup=(everything || (persistgroup0==0))?0:1;
161for (int i=groups.size()-1;i>=lastgroup;i--)
162        removeGroup(i);
163}
164
165void MutableParam::p_clear(ExtValue *args,ExtValue *ret)
166{ clear(); }
167
168int MutableParam::addProperty(void* data,const char* id,const char* type,const char* name,const char* help,int flags,int group,int position)
169{
170if ((!id)&&(!type)) return -1;
171if (!isValidTypeDescription(type)) return -1;
172ParamEntry *pe=new ParamEntry();
173pe->fun1=0; pe->fun2=0;
174pe->group=(paInt)group;
175pe->flags=(paInt)(flags | MUTPARAM_ALLOCENTRY);
176pe->offset=(intptr_t)data;
177pe->id=strdup(id);
178pe->type=strdup(type);
179pe->name=name?strdup(name):0;
180pe->help=help?strdup(help):0;
181return addProperty(pe,position);
182}
183
184void MutableParam::p_addprop(ExtValue *args,ExtValue *ret)
185{
186int i=addProperty(0,args[2].getString().c_str(),args[1].getString().c_str(),args[0].getString().c_str());
187ret->setInt(i);
188}
189
190void MutableParam::p_remprop(ExtValue *args,ExtValue *ret)
191{
192removeProperty(args[0].getInt());
193}
194
195void MutableParam::p_addgroup(ExtValue *args,ExtValue *ret)
196{
197int i=addGroup(args[0].getString());
198ret->setInt(i);
199}
200
201void MutableParam::p_remgroup(ExtValue *args,ExtValue *ret)
202{
203removeGroup(args[0].getInt());
204}
205
206void MutableParam::notify(int id)
207{
208changed=id;
209onactivate.action(id);
210}
211
212int MutableParam::setInt(int i,paInt v)
213{
214int ret=SimpleAbstractParam::setInt(i,v);
215if (ret & PSET_CHANGED) notify(i);
216return ret;
217}
218
219int MutableParam::setDouble(int i,double v)
220{
221int ret=SimpleAbstractParam::setDouble(i,v);
222if (ret & PSET_CHANGED) notify(i);
223return ret;
224}
225
226int MutableParam::setString(int i,const SString &v)
227{
228int ret=SimpleAbstractParam::setString(i,v);
229if (ret & PSET_CHANGED) notify(i);
230return ret;
231}
232
233int MutableParam::setObject(int i,const ExtObject &v)
234{
235int ret=SimpleAbstractParam::setObject(i,v);
236if (ret & PSET_CHANGED) notify(i);
237return ret;
238}
239
240int MutableParam::setExtValue(int i,const ExtValue &v)
241{
242int ret=SimpleAbstractParam::setExtValue(i,v);
243if (ret & PSET_CHANGED) notify(i);
244return ret;
245}
246
247void MutableParam::call(int i,ExtValue* args,ExtValue *ret)
248{
249if (i<staticprops) return SimpleAbstractParam::call(i,args,ret);
250notify(i);
251}
252
253///////////////////
254
255void ParamSaver::clear()
256{
257for(int i=0;i<store.size();i+=2)
258        {
259        SString *n=(SString*)store(i);
260        ExtValue *v=(ExtValue*)store(i+1);
261        delete n;
262        delete v;
263        }       
264store.clear();
265}
266
267void ParamSaver::loadFrom(ParamInterface& p)
268{
269int N=p.getPropCount();
270for(int i=0;i<N;i++)
271        {
272        if (shouldLoad(p,i))
273                {
274                ExtValue v;
275                p.get(i,v);
276                store+=new SString(p.id(i));
277                store+=new ExtValue(v);
278                }
279        }
280}
281
282void ParamSaver::saveTo(MutableParam& p)
283{
284for(int i=0;i<store.size();i+=2)
285        {
286        SString *n=(SString*)store(i);
287        int prop=p.findId(n->c_str());
288        if (prop<0)
289                prop=p.addProperty(0,n->c_str(),"x",0,0,0,0,-1);
290        p.setExtValue(prop,*(ExtValue*)store(i+1));
291        }
292}
Note: See TracBrowser for help on using the repository browser.