source: cpp/frams/model/modelparts.cpp @ 196

Last change on this file since 196 was 121, checked in by sz, 11 years ago

updated file headers and makefiles

  • Property svn:eol-style set to native
File size: 17.6 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <stdlib.h>
6#include <math.h>
7#include <stdio.h>
8#include <string.h>
9#include <ctype.h>
10#include <time.h>
11#include <errno.h>
12
13///////////////////////////////     MODELPARTS.CPP     ///////////////
14
15#include "modelparts.h"
16#include "model.h"
17
18#include <common/nonstd.h>
19#include <frams/param/param.h>
20#include <frams/neuro/neurolibrary.h>
21#include <frams/util/multirange.h>
22#include <frams/util/extvalue.h>
23#include <frams/param/paramobj.h>
24
25#include F0_DEFASSIGN_FILE
26
27#ifndef GDK_WITHOUT_FRAMS
28#include <frams/neuro/neuroclsobject.h>
29#endif
30
31template<>
32char ModelUserTags::reg[5]={0};
33
34/////////////////////////
35
36PartBase::~PartBase()
37{if (mapped) delete mapped;}
38
39void PartBase::notifyMappingChange()
40{
41if (owner) owner->partmappingchanged=1;
42}
43
44void PartBase::setMapping(const IRange &r)
45{
46if (mapped) (*mapped)=r;
47else mapped=new MultiRange(r);
48notifyMappingChange();
49}
50
51void PartBase::clearMapping()
52{
53if (mapped) {delete mapped; mapped=0;}
54}
55
56void PartBase::addMapping(const IRange &r)
57{
58if (mapped) mapped->add(r);
59else mapped=new MultiRange(r);
60notifyMappingChange();
61}
62
63void PartBase::setMapping(const MultiRange &mr)
64{
65if (mapped) (*mapped)=mr;
66else mapped=new MultiRange(mr);
67notifyMappingChange();
68}
69
70void PartBase::addMapping(const MultiRange &mr)
71{
72if (mapped) mapped->add(mr);
73else mapped=new MultiRange(mr);
74notifyMappingChange();
75}
76
77void PartBase::setInfo(const SString& name,const SString& value)
78{
79strSetField(info,name,value);
80}
81
82void PartBase::setInfo(const SString& name,int value)
83{
84setInfo(name,SString::valueOf(value));
85}
86
87void PartBase::setInfo(const SString& name,double value)
88{
89setInfo(name,SString::valueOf(value));
90}
91
92SString PartBase::getInfo(const SString& name)
93{
94return strGetField(info,name);
95}
96
97/////////////////////////
98
99NeuroClass::NeuroClass(ParamEntry *_props,SString _description,
100                       int _prefinputs,int _prefoutput,int _preflocation,
101                       int *_vectordata,bool own_vd,int vhints)
102        :ownedvectordata(own_vd),
103         name(_props->name),longname(_props->id),description(_description),
104         props(_props),ownedprops(false),
105         prefinputs(_prefinputs),
106         prefoutput(_prefoutput),
107         preflocation(_preflocation),
108         vectordata(_vectordata),
109         visualhints(vhints),impl_count(0),/*impl(0),*/active(1),genactive(0)
110{}
111
112NeuroClass::~NeuroClass()
113{
114setSymbolGlyph(0,0);
115if (props && ownedprops)
116        ParamObject::freeParamTab(props);
117}
118
119NeuroClass::NeuroClass()
120        :ownedvectordata(0),
121         name("Invalid"),
122         props(empty_paramtab),ownedprops(false),
123         prefinputs(0), prefoutput(0),
124         preflocation(0), vectordata(0),
125         visualhints(0),impl_count(0), /*impl(0),*/ active(1), genactive(0)
126{}
127
128SString NeuroClass::getSummary()
129{
130SString t;
131t=getDescription();
132if (t.len()) t+="\n\n";
133t+="Characteristics:\n";
134if(getPreferredInputs())
135        {
136        if (getPreferredInputs()<0) t+="   supports any number of inputs\n";
137        else if (getPreferredInputs()==1) t+="   uses single input\n";
138        else t+=SString::sprintf("   uses %d inputs\n",getPreferredInputs());
139        }
140else t+="   does not use inputs\n";
141if(getPreferredOutput())
142        t+="   provides output value\n";
143else
144        t+="   does not provide output value\n";
145switch(getPreferredLocation())
146        {
147        case 0: t+="   does not require location in body\n"; break;
148        case 1: t+="   should be located on a Part\n"; break;
149        case 2: t+="   should be located on a Joint\n"; break;
150        }
151Param p=getProperties();
152if (p.getPropCount())
153        {
154        if (t.len()) t+="\n\n";
155        t+="Properties:\n";
156        const char *h;
157        int i;
158        for(i=0;i<p.getPropCount();i++)
159                {
160                if (i) t+="\n";
161                t+="   "; t+=p.name(i); t+=" ("; t+=p.id(i); t+=")";
162                switch(*p.type(i))
163                        {
164                        case 'd': t+=" integer";
165                        {long a,b,c; if (p.getMinMax(i,a,b,c)>=2) t+=SString::sprintf(" %d..%d",a,b);}
166                                break;
167                        case 'f': t+=" float";
168                        {double a,b,c; if (p.getMinMax(i,a,b,c)>=2) t+=SString::sprintf(" %g..%g",a,b);}
169                                break;
170                        case 's': t+=" string"; break;
171                        case 'x': t+=" anything"; break;
172                        }
173                if (h=p.help(i)) if (*h) {t+=" - "; t+=h;}
174                }
175        }
176return t;
177}
178
179/////////////////////////
180
181/////////////////////////////////////
182
183Neuro::Neuro(double _state,double _inertia,double _force,double _sigmo)
184        :PartBase(getDefaultStyle()),state(_state)
185#ifdef MODEL_V1_COMPATIBLE
186,inertia(_inertia),force(_force),sigmo(_sigmo)
187#endif
188{
189#ifdef MODEL_V1_COMPATIBLE
190olditems=0;
191#endif
192flags=0;
193myclass=0;
194knownclass=1;
195part_refno=-1; joint_refno=-1;
196}
197
198Neuro::Neuro(void):PartBase(getDefaultStyle())
199{
200defassign();
201state=0.0;
202myclass=NULL;
203myclassname="N";//default d="N" but f0.def is unable to set this (d is GETSET, not a regular FIELD)
204knownclass=0;
205refno=0;
206pos=Pt3D_0; rot=Pt3D_0;
207parent=0; part=0; joint=0;
208parentcount=0;
209#ifdef MODEL_V1_COMPATIBLE
210olditems=0;
211#endif
212flags=0;
213part_refno=-1; joint_refno=-1;
214}
215
216
217Neuro::~Neuro()
218{
219#ifdef MODEL_V1_COMPATIBLE
220if (olditems) delete olditems;
221#endif
222int i;
223for(i=0;i<inputs.size();i++)
224        {
225        NInput &ni=inputs(i);
226        if (ni.info) delete ni.info;
227        }
228}
229
230SString** Neuro::inputInfo(int i)
231{
232if (i>=getInputCount()) return 0;
233return &inputs(i).info;
234}
235
236void Neuro::setInputInfo(int i,const SString& name,const SString &value)
237{
238SString **s=inputInfo(i);
239if (!s) return;
240if (!*s) *s=new SString();
241strSetField(**s,name,value);
242}
243
244void Neuro::setInputInfo(int i,const SString& name,int value)
245{
246setInputInfo(i,name,SString::valueOf(value));
247}
248
249void Neuro::setInputInfo(int i,const SString& name,double value)
250{
251setInputInfo(i,name,SString::valueOf(value));
252}
253
254SString Neuro::getInputInfo(int i)
255{
256SString **s=inputInfo(i);
257if (!s) return SString();
258if (!*s) return SString();
259return **s;
260}
261
262SString Neuro::getInputInfo(int i,const SString& name)
263{
264SString **s=inputInfo(i);
265if (!s) return SString();
266if (!*s) return SString();
267return strGetField(**s,name);
268}
269
270void Neuro::operator=(const Neuro& src)
271{
272refno=src.refno;
273#ifdef MODEL_V1_COMPATIBLE
274neuro_refno=-1;
275conn_refno=-1;
276force=src.force;
277sigmo=src.sigmo;
278inertia=src.inertia;
279weight=src.weight;
280olditems=0;
281#endif
282state=src.state;
283part_refno=-1;
284joint_refno=-1;
285pos=src.pos; rot=src.rot;
286parent=0; part=0; joint=0;
287parentcount=0;
288flags=0;
289myclass=src.myclass;
290knownclass=src.knownclass;
291myclassname=src.myclassname;
292myclassparams=src.myclassparams;
293}
294
295void Neuro::attachToPart(int i)
296{attachToPart((i>=0)?owner->getPart(i):0);}
297
298void Neuro::attachToJoint(int i)
299{attachToJoint((i>=0)?owner->getJoint(i):0);}
300
301int Neuro::getClassCount()
302{return NeuroLibrary::staticlibrary.getClassCount();}
303
304NeuroClass* Neuro::getClass(int classindex)
305{return NeuroLibrary::staticlibrary.getClass(classindex);}
306
307NeuroClass* Neuro::getClass(const SString& classname)
308{return NeuroLibrary::staticlibrary.findClass(classname);}
309
310int Neuro::getClassIndex(const NeuroClass*nc)
311{return NeuroLibrary::staticlibrary.classes.find((void*)nc);}
312
313NeuroClass* Neuro::getClass()
314{
315checkClass();
316return myclass;
317}
318
319void Neuro::setClass(NeuroClass* cl)
320{
321myclass=cl;
322myclassname=cl->getName();
323knownclass=1;
324}
325
326SString Neuro::getClassName(int classindex)
327{
328NeuroClass *cl=NeuroLibrary::staticlibrary.getClass(classindex);
329return cl? cl->getName() : SString();
330}
331
332void Neuro::setDetails(const SString& details)
333{
334int colon=details.indexOf(':');
335if (colon>=0) {myclassname=details.substr(0,colon); myclassparams=details.substr(colon+1);}
336else {myclassname=details; myclassparams=0;}
337knownclass=0;
338}
339
340SString Neuro::getDetails()
341{
342SString ret=getClassName();
343if (myclassparams.len()) {if (!ret.len()) ret="N"; ret+=":"; ret+=myclassparams;}
344return ret;
345}
346
347void Neuro::checkClass()
348{
349if (knownclass) return;
350myclass=getClass(myclassname);
351knownclass=1;
352}
353
354SyntParam Neuro::classProperties(bool handle_defaults_when_saving)
355{
356NeuroClass *cl=getClass();
357ParamEntry *pe = cl ? cl->getParamTab() : emptyParamTab;
358return SyntParam(pe,&myclassparams,handle_defaults_when_saving);
359}
360
361SString Neuro::getClassName()
362{
363return myclassname;
364}
365
366void Neuro::setClassName(const SString& clazz)
367{
368myclassname=clazz;
369knownclass=0;
370}
371
372int Neuro::addInput(Neuro* child,double weight,const SString *info)
373{
374inputs+=NInput(child,weight,(info&&(info->len()))?new SString(*info):0);
375child->parentcount++;
376if (child->parentcount==1) {child->parent=this;}
377return inputs.size()-1;
378}
379
380int Neuro::findInput(Neuro* child) const
381{
382for(int i=0;i<inputs.size();i++)
383        if (inputs(i).n==child) return i;
384return -1;
385}
386
387Neuro* Neuro::getInput(int i,double &weight) const
388{
389if (i>=getInputCount()) return 0;
390NInput &inp=inputs(i);
391weight=inp.weight;
392return inp.n;
393}
394
395double Neuro::getInputWeight(int i) const
396{
397return inputs(i).weight;
398}
399
400void Neuro::setInputWeight(int i,double w)
401{
402inputs(i).weight=w;
403}
404
405void Neuro::setInput(int i,Neuro* n)
406{
407NInput &inp=inputs(i);
408inp.n=n;
409}
410
411void Neuro::setInput(int i,Neuro* n,double w)
412{
413NInput &inp=inputs(i);
414inp.n=n;
415inp.weight=w;
416}
417
418void Neuro::removeInput(int refno)
419{
420Neuro *child=getInput(refno);
421child->parentcount--;
422if (child->parent==this) child->parent=0;
423SString *s=inputs(refno).info;
424if (s) delete s;
425inputs.remove(refno);
426}
427
428int Neuro::removeInput(Neuro* child)
429{
430int i=findInput(child);
431if (i>=0) removeInput(i);
432return i;
433}
434
435int Neuro::getOutputsCount() const
436{
437   int c=0;
438   for(int i=0;i<owner->getNeuroCount();i++)
439     for(int j=0;j<owner->getNeuro(i)->getInputCount();j++) c+=owner->getNeuro(i)->getInput(j)==this;
440   return c;
441}
442
443int Neuro::isOldEffector()
444{
445static SString bend("|"),rot("@");
446return ((getClassName()==bend)||(getClassName()==rot));
447}
448
449int Neuro::isOldReceptor()
450{
451static SString g("G"),t("T"),s("S");
452return ((getClassName()==g)||(getClassName()==t)||(getClassName()==s));
453}
454
455int Neuro::isOldNeuron()
456{
457static SString n("N");
458return (getClassName()==n);
459}
460
461int Neuro::isNNConnection()
462{
463static SString conn("-");
464return (getClassName()==conn);
465}
466
467int Neuro::findInputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
468{
469Neuro *nu;
470SString cn(classname);
471int n0=result.size();
472for(int i=0;nu=getInput(i);i++)
473        {
474        if (part)
475                if (nu->part != part) continue;
476        if (joint)
477                if (nu->joint != joint) continue;
478        if (classname)
479                if (nu->getClassName() != cn) continue;
480        result+=(void*)nu;
481        }
482return result.size()-n0;
483}
484
485int Neuro::findOutputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
486{ // not very efficient...
487Neuro *nu,*inp;
488SString cn(classname);
489SList found;
490int n0=result.size();
491for(int i=0;nu=getModel().getNeuro(i);i++)
492        {
493        if (part)
494                if (nu->part != part) continue;
495        if (joint)
496                if (nu->joint != joint) continue;
497        if (classname)
498                if (inp->getClassName() != cn) continue;
499        for (int j=0;inp=nu->getInput(j);j++)
500                if (inp==this)
501                        {
502                        result+=(void*)nu;
503                        break;
504                        }
505        }
506return result.size()-n0;
507}
508
509void Neuro::get_inputCount(PARAMGETARGS)
510{ret->setInt(inputs.size());}
511
512void Neuro::p_getInputNeuroDef(ExtValue *args,ExtValue *ret)
513{
514int i=args->getInt();
515if ((i<0)||(i>=inputs.size()))
516        ret->setEmpty();
517else
518        ret->setObject(ExtObject(&Neuro::getStaticParam(),inputs(i).n));
519}
520
521void Neuro::p_getInputWeight(ExtValue *args,ExtValue *ret)
522{
523int i=args->getInt();
524if ((i<0)||(i>=inputs.size()))
525        ret->setEmpty();
526else
527        ret->setDouble(inputs(i).weight);
528}
529
530void Neuro::p_getInputNeuroIndex(ExtValue *args,ExtValue *ret)
531{
532int i=args->getInt();
533if ((i<0)||(i>=inputs.size()))
534        ret->setInt(-1);
535else
536        ret->setInt(inputs(i).n->refno);
537}
538
539void Neuro::get_classObject(PARAMGETARGS)
540{
541#ifndef GDK_WITHOUT_FRAMS
542NeuroClassExt::makeStaticObject(ret,getClass());
543#endif
544}
545
546/////// old items
547#ifdef MODEL_V1_COMPATIBLE
548void OldItems::buildlist()
549{ // guaranteed to work only for old NN layouts
550 // (neurons,neuro connections, old receptors and effectors)
551if (listok) return;
552 // inputs can contain both neuroitem connections (details="") and direct neuron references (details="N")
553 // in OldItems we create neuroitems freom direct references
554for(int i=0;i<neuro.getInputCount();i++)
555        {
556        float w;
557        Neuro *n=neuro.getInput(i,w);
558        if (n->isOldNeuron())
559                {
560                Neuro *ni=new Neuro();
561                ni->setClassName("-");
562                ni->weight=w;
563                ni->neuro_refno=neuro.refno;
564                ni->conn_refno=n->refno;
565                items+=ni;
566                syntitems+=ni;
567                }
568        else
569                {
570                items+=n;
571                n->weight=w;
572                }
573        }
574SList outputs;
575neuro.findOutputs(outputs);
576FOREACH(Neuro*,n,outputs)
577        {
578        if (n->isNNConnection() || n->isOldNeuron())
579                outputs-=n;
580        }
581items+=outputs;
582listok=1;
583}
584
585void OldItems::freelist()
586{
587FOREACH(Neuro*,n,syntitems)
588        delete n;
589syntitems.clear();
590items.clear();
591listok=0;
592}
593
594int OldItems::getItemCount()
595{
596buildlist();
597return items.size();
598}
599
600NeuroItem *OldItems::getNeuroItem(int i)
601{
602buildlist();
603return (NeuroItem*)items(i);
604}
605
606NeuroItem *OldItems::addNewNeuroItem()
607{
608Neuro *nu=neuro.getModel().addNewNeuro();
609nu->setClassName("-");
610if (listok) items+=nu;
611neuro.addInput(nu);
612return (NeuroItem*)nu;
613}
614
615int OldItems::findNeuroItem(NeuroItem *ni)
616{
617buildlist();
618return items.find((void*)ni);
619}
620#endif
621
622///////////////////////////////////////
623
624SString Part::getDefaultStyle()
625{return SString("part");}
626SString Joint::getDefaultStyle()
627{return SString("joint");}
628/*
629const SString& Neuro::getDefaultStyle()
630{static SString s("neuro"); return s;}
631const SString& NeuroItem::getDefaultStyle()
632{static SString s("neuroitem"); return s;}
633*/
634SString Neuro::getDefaultStyle()
635{return SString("neuro");}
636
637Part::Part(enum Shape s):PartBase(getDefaultStyle())
638{
639o=Orient_1;
640p=Pt3D_0;
641rot=Pt3D_0;
642flags=0;
643defassign();
644shape=s;
645}
646
647void Part::operator=(const Part& src)
648{
649p=src.p; o=src.o;
650flags=src.flags;
651mass=src.mass; density=src.density;
652friction=src.friction;
653ingest=src.ingest;
654assim=src.assim;
655size=src.size;
656rot=src.rot;
657refno=src.refno;
658vcolor=src.vcolor;
659vsize=src.vsize;
660shape=src.shape;
661}
662
663void Part::setOrient(const Orient &_o)
664{
665o=_o;
666rot.getAngles(o.x,o.z);
667}
668
669void Part::setRot(const Pt3D &r)
670{
671rot=r;
672o=Orient_1;
673o.rotate(rot);
674}
675
676void Part::setPositionAndRotationFromAxis(const Pt3D &p1,const Pt3D &p2)
677{
678Pt3D x=p2-p1;
679Pt3D dir(x.y,x.z,x.x);
680p=p1+x*0.5;
681rot.getAngles(x,dir);
682}
683
684Param& Part::getStaticParam()
685{
686static Param p(f0_part_paramtab,0,"Part");
687return p;
688}
689
690
691///////////////////////////
692
693Joint::Joint():PartBase(getDefaultStyle())
694{
695rot=Pt3D_0;
696defassign();
697d.x=JOINT_DELTA_MARKER;
698d.y=JOINT_DELTA_MARKER;
699d.z=JOINT_DELTA_MARKER;
700part1=0; part2=0;
701flags=0;
702usedelta=0;
703}
704
705void Joint::operator=(const Joint& src)
706{
707rot=src.rot;
708d=src.d;
709stamina=src.stamina;
710stif=src.stif; rotstif=src.rotstif;
711part1=0; part2=0;
712flags=src.flags;
713usedelta=src.usedelta;
714refno=src.refno;
715}
716
717void Joint::attachToParts(Part* p1,Part* p2)
718{
719part1=p1;
720part2=p2;
721if (p1 && p2)
722        {
723        o=rot;
724        if (usedelta)
725                {
726                p1->o.transform(p2->o,o);
727//              p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
728                p2->p=p2->o.transform(d)+p1->p;
729                }
730        }
731}
732
733void Joint::attachToParts(int p1,int p2)
734{
735attachToParts((p1>=0)?owner->getPart(p1):0,(p2>=0)?owner->getPart(p2):0);
736}
737
738void Joint::resetDelta()
739{
740d=Pt3D(JOINT_DELTA_MARKER,JOINT_DELTA_MARKER,JOINT_DELTA_MARKER);
741}
742
743void Joint::resetDeltaMarkers()
744{
745if (d.x==JOINT_DELTA_MARKER) d.x=0;
746if (d.y==JOINT_DELTA_MARKER) d.y=0;
747if (d.z==JOINT_DELTA_MARKER) d.z=0;
748}
749
750void Joint::useDelta(bool use)
751{
752usedelta=use;
753}
754
755bool Joint::isDelta()
756{
757return usedelta;
758}
759
760Param& Joint::getStaticParam()
761{
762static Param p(f0_joint_paramtab,0,"Joint");
763return p;
764}
765
766
767/////////////////////////////////////////////////////////////////
768/////////////////////////////////////////////////////////////////
769
770#include F0_CLASSES_FILE
771
772#ifdef MODEL_V1_COMPATIBLE
773
774#define FIELDSTRUCT Neuro
775ParamEntry f0_old_neuro_tab[]=
776{
777{"Connections",2,6,"n",},
778{"Other properties",},
779{"p",0,0,"part ref#","d",FIELD(part_refno),},
780{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
781{"s",1,0,"state","f",FIELD(state),},
782{"in",1,0,"Inertia","f",FIELD(inertia),},
783{"fo",1,0,"Force","f",FIELD(force),},
784{"si",1,0,"Sigmoid","f",FIELD(sigmo),},
785{0,0,0,},
786};
787#undef FIELDSTRUCT
788
789#define FIELDSTRUCT NeuroItem
790ParamEntry f0_neuroitem_paramtab[]=
791{
792{"Connections",3,12,"ni",},
793{"Geometry",},
794{"Other",},
795{"n",0,0,"neuron ref#","d",FIELD(neuro_refno),},
796{"c",2,0,"connection ref#","d",FIELD(conn_refno),},
797{"w",2,0,"connection weight","f",FIELD(weight),},
798{"p",0,0,"part ref#","d",FIELD(part_refno),},
799{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
800{"px",1,0,"position.x","f",FIELD(pos.x),},
801{"py",1,0,"position.y","f",FIELD(pos.y),},
802{"pz",1,0,"position.z","f",FIELD(pos.z),},
803{"rx",1,0,"rotation.x","f",FIELD(rot.x),},
804{"ry",1,0,"rotation.y","f",FIELD(rot.y),},
805{"rz",1,0,"rotation.z","f",FIELD(rot.z),},
806{"d",2,0,"item details","s",GETSET(details),},
807{0,0,0,},
808};
809#undef FIELDSTRUCT
810#endif
811
812////////////////////////////////////////
813
814ParamEntry Neuro::emptyParamTab[]=
815{
816{"Undefined Neuro",1,0,"?",},
817{0,0,0,},
818};
819
820Param Part::extraProperties()
821{
822return Param(f0_part_xtra_paramtab,this);
823}
824
825Param Joint::extraProperties()
826{
827return Param(f0_joint_xtra_paramtab,this);
828}
829
830Param Neuro::extraProperties()
831{
832return Param(f0_neuro_xtra_paramtab,this);
833}
834
835Param Part::properties()
836{
837return Param(f0_part_paramtab,this);
838}
839
840Param Joint::properties()
841{
842return Param(usedelta?f0_joint_paramtab:f0_nodeltajoint_paramtab,this);
843}
844
845Param Neuro::properties()
846{
847return Param(f0_neuro_paramtab,this);
848}
849
850class NeuroExtParamTab: public ParamTab
851{
852  public:
853NeuroExtParamTab():ParamTab(f0_neuro_paramtab)
854        {
855#define FIELDSTRUCT NeuroExt
856        ParamEntry entry={"class",2,0,"neuro class","s",GETSET(neuroclass)};
857#undef FIELDSTRUCT
858        add(&entry);
859
860#define FIELDSTRUCT Neuro
861        ParamEntry entry2={"state",2,0,"state","f",FIELD(state)};
862#undef FIELDSTRUCT
863        add(&entry2);
864        }
865};
866
867Param& Neuro::getStaticParam()
868{
869static Param p(f0_neuro_paramtab,0,"NeuroDef");
870return p;
871}
872
873////////////////////////
874
875NeuroConn::NeuroConn()
876{
877defassign();
878}
879
880//////////////////////////////////////
881
882ParamEntry *NeuroExt::getParamTab()
883{
884static NeuroExtParamTab tab;
885return tab.getParamTab();
886}
887
888void NeuroExt::get_neuroclass(PARAMGETARGS)
889{ret->setString(getClassName());}
890
891int NeuroExt::set_neuroclass(PARAMSETARGS)
892{setClassName(arg->getString());return PSET_CHANGED;}
893
894
Note: See TracBrowser for help on using the repository browser.