// This file is a part of the Framsticks GDK. // Copyright (C) 1999-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.framsticks.com/ for further information. #include "mutableparam.h" #include #define FIELDSTRUCT MutableParam ParamEntry MutableParam::pe_tab[]= { {"clear",0,PARAM_DONTSAVE+PARAM_USERHIDDEN,"remove all properties","p",PROCEDURE(p_clear),}, {"add",0,PARAM_DONTSAVE+PARAM_USERHIDDEN,"add property (id,type,name,help)","p",PROCEDURE(p_addprop),}, {"remove",0,PARAM_DONTSAVE+PARAM_USERHIDDEN,"remove property (index)","p",PROCEDURE(p_remprop),}, {"addGroup",0,PARAM_DONTSAVE+PARAM_USERHIDDEN,"add group (name)","p",PROCEDURE(p_addgroup),}, {"removeGroup",0,PARAM_DONTSAVE+PARAM_USERHIDDEN,"remove group (index)","p",PROCEDURE(p_remgroup),}, {"changedProperty",0,PARAM_DONTSAVE+PARAM_USERHIDDEN+PARAM_READONLY,"last changed property #","d",FIELD(changed),}, {"changedPropertyId",0,PARAM_DONTSAVE+PARAM_USERHIDDEN+PARAM_READONLY,"last changed property id","s",GETONLY(changedname),}, }; #undef FIELDSTRUCT MutableParam::MutableParam(const char*n,const char*g,int gr0) :SimpleAbstractParam(this,n),persistgroup0(gr0),grprefix(g) { if (persistgroup0) addGroup(grprefix,1); } int MutableParam::findGroup(const SString name,int ignoreprefix) { int skipprefix=grprefix.len()?grprefix.len()+2:0; for (int i=0;i=MutableParam::getGroupCount())) return; ParamEntry *e; for (int i=MutableParam::getPropCount()-1;i>=staticprops;i--) { e=entry(i); if (g==e->group) removeProperty(i); } SString *s=(SString *)groups(g); if (s) delete s; groups-=g; ongroupdelete.action(g); } int MutableParam::grmember(int g,int a) { if (g==0) { if (getGroupCount()<2) return (agroup) if (!a--) return i; return -9999; } int MutableParam::addProperty(ParamEntry *pe,int position) { DB(printf("MutableParam::add(%s)\n",pe->id)); if (position<0) position=entries.size()+staticprops; entries.insert(position-staticprops,pe); if (pe->offset) pe->flags &= ~MUTPARAM_ALLOCDATA; else { pe->flags |= MUTPARAM_ALLOCDATA; void *d=0; switch(pe->type[0]) { case 'd': d=new int(); *((int*)d)=0; break; case 'f': d=new double(); *((double*)d)=0; break; case 's': d=new SString(); break; case 'x': d=new ExtValue(); break; case 'o': d=new ExtObject(); break; } pe->offset=(int)d; } onadd.action(position); return position; } ParamEntry * MutableParam::removeProperty(ParamEntry *pe) { int index=entries.find(pe); if (index>=0) return removeProperty(index); else return pe; } ParamEntry * MutableParam::removeProperty(int i) { ParamEntry *pe=(ParamEntry *)entries(i-staticprops); DB(printf("MutableParam::remove(%d)\n",i)); void *d=(void*)pe->offset; if (d && (pe->flags & MUTPARAM_ALLOCDATA)) switch(pe->type[0]) { case 'd': delete (int*)d; break; case 'f': delete (double*)d; break; case 's': delete (SString*)d; break; case 'x': delete (ExtValue*)d; break; case 'o': delete (ExtObject*)d; break; } entries-=i-staticprops; if (pe->flags & MUTPARAM_ALLOCENTRY) { if (pe->name) free((void*)pe->name); if (pe->id) free((void*)pe->id); if (pe->help) free((void*)pe->help); if (pe->type) free((void*)pe->type); delete pe; } ondelete.action(i); return pe; } void MutableParam::clear(int everything) { DB(printf("MutableParam::clear\n")); for (int i=entries.size()-1;i>=0;i--) removeProperty(i+staticprops); int lastgroup=(everything || (persistgroup0==0))?0:1; for (int i=groups.size()-1;i>=lastgroup;i--) removeGroup(i); } void MutableParam::p_clear(ExtValue *args,ExtValue *ret) { clear(); } int MutableParam::addProperty(void* data,const char* id,const char* type,const char* name,const char* help,int flags,int group,int position) { if ((!id)&&(!type)) return -1; ParamEntry *pe=new ParamEntry(); pe->fun1=0; pe->fun2=0; pe->group=(short)group; pe->flags=(short)(flags | MUTPARAM_ALLOCENTRY); pe->offset=(long)data; pe->id=strdup(id); pe->type=strdup(type); pe->name=name?strdup(name):0; pe->help=help?strdup(help):0; return addProperty(pe,position); } void MutableParam::p_addprop(ExtValue *args,ExtValue *ret) { int i=addProperty(0,args[2].getString(),args[1].getString(),args[0].getString()); ret->setInt(i); } void MutableParam::p_remprop(ExtValue *args,ExtValue *ret) { removeProperty(args[0].getInt()); } void MutableParam::p_addgroup(ExtValue *args,ExtValue *ret) { int i=addGroup(args[0].getString()); ret->setInt(i); } void MutableParam::p_remgroup(ExtValue *args,ExtValue *ret) { removeGroup(args[0].getInt()); } void MutableParam::notify(int id) { changed=id; onactivate.action(id); } int MutableParam::setInt(int i,long v) { int ret=SimpleAbstractParam::setInt(i,v); if (ret & PSET_CHANGED) notify(i); return ret; } int MutableParam::setDouble(int i,double v) { int ret=SimpleAbstractParam::setDouble(i,v); if (ret & PSET_CHANGED) notify(i); return ret; } int MutableParam::setString(int i,const SString &v) { int ret=SimpleAbstractParam::setString(i,v); if (ret & PSET_CHANGED) notify(i); return ret; } int MutableParam::setObject(int i,const ExtObject &v) { int ret=SimpleAbstractParam::setObject(i,v); if (ret & PSET_CHANGED) notify(i); return ret; } int MutableParam::setExtValue(int i,const ExtValue &v) { int ret=SimpleAbstractParam::setExtValue(i,v); if (ret & PSET_CHANGED) notify(i); return ret; } void MutableParam::call(int i,ExtValue* args,ExtValue *ret) { if (i