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

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

Code formatting

  • Property svn:eol-style set to native
File size: 7.3 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{
24        if (persistgroup0)
25                addGroup(grprefix, 1);
26}
27
28int MutableParam::findGroup(const SString name, int ignoreprefix)
29{
30        int skipprefix = grprefix.len() ? grprefix.len() + 2 : 0;
31        for (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        }
43        return -1;
44}
45
46int MutableParam::addGroup(const SString& gname, int noprefix)
47{
48        SString tmp;
49        if (noprefix)
50                tmp = gname;
51        else
52        {
53                tmp = grprefix;
54                if (tmp.len()) tmp += ": ";
55                tmp += gname;
56        }
57        groups += new SString(tmp);
58        int position = groups.size() - 1;
59        ongroupadd.action(position);
60        return position;
61}
62
63void MutableParam::removeGroup(int g)
64{
65        if ((g < 0) || (g >= MutableParam::getGroupCount())) return;
66        ParamEntry *e;
67        for (int i = MutableParam::getPropCount() - 1; i >= staticprops; i--)
68        {
69                e = entry(i);
70                if (g == e->group)
71                        removeProperty(i);
72        }
73        SString *s = (SString *)groups(g);
74        if (s) delete s;
75        groups -= g;
76        ongroupdelete.action(g);
77}
78
79int MutableParam::grmember(int g, int a)
80{
81        if (g == 0)
82        {
83                if (getGroupCount() < 2)
84                        return (a < getPropCount()) ? a : -9999;
85                if (a < staticprops) return a;
86                a -= staticprops;
87        }
88        ParamEntry *e;
89        for (int i = staticprops; e = entry(i); i++)
90                if (g == e->group)
91                        if (!a--) return i;
92        return -9999;
93}
94
95int MutableParam::addProperty(ParamEntry *pe, int position)
96{
97        DB(printf("MutableParam::add(%s)\n", pe->id));
98        if (position < 0)
99                position = entries.size() + staticprops;
100        entries.insert(position - staticprops, pe);
101
102        if (pe->offset)
103                pe->flags &= ~MUTPARAM_ALLOCDATA;
104        else
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        }
118        onadd.action(position);
119        return 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{
130        ParamEntry *pe = (ParamEntry *)entries(i - staticprops);
131        DB(printf("MutableParam::remove(%d)\n", i));
132        void *d = (void*)pe->offset;
133        if (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        }
142        entries -= i - staticprops;
143        if (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        }
151        ondelete.action(i);
152        return pe;
153}
154
155void MutableParam::clear(int everything)
156{
157        DB(printf("MutableParam::clear\n"));
158        for (int i = entries.size() - 1; i >= 0; i--)
159                removeProperty(i + staticprops);
160        int lastgroup = (everything || (persistgroup0 == 0)) ? 0 : 1;
161        for (int i = groups.size() - 1; i >= lastgroup; i--)
162                removeGroup(i);
163}
164
165void MutableParam::p_clear(ExtValue *args, ExtValue *ret)
166{
167        clear();
168}
169
170int MutableParam::addProperty(void* data, const char* id, const char* type, const char* name, const char* help, int flags, int group, int position)
171{
172        if ((!id) && (!type)) return -1;
173        if (!isValidTypeDescription(type)) return -1;
174        ParamEntry *pe = new ParamEntry();
175        pe->fun1 = 0; pe->fun2 = 0;
176        pe->group = (paInt)group;
177        pe->flags = (paInt)(flags | MUTPARAM_ALLOCENTRY);
178        pe->offset = (intptr_t)data;
179        pe->id = strdup(id);
180        pe->type = strdup(type);
181        pe->name = name ? strdup(name) : 0;
182        pe->help = help ? strdup(help) : 0;
183        return addProperty(pe, position);
184}
185
186void MutableParam::p_addprop(ExtValue *args, ExtValue *ret)
187{
188        int i = addProperty(0, args[2].getString().c_str(), args[1].getString().c_str(), args[0].getString().c_str());
189        ret->setInt(i);
190}
191
192void MutableParam::p_remprop(ExtValue *args, ExtValue *ret)
193{
194        removeProperty(args[0].getInt());
195}
196
197void MutableParam::p_addgroup(ExtValue *args, ExtValue *ret)
198{
199        int i = addGroup(args[0].getString());
200        ret->setInt(i);
201}
202
203void MutableParam::p_remgroup(ExtValue *args, ExtValue *ret)
204{
205        removeGroup(args[0].getInt());
206}
207
208void MutableParam::notify(int id)
209{
210        changed = id;
211        onactivate.action(id);
212}
213
214int MutableParam::setInt(int i, paInt v)
215{
216        int ret = SimpleAbstractParam::setInt(i, v);
217        if (ret & PSET_CHANGED) notify(i);
218        return ret;
219}
220
221int MutableParam::setDouble(int i, double v)
222{
223        int ret = SimpleAbstractParam::setDouble(i, v);
224        if (ret & PSET_CHANGED) notify(i);
225        return ret;
226}
227
228int MutableParam::setString(int i, const SString &v)
229{
230        int ret = SimpleAbstractParam::setString(i, v);
231        if (ret & PSET_CHANGED) notify(i);
232        return ret;
233}
234
235int MutableParam::setObject(int i, const ExtObject &v)
236{
237        int ret = SimpleAbstractParam::setObject(i, v);
238        if (ret & PSET_CHANGED) notify(i);
239        return ret;
240}
241
242int MutableParam::setExtValue(int i, const ExtValue &v)
243{
244        int ret = SimpleAbstractParam::setExtValue(i, v);
245        if (ret & PSET_CHANGED) notify(i);
246        return ret;
247}
248
249void MutableParam::call(int i, ExtValue* args, ExtValue *ret)
250{
251        if (i < staticprops) return SimpleAbstractParam::call(i, args, ret);
252        notify(i);
253}
254
255///////////////////
256
257void ParamSaver::clear()
258{
259        for (int i = 0; i < store.size(); i += 2)
260        {
261                SString *n = (SString*)store(i);
262                ExtValue *v = (ExtValue*)store(i + 1);
263                delete n;
264                delete v;
265        }
266        store.clear();
267}
268
269void ParamSaver::loadFrom(ParamInterface& p)
270{
271        int N = p.getPropCount();
272        for (int i = 0; i < N; i++)
273        {
274                if (shouldLoad(p, i))
275                {
276                        ExtValue v;
277                        p.get(i, v);
278                        store += new SString(p.id(i));
279                        store += new ExtValue(v);
280                }
281        }
282}
283
284void ParamSaver::saveTo(MutableParam& p)
285{
286        for (int i = 0; i < store.size(); i += 2)
287        {
288                SString *n = (SString*)store(i);
289                int prop = p.findId(n->c_str());
290                if (prop < 0)
291                        prop = p.addProperty(0, n->c_str(), "x", 0, 0, 0, 0, -1);
292                p.setExtValue(prop, *(ExtValue*)store(i + 1));
293        }
294}
Note: See TracBrowser for help on using the repository browser.