Changeset 721


Ignore:
Timestamp:
01/14/18 11:25:02 (2 years ago)
Author:
Maciej Komosinski
Message:

Code formatting

Location:
cpp/frams
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/neuro/neuroimpl.h

    r646 r721  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    2323{
    2424public:
    25 NeuroNetConfig(NeuroFactory *fac);
    26 
    27 Param par;
    28 double randominit;
    29 double nnoise;
    30 double touchrange;
    31 
    32 NeuroFactory *factory;
    33 //static NeuroNetConfig& getGlobalConfig();
     25        NeuroNetConfig(NeuroFactory *fac);
     26
     27        Param par;
     28        double randominit;
     29        double nnoise;
     30        double touchrange;
     31
     32        NeuroFactory *factory;
     33        //static NeuroNetConfig& getGlobalConfig();
    3434};
    3535
    3636#ifdef NEURO_SIGNALS
    37 class NeuroSignals: public SignalSet
     37class NeuroSignals : public SignalSet
    3838{
    39   protected:
    40 Creature *cr;
    41 NeuroImpl *owner;
    42 Creature *getCreature();
    43   public:
    44 
    45 NeuroSignals(NeuroImpl *n):cr(0),owner(n) {}
     39protected:
     40        Creature *cr;
     41        NeuroImpl *owner;
     42        Creature *getCreature();
     43public:
     44
     45        NeuroSignals(NeuroImpl *n) :cr(0), owner(n) {}
    4646
    4747#define STATRICKCLASS NeuroSignals
    48 PARAMPROCDEF(p_add);
    49 PARAMPROCDEF(p_get);
    50 PARAMGETDEF(size);
    51 PARAMPROCDEF(p_receive);
    52 PARAMPROCDEF(p_receiveSet);
    53 PARAMPROCDEF(p_receiveFilter);
    54 PARAMPROCDEF(p_receiveSingle);
     48        PARAMPROCDEF(p_add);
     49        PARAMPROCDEF(p_get);
     50        PARAMGETDEF(size);
     51        PARAMPROCDEF(p_receive);
     52        PARAMPROCDEF(p_receiveSet);
     53        PARAMPROCDEF(p_receiveFilter);
     54        PARAMPROCDEF(p_receiveSingle);
    5555#undef STATRICKCLASS
    5656
    57 static Param& getStaticParam();
     57        static Param& getStaticParam();
    5858};
    5959#endif
     
    6262class NeuroNetImpl
    6363{
    64 CallbackNode *cnode;
    65 Model &mod;
    66 SList neurons[4];
    67 NeuroNetConfig& config;
    68 int isbuilt,errorcount;
    69 STCALLBACKDEFC(NeuroNetImpl,destroyNN);
    70 int minorder,maxorder;
    71 
    72   public:
    73 #ifdef NEURO_SIGNALS
    74 ChannelSpace *channels;
    75 #endif
    76 static int mytags_id;
    77 static double getStateFromNeuro(Neuro *n);
    78 int getErrorCount() {return errorcount;}
    79 NeuroNetConfig &getConfig() {return config;}
    80 NeuroNetImpl(Model& model, NeuroNetConfig& conf
    81 #ifdef NEURO_SIGNALS
    82 , ChannelSpace *ch=0
    83 #endif
    84 );
    85 ~NeuroNetImpl();
    86 void simulateNeuroNet();
    87 void simulateNeuroPhysics();
    88 
    89 static NeuroImpl *getImpl(Neuro* n) {return (NeuroImpl*)n->userdata[mytags_id];}
     64        CallbackNode *cnode;
     65        Model &mod;
     66        SList neurons[4];
     67        NeuroNetConfig& config;
     68        int isbuilt, errorcount;
     69        STCALLBACKDEFC(NeuroNetImpl, destroyNN);
     70        int minorder, maxorder;
     71
     72public:
     73#ifdef NEURO_SIGNALS
     74        ChannelSpace *channels;
     75#endif
     76        static int mytags_id;
     77        static double getStateFromNeuro(Neuro *n);
     78        int getErrorCount() { return errorcount; }
     79        NeuroNetConfig &getConfig() { return config; }
     80        NeuroNetImpl(Model& model, NeuroNetConfig& conf
     81#ifdef NEURO_SIGNALS
     82                , ChannelSpace *ch = 0
     83#endif
     84                );
     85        ~NeuroNetImpl();
     86        void simulateNeuroNet();
     87        void simulateNeuroPhysics();
     88
     89        static NeuroImpl *getImpl(Neuro* n) { return (NeuroImpl*)n->userdata[mytags_id]; }
    9090};
    9191
     
    9595   (Neuro::state) in each simulation step.
    9696
    97 SUBCLASSING TUTORIAL
    98 ====================
    99 
    100 1.Derive your custom neuron from NeuroImpl class. The name must be prefixed with NI_
    101 
    102 class NI_MyNeuron: public NeuroImpl
    103 { ... };
    104 
    105 2.Public parameters
    106 Create any number of public fields, they will be adjustable from the genotype level.
    107 3 datatypes are supported: long, double and SString
    108 
    109 public:
    110   paInt intParameter;
    111   double fpParameter;
    112   SString txtParameter;
    113 
    114 
    115 3.Required method: "instantiator".
    116 It is always the same, just create a new instance of your neuron.
    117 public:
    118   NeuroImpl* makeNew() { return new NI_MyNeuron(); };
    119 
    120 
    121 4.Required method: default constructor
    122 Set the "paramentries" variable if you need public parameters in your neuron.
    123 NI_..._tab is created automatically and should be declared as: extern ParamEntry NI_..._tab[];
    124 At this stage the parameter values are not yet available.
    125 
    126 public:
    127  NI_MyNeuron() // no parameters!
    128  {
    129  paramentries=NI_MyNeuron_tab;
    130  // you add here: some general initialization
    131  }
    132 
    133 
    134 5.Optional method: initialization
    135 This method is called once before the neuron is actually used in the simulation.
    136 The parameter values are already initialized (according to the genotype) and the neuron is bound to the creature (i.e. this->neuro is valid).
    137 Return 0 if the neuron cannot be initialized.
    138 
    139 int lateinit()
    140  {
    141  // you add here: initialization using full neuron context
    142  // example: if (!neuro->joint) return 0; //this neuron must be attached to joint
    143  return 1;//OK
    144  }
    145 
    146 
    147 6.Required method: simulation step
    148 If it has output: calculate the next neuron state and call setState()
    149 If it is an effector: do anything else
    150 
    151 void go()
    152  {
    153  // you add here: things called every simulation step
    154  }
    155 
    156 Note: You can make your neuron fire before or after "regular" neurons by changing its "simorder" property (during initialization). The default value is 1, whereas receptors have simorder=0 and effectors have simorder=2.
    157 
    158 
    159 7.Neuron definition
    160 In order to incorporate the new neuron into Framsticks you need to provide some additional information (to be added to "f0.def" file).
    161 
    162 NEUROCLASS(MyNeuron,MN,This is the name,`Neuron description',-1,1,0)
    163 NEUROPROP(int,0,0,name of the int,d,,,,intParameter)
    164 NEUROPROP(fp,0,0,name of the floating point,f,,,,fpParameter)
    165 NEUROPROP(txt,0,0,name of the text,s,,,,txtParameter)
    166 ENDNEUROCLASS
    167 
    168 NEUROCLASS:
    169 - MyNeuron: neuron class name (without the NI_ prefix)
    170 - MN: neuron symbol (used in genotypes)
    171 - full name and description
    172 - -1: preferred number of inputs (special case: -1=any)
    173 - 1: provides output: 1=yes/0=no
    174 - 0: preferred location: 0=none, 1=part, 2=joint
    175 
    176 NEUROPROP:
    177 - int/fp/txt: parameter names as visible in genotypes and scripting
    178 - "name of the ...": descriptive name
    179 - d/f/s: type (int/floating point/string)
    180 - intParameter/fpParameter/txtParameter: C++ field names
    181 
    182    
    183  */
     97   SUBCLASSING TUTORIAL
     98   ====================
     99
     100   1.Derive your custom neuron from NeuroImpl class. The name must be prefixed with NI_
     101
     102   class NI_MyNeuron: public NeuroImpl
     103   { ... };
     104
     105   2.Public parameters
     106   Create any number of public fields, they will be adjustable from the genotype level.
     107   3 datatypes are supported: long, double and SString
     108
     109   public:
     110   paInt intParameter;
     111   double fpParameter;
     112   SString txtParameter;
     113
     114
     115   3.Required method: "instantiator".
     116   It is always the same, just create a new instance of your neuron.
     117   public:
     118   NeuroImpl* makeNew() { return new NI_MyNeuron(); };
     119
     120
     121   4.Required method: default constructor
     122   Set the "paramentries" variable if you need public parameters in your neuron.
     123   NI_..._tab is created automatically and should be declared as: extern ParamEntry NI_..._tab[];
     124   At this stage the parameter values are not yet available.
     125
     126   public:
     127   NI_MyNeuron() // no parameters!
     128   {
     129   paramentries=NI_MyNeuron_tab;
     130   // you add here: some general initialization
     131   }
     132
     133
     134   5.Optional method: initialization
     135   This method is called once before the neuron is actually used in the simulation.
     136   The parameter values are already initialized (according to the genotype) and the neuron is bound to the creature (i.e. this->neuro is valid).
     137   Return 0 if the neuron cannot be initialized.
     138
     139   int lateinit()
     140   {
     141   // you add here: initialization using full neuron context
     142   // example: if (!neuro->joint) return 0; //this neuron must be attached to joint
     143   return 1;//OK
     144   }
     145
     146
     147   6.Required method: simulation step
     148   If it has output: calculate the next neuron state and call setState()
     149   If it is an effector: do anything else
     150
     151   void go()
     152   {
     153   // you add here: things called every simulation step
     154   }
     155
     156   Note: You can make your neuron fire before or after "regular" neurons by changing its "simorder" property (during initialization). The default value is 1, whereas receptors have simorder=0 and effectors have simorder=2.
     157
     158
     159   7.Neuron definition
     160   In order to incorporate the new neuron into Framsticks you need to provide some additional information (to be added to "f0.def" file).
     161
     162   NEUROCLASS(MyNeuron,MN,This is the name,`Neuron description',-1,1,0)
     163   NEUROPROP(int,0,0,name of the int,d,,,,intParameter)
     164   NEUROPROP(fp,0,0,name of the floating point,f,,,,fpParameter)
     165   NEUROPROP(txt,0,0,name of the text,s,,,,txtParameter)
     166   ENDNEUROCLASS
     167
     168   NEUROCLASS:
     169   - MyNeuron: neuron class name (without the NI_ prefix)
     170   - MN: neuron symbol (used in genotypes)
     171   - full name and description
     172   - -1: preferred number of inputs (special case: -1=any)
     173   - 1: provides output: 1=yes/0=no
     174   - 0: preferred location: 0=none, 1=part, 2=joint
     175
     176   NEUROPROP:
     177   - int/fp/txt: parameter names as visible in genotypes and scripting
     178   - "name of the ...": descriptive name
     179   - d/f/s: type (int/floating point/string)
     180   - intParameter/fpParameter/txtParameter: C++ field names
     181
     182
     183   */
    184184class NeuroImpl
    185185{
    186186protected:
    187 int simorder;
    188 int channels;
    189 SListTempl<double> chstate;
    190 SListTempl<double> chnewstate;
    191 Param *fields_param;
    192 ExtObject *fields_object;
     187        int simorder;
     188        int channels;
     189        SListTempl<double> chstate;
     190        SListTempl<double> chnewstate;
     191        Param *fields_param;
     192        ExtObject *fields_object;
    193193public:
    194 static const int ENDDRAWING;
    195 static const int MAXDRAWINGXY;
    196 
    197 enum NeuroImplStats { BeforeInit=0, InitError=1, InitOk=2 };
    198 NeuroImplStats status;
    199 /** originating neuron object (from the model) */
    200 Neuro *neuro;
    201 NeuroClass *neuroclass;
    202 /** don't access directly */
    203 double newstate;
    204 NeuroNetImpl *owner;
    205 /** will be used by readParam() method, if not null  */
    206 ParamEntry *paramentries; // no extra properties if ==0
    207 
    208 #ifdef NEURO_SIGNALS
    209 NeuroSignals sigs;
    210 ExtObject sigs_obj;
    211 #endif
    212 
    213 /** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
    214     subclasses must return new object here. */
    215 virtual NeuroImpl* makeNew() {return 0;} //
    216 /** read additional properties from "moredata" field of the originating Neuro */
    217 void readParam();
    218 /** called when all other neuro objects were already created and "moredata" transferred to
    219     object fields.
    220     useful for initialization that cannot be performed in the constructor.
    221     @return 1=ok  0=failure
    222 */
    223 virtual int lateinit() {return 1;}
    224 /** calculate 'newstate - implementation dependent */
    225 virtual void go(){}
    226 /** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
    227 virtual void goPhysics(){}
    228 
    229 int getSimOrder() {return simorder;}
    230 virtual int getNeedPhysics() {return 0;}
    231 
    232 void setChannelCount(int c);
    233 int getChannelCount() {return channels;}
    234 
    235 int getInputCount() {return neuro->getInputCount();}
    236 int getInputChannelCount(int i);
    237 double getInputState(int i,int channel=0);
    238 double getWeightedInputState(int i,int channel=0);
    239 double getInputSum(int startwith=0);
    240 double getWeightedInputSum(int startwith=0);
    241 double getInputWeight(int i) {return neuro->getInputWeight(i);}
    242 void setState(double st,int channel);
    243 void setState(double st) {validateNeuroState(st); newstate=st;}
    244 double getState(int channel);
    245 double getState() {return neuro->state;}
    246 
    247 virtual int getDrawingCount() {return 0;}
    248 virtual int* getDrawing(int i) {return 0;}
    249 
    250 /** is this implementation current? script neurons retain their original implementation when reloading *.neuro */
    251 virtual bool isCurrent() {return true;}
    252 
    253 void commit();
    254 void validateNeuroState(double& st) {if (st<=-1e10) st=-1e10; else if (st>1e10) st=1e10;}
    255 
    256 NeuroImpl():simorder(1),channels(1),fields_param(0),fields_object(0),status(BeforeInit),neuro(0),newstate(0),owner(0),paramentries(0)
    257 #ifdef NEURO_SIGNALS
    258 ,sigs(this),sigs_obj(&NeuroSignals::getStaticParam(),&sigs)
    259 #endif
    260  {}
    261 virtual ~NeuroImpl();
    262 virtual void createFieldsObject();
    263 
    264 /** usually == "newstate" but will obey the "hold state" */
    265 double getNewState(int channel=0);
    266 
    267 /** don't use! */
    268 void setCurrentState(double st,int channel=0);
    269 
    270 bool getPosition(Pt3D &pos);
    271 Creature* getCreature();
     194        static const int ENDDRAWING;
     195        static const int MAXDRAWINGXY;
     196
     197        enum NeuroImplStats { BeforeInit = 0, InitError = 1, InitOk = 2 };
     198        NeuroImplStats status;
     199        /** originating neuron object (from the model) */
     200        Neuro *neuro;
     201        NeuroClass *neuroclass;
     202        /** don't access directly */
     203        double newstate;
     204        NeuroNetImpl *owner;
     205        /** will be used by readParam() method, if not null  */
     206        ParamEntry *paramentries; // no extra properties if ==0
     207
     208#ifdef NEURO_SIGNALS
     209        NeuroSignals sigs;
     210        ExtObject sigs_obj;
     211#endif
     212
     213        /** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
     214                subclasses must return new object here. */
     215        virtual NeuroImpl* makeNew() { return 0; } //
     216        /** read additional properties from "moredata" field of the originating Neuro */
     217        void readParam();
     218        /** called when all other neuro objects were already created and "moredata" transferred to
     219                object fields.
     220                useful for initialization that cannot be performed in the constructor.
     221                @return 1=ok  0=failure
     222                */
     223        virtual int lateinit() { return 1; }
     224        /** calculate 'newstate - implementation dependent */
     225        virtual void go(){}
     226        /** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
     227        virtual void goPhysics(){}
     228
     229        int getSimOrder() { return simorder; }
     230        virtual int getNeedPhysics() { return 0; }
     231
     232        void setChannelCount(int c);
     233        int getChannelCount() { return channels; }
     234
     235        int getInputCount() { return neuro->getInputCount(); }
     236        int getInputChannelCount(int i);
     237        double getInputState(int i, int channel = 0);
     238        double getWeightedInputState(int i, int channel = 0);
     239        double getInputSum(int startwith = 0);
     240        double getWeightedInputSum(int startwith = 0);
     241        double getInputWeight(int i) { return neuro->getInputWeight(i); }
     242        void setState(double st, int channel);
     243        void setState(double st) { validateNeuroState(st); newstate = st; }
     244        double getState(int channel);
     245        double getState() { return neuro->state; }
     246
     247        virtual int getDrawingCount() { return 0; }
     248        virtual int* getDrawing(int i) { return 0; }
     249
     250        /** is this implementation current? script neurons retain their original implementation when reloading *.neuro */
     251        virtual bool isCurrent() { return true; }
     252
     253        void commit();
     254        void validateNeuroState(double& st) { if (st <= -1e10) st = -1e10; else if (st > 1e10) st = 1e10; }
     255
     256        NeuroImpl() :simorder(1), channels(1), fields_param(0), fields_object(0), status(BeforeInit), neuro(0), newstate(0), owner(0), paramentries(0)
     257#ifdef NEURO_SIGNALS
     258                , sigs(this), sigs_obj(&NeuroSignals::getStaticParam(), &sigs)
     259#endif
     260        {}
     261        virtual ~NeuroImpl();
     262        virtual void createFieldsObject();
     263
     264        /** usually == "newstate" but will obey the "hold state" */
     265        double getNewState(int channel = 0);
     266
     267        /** don't use! */
     268        void setCurrentState(double st, int channel = 0);
     269
     270        bool getPosition(Pt3D &pos);
     271        Creature* getCreature();
    272272
    273273#define STATRICKCLASS NeuroImpl
    274 PARAMGETDEF(count) {arg1->setInt(getInputCount());}
    275 PARAMPROCDEF(p_get) {arg2->setDouble(getInputState(arg1->getInt()));}
    276 PARAMPROCDEF(p_getweight) {arg2->setDouble(getInputWeight(arg1->getInt()));}
    277 PARAMPROCDEF(p_getw) {arg2->setDouble(getWeightedInputState(arg1->getInt()));}
    278 PARAMPROCDEF(p_getsum) {arg2->setDouble(getInputSum(arg1->getInt()));}
    279 PARAMPROCDEF(p_getwsum) {arg2->setDouble(getWeightedInputSum(arg1->getInt()));}
    280 PARAMGETDEF(sum) {arg1->setDouble(getInputSum(0));}
    281 PARAMGETDEF(wsum) {arg1->setDouble(getWeightedInputSum(0));}
    282 PARAMPROCDEF(p_getchancount) {arg2->setInt(getInputChannelCount(arg1->getInt()));}
    283 PARAMPROCDEF(p_getchan) {arg2->setDouble(getInputState(arg1[1].getInt(),arg1[0].getInt()));}
    284 PARAMPROCDEF(p_getwchan) {arg2->setDouble(getWeightedInputState(arg1[1].getInt(),arg1[0].getInt()));}
    285 PARAMGETDEF(state) {arg1->setDouble(getState());}
    286 PARAMSETDEF(state) {setState(arg1->getDouble()); return 0;}
    287 PARAMGETDEF(cstate) {arg1->setDouble(neuro->state);}
    288 PARAMSETDEF(cstate) {setCurrentState(arg1->getDouble()); return 0;}
    289 PARAMGETDEF(hold) {arg1->setInt((neuro->flags&(Neuro::HoldState))?1:0);}
    290 PARAMSETDEF(hold) {neuro->flags=(neuro->flags&~Neuro::HoldState)|(arg1->getInt()?Neuro::HoldState:0); return 0;}
    291 PARAMGETDEF(channels) {arg1->setInt(getChannelCount());}
    292 PARAMSETDEF(channels) {setChannelCount(arg1->getInt()); return 0;}
    293 PARAMPROCDEF(p_getstate) {arg2->setDouble(getState(arg1->getInt()));}
    294 PARAMPROCDEF(p_setstate) {setState(arg1[0].getDouble(),arg1[1].getInt());}
    295 PARAMPROCDEF(p_setcstate) {setCurrentState(arg1[0].getDouble(),arg1[1].getInt());}
    296 PARAMGETDEF(creature);
    297 PARAMGETDEF(part);
    298 PARAMGETDEF(joint);
    299 PARAMGETDEF(position_x);
    300 PARAMGETDEF(position_y);
    301 PARAMGETDEF(position_z);
    302 PARAMGETDEF(fields);
    303 PARAMGETDEF(neurodef);
    304 PARAMGETDEF(classObject);
     274        PARAMGETDEF(count) { arg1->setInt(getInputCount()); }
     275        PARAMPROCDEF(p_get) { arg2->setDouble(getInputState(arg1->getInt())); }
     276        PARAMPROCDEF(p_getweight) { arg2->setDouble(getInputWeight(arg1->getInt())); }
     277        PARAMPROCDEF(p_getw) { arg2->setDouble(getWeightedInputState(arg1->getInt())); }
     278        PARAMPROCDEF(p_getsum) { arg2->setDouble(getInputSum(arg1->getInt())); }
     279        PARAMPROCDEF(p_getwsum) { arg2->setDouble(getWeightedInputSum(arg1->getInt())); }
     280        PARAMGETDEF(sum) { arg1->setDouble(getInputSum(0)); }
     281        PARAMGETDEF(wsum) { arg1->setDouble(getWeightedInputSum(0)); }
     282        PARAMPROCDEF(p_getchancount) { arg2->setInt(getInputChannelCount(arg1->getInt())); }
     283        PARAMPROCDEF(p_getchan) { arg2->setDouble(getInputState(arg1[1].getInt(), arg1[0].getInt())); }
     284        PARAMPROCDEF(p_getwchan) { arg2->setDouble(getWeightedInputState(arg1[1].getInt(), arg1[0].getInt())); }
     285        PARAMGETDEF(state) { arg1->setDouble(getState()); }
     286        PARAMSETDEF(state) { setState(arg1->getDouble()); return 0; }
     287        PARAMGETDEF(cstate) { arg1->setDouble(neuro->state); }
     288        PARAMSETDEF(cstate) { setCurrentState(arg1->getDouble()); return 0; }
     289        PARAMGETDEF(hold) { arg1->setInt((neuro->flags&(Neuro::HoldState)) ? 1 : 0); }
     290        PARAMSETDEF(hold) { neuro->flags = (neuro->flags&~Neuro::HoldState) | (arg1->getInt() ? Neuro::HoldState : 0); return 0; }
     291        PARAMGETDEF(channels) { arg1->setInt(getChannelCount()); }
     292        PARAMSETDEF(channels) { setChannelCount(arg1->getInt()); return 0; }
     293        PARAMPROCDEF(p_getstate) { arg2->setDouble(getState(arg1->getInt())); }
     294        PARAMPROCDEF(p_setstate) { setState(arg1[0].getDouble(), arg1[1].getInt()); }
     295        PARAMPROCDEF(p_setcstate) { setCurrentState(arg1[0].getDouble(), arg1[1].getInt()); }
     296        PARAMGETDEF(creature);
     297        PARAMGETDEF(part);
     298        PARAMGETDEF(joint);
     299        PARAMGETDEF(position_x);
     300        PARAMGETDEF(position_y);
     301        PARAMGETDEF(position_z);
     302        PARAMGETDEF(fields);
     303        PARAMGETDEF(neurodef);
     304        PARAMGETDEF(classObject);
    305305#undef STATRICKCLASS
    306306
    307   static Param& getStaticParam();
     307        static Param& getStaticParam();
    308308};
    309309
  • cpp/frams/param/multiparamload.h

    r535 r721  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1414        http://www.framsticks.com/common/formatspec.html
    1515        The loader can be configured to recognize multiple object types from object headers
    16     and automatically call ParamInterface::load for the matching class.
    17    
    18     Your code should repeatedly call MultiParamLoader::go() method and check the status after each call, until the end of file.
    19     The loader pauses before and/or after each object giving you a chance to perform your application-specific actions (see MultiParamLoader::breakOn()).
    20     If your application does not require any special actions, then the simple MultiParamLoader:run() can be used.
    21     The word "record" (and "record type") used in this description refer to the textual form of a serialized object - this is to avoid confusion with 'live' objects passed to the loader methods. "Record type" can be the same as the class name, but it does not have to be the same. For example, the most common record type for storing the Genotype object is called "org" (think: organism) instead of "Genotype".
     16        and automatically call ParamInterface::load for the matching class.
    2217
    23     Typical usage scenarios:
    24     1. Loading a file that contains at most one object of any given class:
    25     - declare the object class(es) - MultiParamLoader::addClass()
    26     - call MultiParamLoader::run()
    27     - and that's all, the records from the file will be loaded into the corresponding objects
     18        Your code should repeatedly call MultiParamLoader::go() method and check the status after each call, until the end of file.
     19        The loader pauses before and/or after each object giving you a chance to perform your application-specific actions (see MultiParamLoader::breakOn()).
     20        If your application does not require any special actions, then the simple MultiParamLoader:run() can be used.
     21        The word "record" (and "record type") used in this description refer to the textual form of a serialized object - this is to avoid confusion with 'live' objects passed to the loader methods. "Record type" can be the same as the class name, but it does not have to be the same. For example, the most common record type for storing the Genotype object is called "org" (think: organism) instead of "Genotype".
    2822
    29     2. Loading multiple objects and adding them to a list (see loadtest.cpp for a sample code that demonstrates this scenario)
    30     - declare the object class giving the empty "template" object - MultiParamLoader::addClass()
    31     - set breakOn(AfterObject)
    32     - call MultiParamLoader::go() in a loop
    33     - the returned status will be equal to AfterObject each time an object is loaded. One can detect this condition and create the real object from our template object
    34     (alternatively, one could breakOn(BeforeObject) and use MultiParamLoader::loadObjectNow(ParamInterface*) to load the incoming object into a newly created object).   
    35  */
     23        Typical usage scenarios:
     24        1. Loading a file that contains at most one object of any given class:
     25        - declare the object class(es) - MultiParamLoader::addClass()
     26        - call MultiParamLoader::run()
     27        - and that's all, the records from the file will be loaded into the corresponding objects
     28
     29        2. Loading multiple objects and adding them to a list (see loadtest.cpp for a sample code that demonstrates this scenario)
     30        - declare the object class giving the empty "template" object - MultiParamLoader::addClass()
     31        - set breakOn(AfterObject)
     32        - call MultiParamLoader::go() in a loop
     33        - the returned status will be equal to AfterObject each time an object is loaded. One can detect this condition and create the real object from our template object
     34        (alternatively, one could breakOn(BeforeObject) and use MultiParamLoader::loadObjectNow(ParamInterface*) to load the incoming object into a newly created object).
     35        */
    3636class MultiParamLoader
    3737{
    38 VirtFILE *file;
    39 SListTempl<VirtFILE*> filestack;
    40 char ownfile;
    41 PtrListTempl<ExtObject*> objects;
    42 int status;
    43 SString lasterror, lastcomment, lastunknown;
    44 ExtObject lastobject;
    45 int breakcond;
    46 Param emptyparam;
    47 bool aborting;
    48 int linenum;
     38        VirtFILE *file;
     39        SListTempl<VirtFILE*> filestack;
     40        char ownfile;
     41        PtrListTempl<ExtObject*> objects;
     42        int status;
     43        SString lasterror, lastcomment, lastunknown;
     44        ExtObject lastobject;
     45        int breakcond;
     46        Param emptyparam;
     47        bool aborting;
     48        int linenum;
    4949
    50 void init();
     50        void init();
    5151
    52 int maybeBreak(int cond)
    53 { status=cond; return breakcond & cond; }
     52        int maybeBreak(int cond)
     53        {
     54                status = cond;
     55                return breakcond & cond;
     56        }
    5457
    55 VirtFILE* popstack();
    56 void clearstack();
     58        VirtFILE* popstack();
     59        void clearstack();
    5760
    58   public:
    59 MultiParamLoader() {init();}
    60 MultiParamLoader(VirtFILE *f) {init(); load(f);}
    61 MultiParamLoader(const char* filename) {init(); load(filename);}
     61public:
     62        MultiParamLoader() { init(); }
     63        MultiParamLoader(VirtFILE *f) { init(); load(f); }
     64        MultiParamLoader(const char* filename) { init(); load(filename); }
    6265
    63 ~MultiParamLoader() {abort();clearObjects();}
     66        ~MultiParamLoader() { abort(); clearObjects(); }
    6467
    65 void reset();
     68        void reset();
    6669
    67 void load(); //< use previously opened file
    68 void load(VirtFILE *f);
    69 void load(const char* filename);
     70        void load(); //< use previously opened file
     71        void load(VirtFILE *f);
     72        void load(const char* filename);
    7073
    71 /** Register the object class. Class names will be matched with object headers ("xxx:" in the input file).
    72     Used with breakOn(BeforeObject) and/or breakOn(AfterObject).
    73     Note that registered classes will only work when the record name matches the class name, otherwise breakOn(BeforeUnknown) must be used and then getClassName() to check for the expected record.
    74  */
    75 void addObject(ParamInterface *pi) {objects+=new ExtObject(pi);}
    76 void removeObject(ParamInterface *pi) {removeObject(ExtObject(pi));}
    77 void addObject(const ExtObject &o) {objects+=new ExtObject(o);}
    78 void removeObject(const ExtObject &o);
    79 int findObject(const ExtObject &o);
    80 void clearObjects();
     74        /** Register the object class. Class names will be matched with object headers ("xxx:" in the input file).
     75                Used with breakOn(BeforeObject) and/or breakOn(AfterObject).
     76                Note that registered classes will only work when the record name matches the class name, otherwise breakOn(BeforeUnknown) must be used and then getClassName() to check for the expected record.
     77                */
     78        void addObject(ParamInterface *pi) { objects += new ExtObject(pi); }
     79        void removeObject(ParamInterface *pi) { removeObject(ExtObject(pi)); }
     80        void addObject(const ExtObject &o) { objects += new ExtObject(o); }
     81        void removeObject(const ExtObject &o);
     82        int findObject(const ExtObject &o);
     83        void clearObjects();
    8184
    82 /** To be used in the main loop: while(event=loader.go()) { ... }
    83     loader.go() will return on specified events (@see breakOn(), noBreakOn()),
    84     then you can handle the event and resume loading.
    85  */
    86 virtual int go();
    87 /** same value as 'go()' */
    88 int getStatus() {return status;}
    89 int finished() {return (status==Finished);}
     85        /** To be used in the main loop: while(event=loader.go()) { ... }
     86                loader.go() will return on specified events (@see breakOn(), noBreakOn()),
     87                then you can handle the event and resume loading.
     88                */
     89        virtual int go();
     90        /** same value as 'go()' */
     91        int getStatus() { return status; }
     92        int finished() { return (status == Finished); }
    9093
    91 VirtFILE *getFile() {return file;}
    92 SString currentFilePathForErrorMessage();
     94        VirtFILE *getFile() { return file; }
     95        SString currentFilePathForErrorMessage();
    9396
    94 /** Abort immediately and close the file if needed */
    95 void abort();
    96 /** @param conditions can be combined bitwise, eg. MultiParamLoader::BeforeObject |  MultiParamLoader::OnComment
    97     @see BreakConfitions
    98 */
    99 void breakOn(int conditions) {breakcond|=conditions;}
    100 void noBreakOn(int conditions) {breakcond&=~conditions;}
    101 /**
    102    These constants are used as arguments in breakOn(), and as status values from go() and getStatus().
    103    The user code can define some classes for automatic recognition (using addClass()); such records can be read without performing any additional actions.
    104    
    105    - BeforeObject: found an object with recognized classname (addClass()). Application code can choose to skip the incoming record (skipObject()), redirect the incoming data into a different object (loadObjectNow(ParamInterface*)), or do nothing for default behavior (loading into previously registered object).
     97        /** Abort immediately and close the file if needed */
     98        void abort();
     99        /** @param conditions can be combined bitwise, eg. MultiParamLoader::BeforeObject |  MultiParamLoader::OnComment
     100                @see BreakConfitions
     101                */
     102        void breakOn(int conditions) { breakcond |= conditions; }
     103        void noBreakOn(int conditions) { breakcond &= ~conditions; }
     104        /**
     105           These constants are used as arguments in breakOn(), and as status values from go() and getStatus().
     106           The user code can define some classes for automatic recognition (using addClass()); such records can be read without performing any additional actions.
    106107
    107    - AfterObject: the object was loaded into the registered class interface (addClass()). This is to allow for additional actions after loading the object (e.g. data validation).
     108           - BeforeObject: found an object with recognized classname (addClass()). Application code can choose to skip the incoming record (skipObject()), redirect the incoming data into a different object (loadObjectNow(ParamInterface*)), or do nothing for default behavior (loading into previously registered object).
    108109
    109    - BeforeUnknown: unknown (not registered) object header detected. Like in BeforeObject, the application can skipObject() or loadObjectNow().
     110           - AfterObject: the object was loaded into the registered class interface (addClass()). This is to allow for additional actions after loading the object (e.g. data validation).
    110111
    111 @see getClass(), GetClassName()
    112  */
    113 enum BreakConditions { Finished=0, BeforeObject=1, AfterObject=2,
    114                        BeforeUnknown=4, OnComment=8, OnError=16, Loading=32 };
     112           - BeforeUnknown: unknown (not registered) object header detected. Like in BeforeObject, the application can skipObject() or loadObjectNow().
    115113
    116 /** Can be used BeforeObject and AfterObject */
    117 ExtObject &getObject() {return lastobject;}
    118 /** Can be used BeforeUnknown, BeforeObject, AfterObject */
    119 const SString& getObjectName() {return lastunknown;}
    120 void setObjectName(SString n) {lastunknown=n;}
    121 /** Unknown object will be loaded if you set its class BeforeUnknown */
    122 void setObject(ParamInterface *pi) {lastobject=ExtObject(pi);}
    123 void setObject(const ExtObject& o) {lastobject=o;}
    124 /** Can be used OnComment */
    125 const SString& getComment() {return lastcomment;}
    126 /** Can be used OnError */
    127 const SString& getError() {return lasterror;}
    128 /** Can be used BeforeObject and BeforeUnknown */
    129 int loadObjectNow(ParamInterface *pi,bool warn_unknown_fields=true) {return loadObjectNow(ExtObject(pi),warn_unknown_fields);}
    130 int loadObjectNow(const ExtObject &o,bool warn_unknown_fields=true);
    131 /** Can be used BeforeObject */
    132 int loadObjectNow() {return loadObjectNow(getObject());}
    133 /** Can be used BeforeObject and BeforeUnknown.
    134     Object data will not be loaded. */
    135 int skipObject() {return loadObjectNow(&emptyparam,false);}
    136 /** @return 1 if no errors */
    137 int run();
     114           @see getClass(), GetClassName()
     115           */
     116        enum BreakConditions {
     117                Finished = 0, BeforeObject = 1, AfterObject = 2,
     118                BeforeUnknown = 4, OnComment = 8, OnError = 16, Loading = 32
     119        };
    138120
    139 void includeFile(SString& filename);
    140 bool returnFromIncluded();
    141 bool alreadyIncluded(const char* filename);
     121        /** Can be used BeforeObject and AfterObject */
     122        ExtObject &getObject() { return lastobject; }
     123        /** Can be used BeforeUnknown, BeforeObject, AfterObject */
     124        const SString& getObjectName() { return lastunknown; }
     125        void setObjectName(SString n) { lastunknown = n; }
     126        /** Unknown object will be loaded if you set its class BeforeUnknown */
     127        void setObject(ParamInterface *pi) { lastobject = ExtObject(pi); }
     128        void setObject(const ExtObject& o) { lastobject = o; }
     129        /** Can be used OnComment */
     130        const SString& getComment() { return lastcomment; }
     131        /** Can be used OnError */
     132        const SString& getError() { return lasterror; }
     133        /** Can be used BeforeObject and BeforeUnknown */
     134        int loadObjectNow(ParamInterface *pi, bool warn_unknown_fields = true) { return loadObjectNow(ExtObject(pi), warn_unknown_fields); }
     135        int loadObjectNow(const ExtObject &o, bool warn_unknown_fields = true);
     136        /** Can be used BeforeObject */
     137        int loadObjectNow() { return loadObjectNow(getObject()); }
     138        /** Can be used BeforeObject and BeforeUnknown.
     139                Object data will not be loaded. */
     140        int skipObject() { return loadObjectNow(&emptyparam, false); }
     141        /** @return 1 if no errors */
     142        int run();
     143
     144        void includeFile(SString& filename);
     145        bool returnFromIncluded();
     146        bool alreadyIncluded(const char* filename);
    142147
    143148};
    144149
    145150#endif
    146 
  • cpp/frams/param/syntparam.h

    r288 r721  
    99
    1010/** Creates param + matching temporary object (ParamObject)
    11     using the supplied ParamEntry'ies as a template.
    12     This is mainly used for manipulating specialized neuron properties
    13     (Neuro.d field) in absence of live neuron implementations
    14     (these are only available in live creatures, but not when operating
    15     on Models and Genotypes).
     11        using the supplied ParamEntry'ies as a template.
     12        This is mainly used for manipulating specialized neuron properties
     13        (Neuro.d field) in absence of live neuron implementations
     14        (these are only available in live creatures, but not when operating
     15        on Models and Genotypes).
    1616
    17     See also: genomanipulation.cpp
    18  */
    19 class SyntParam: public Param
     17        See also: genomanipulation.cpp
     18        */
     19class SyntParam : public Param
    2020{
    21 void* obj,*def_obj;
    22 ParamEntry *pe;
    23 SString* autostring;
    24   public:
    25 /** @param handle_defaults_when_saving creates a second object holding the default values so Param::save2 can use it for omitting defaults. can be disabled for compatiblity with previous behavior (defaults were ignored in SyntParam)
    26  */
    27 SyntParam(ParamEntry *pe,SString* autostring=0,bool handle_defaults_when_saving=true);
    28 SyntParam(const SyntParam& src);
    29 ~SyntParam();
    30 void setAutoUpdate(SString* autostr) {autostring=autostr;}
    31 void update(SString *s=0);
    32 void revert(SString *s=0);
     21        void* obj, *def_obj;
     22        ParamEntry *pe;
     23        SString* autostring;
     24public:
     25        /** @param handle_defaults_when_saving creates a second object holding the default values so Param::save2 can use it for omitting defaults. can be disabled for compatiblity with previous behavior (defaults were ignored in SyntParam)
     26        */
     27        SyntParam(ParamEntry *pe, SString* autostring = 0, bool handle_defaults_when_saving = true);
     28        SyntParam(const SyntParam& src);
     29        ~SyntParam();
     30        void setAutoUpdate(SString* autostr) { autostring = autostr; }
     31        void update(SString *s = 0);
     32        void revert(SString *s = 0);
    3333};
    3434
Note: See TracChangeset for help on using the changeset viewer.