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

Last change on this file since 824 was 824, checked in by Maciej Komosinski, 5 years ago

MutableParam? property definition can be changed

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