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

Last change on this file since 548 was 528, checked in by Maciej Komosinski, 8 years ago
  • Part.m removed
  • Part.h becomes XPROP
  • validate more part and joint properties in Model.internalcheck()
  • Property svn:eol-style set to native
File size: 17.7 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 <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 SDK_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                        {paInt 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 SDK_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;
645mass=1;
646}
647
648void Part::operator=(const Part& src)
649{
650p=src.p; o=src.o;
651flags=src.flags;
652mass=src.mass; density=src.density;
653friction=src.friction;
654ingest=src.ingest;
655assim=src.assim;
656size=src.size;
657rot=src.rot;
658refno=src.refno;
659vcolor=src.vcolor;
660vsize=src.vsize;
661vis_style=src.vis_style;
662shape=src.shape;
663scale=src.scale;
664hollow=src.hollow;
665}
666
667void Part::setOrient(const Orient &_o)
668{
669o=_o;
670rot.getAngles(o.x,o.z);
671}
672
673void Part::setRot(const Pt3D &r)
674{
675rot=r;
676o=Orient_1;
677o.rotate(rot);
678}
679
680void Part::setPositionAndRotationFromAxis(const Pt3D &p1,const Pt3D &p2)
681{
682Pt3D x=p2-p1;
683Pt3D dir(x.y,x.z,x.x);
684p=p1+x*0.5;
685rot.getAngles(x,dir);
686}
687
688Param& Part::getStaticParam()
689{
690static Param p(f0_part_paramtab,0,"Part");
691return p;
692}
693
694
695///////////////////////////
696
697Joint::Joint():PartBase(getDefaultStyle())
698{
699rot=Pt3D_0;
700defassign();
701d.x=JOINT_DELTA_MARKER;
702d.y=JOINT_DELTA_MARKER;
703d.z=JOINT_DELTA_MARKER;
704part1=0; part2=0;
705flags=0;
706usedelta=0;
707}
708
709void Joint::operator=(const Joint& src)
710{
711rot=src.rot;
712d=src.d;
713shape=src.shape;
714stamina=src.stamina;
715stif=src.stif; rotstif=src.rotstif;
716vis_style=src.vis_style;
717vcolor=src.vcolor;
718part1=0; part2=0;
719flags=src.flags;
720usedelta=src.usedelta;
721refno=src.refno;
722}
723
724void Joint::attachToParts(Part* p1,Part* p2)
725{
726part1=p1;
727part2=p2;
728if (p1 && p2)
729        {
730        o=rot;
731        if (usedelta)
732                {
733                p1->o.transform(p2->o,o);
734//              p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
735                p2->p=p2->o.transform(d)+p1->p;
736                }
737        }
738}
739
740void Joint::attachToParts(int p1,int p2)
741{
742attachToParts((p1>=0)?owner->getPart(p1):0,(p2>=0)?owner->getPart(p2):0);
743}
744
745void Joint::resetDelta()
746{
747d=Pt3D(JOINT_DELTA_MARKER,JOINT_DELTA_MARKER,JOINT_DELTA_MARKER);
748}
749
750void Joint::resetDeltaMarkers()
751{
752if (d.x==JOINT_DELTA_MARKER) d.x=0;
753if (d.y==JOINT_DELTA_MARKER) d.y=0;
754if (d.z==JOINT_DELTA_MARKER) d.z=0;
755}
756
757void Joint::useDelta(bool use)
758{
759usedelta=use;
760}
761
762bool Joint::isDelta()
763{
764return usedelta;
765}
766
767Param& Joint::getStaticParam()
768{
769static Param p(f0_joint_paramtab,0,"Joint");
770return p;
771}
772
773
774/////////////////////////////////////////////////////////////////
775/////////////////////////////////////////////////////////////////
776
777#include F0_CLASSES_FILE
778
779#ifdef MODEL_V1_COMPATIBLE
780
781#define FIELDSTRUCT Neuro
782ParamEntry f0_old_neuro_tab[]=
783{
784{"Connections",2,6,"n",},
785{"Other properties",},
786{"p",0,0,"part ref#","d",FIELD(part_refno),},
787{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
788{"s",1,0,"state","f",FIELD(state),},
789{"in",1,0,"Inertia","f",FIELD(inertia),},
790{"fo",1,0,"Force","f",FIELD(force),},
791{"si",1,0,"Sigmoid","f",FIELD(sigmo),},
792{0,0,0,},
793};
794#undef FIELDSTRUCT
795
796#define FIELDSTRUCT NeuroItem
797ParamEntry f0_neuroitem_paramtab[]=
798{
799{"Connections",3,12,"ni",},
800{"Geometry",},
801{"Other",},
802{"n",0,0,"neuron ref#","d",FIELD(neuro_refno),},
803{"c",2,0,"connection ref#","d",FIELD(conn_refno),},
804{"w",2,0,"connection weight","f",FIELD(weight),},
805{"p",0,0,"part ref#","d",FIELD(part_refno),},
806{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
807{"px",1,0,"position.x","f",FIELD(pos.x),},
808{"py",1,0,"position.y","f",FIELD(pos.y),},
809{"pz",1,0,"position.z","f",FIELD(pos.z),},
810{"rx",1,0,"rotation.x","f",FIELD(rot.x),},
811{"ry",1,0,"rotation.y","f",FIELD(rot.y),},
812{"rz",1,0,"rotation.z","f",FIELD(rot.z),},
813{"d",2,0,"item details","s",GETSET(details),},
814{0,0,0,},
815};
816#undef FIELDSTRUCT
817#endif
818
819////////////////////////////////////////
820
821ParamEntry Neuro::emptyParamTab[]=
822{
823{"Undefined Neuro",1,0,"?",},
824{0,0,0,},
825};
826
827Param Part::extraProperties()
828{
829return Param(f0_part_xtra_paramtab,this);
830}
831
832Param Joint::extraProperties()
833{
834return Param(f0_joint_xtra_paramtab,this);
835}
836
837Param Neuro::extraProperties()
838{
839return Param(f0_neuro_xtra_paramtab,this);
840}
841
842Param Part::properties()
843{
844return Param(f0_part_paramtab,this);
845}
846
847Param Joint::properties()
848{
849return Param(usedelta?f0_joint_paramtab:f0_nodeltajoint_paramtab,this);
850}
851
852Param Neuro::properties()
853{
854return Param(f0_neuro_paramtab,this);
855}
856
857class NeuroExtParamTab: public ParamTab
858{
859  public:
860NeuroExtParamTab():ParamTab(f0_neuro_paramtab)
861        {
862#define FIELDSTRUCT NeuroExt
863        ParamEntry entry={"class",2,0,"neuro class","s",GETSET(neuroclass)};
864#undef FIELDSTRUCT
865        add(&entry);
866
867#define FIELDSTRUCT Neuro
868        ParamEntry entry2={"state",2,0,"state","f",FIELD(state)};
869#undef FIELDSTRUCT
870        add(&entry2);
871        }
872};
873
874Param& Neuro::getStaticParam()
875{
876static Param p(f0_neuro_paramtab,0,"NeuroDef");
877return p;
878}
879
880////////////////////////
881
882NeuroConn::NeuroConn()
883{
884defassign();
885}
886
887//////////////////////////////////////
888
889ParamEntry *NeuroExt::getParamTab()
890{
891static NeuroExtParamTab tab;
892return tab.getParamTab();
893}
894
895void NeuroExt::get_neuroclass(PARAMGETARGS)
896{ret->setString(getClassName());}
897
898int NeuroExt::set_neuroclass(PARAMSETARGS)
899{setClassName(arg->getString());return PSET_CHANGED;}
900
901
Note: See TracBrowser for help on using the repository browser.