CellModules
PrimoCell.hpp
Go to the documentation of this file.
1
6#ifndef BASEPROJECT_Cell_HPP
7#define BASEPROJECT_Cell_HPP
8
9#include <cassert>
10#include <mecacell/mecacell.h>
11#include "../core/Model.hpp"
12#include "../tools/TimeConvert.hpp"
13#include "../tools/RandomManager.hpp"
14
15/*isigen:eval@utilityDeclarations'''
16 from string import Template
17 from functools import cmp_to_key
18 caseTemplate = Template("""
19 case State::$name : {
20 \t$code
21 \tbreak;
22 }""")
23 def buildConditionsCode(destinations):
24 destinations = sorted(destinations, key=cmp_to_key(lambda a, b: (a["condition"] == '')-(b["condition"] == '')))
25 allCode = ''
26 for i,d in enumerate(destinations):
27 if d["to"] == 'CellInstantiation':
28 action = 'this->init()'
29 elif d["to"] == 'DeadCell':
30 action = 'this->die()'
31 else:
32 action = 'this->state = State::{state}'.format(state=d["to"])
33 if (i == 0) & (d["condition"] != ''): code = 'if({condition}) {action};\n'
34 elif (i == 0) & (d["condition"] == ''): code = '{action};\n'
35 elif d["condition"] == '': code = 'else {action};\n'
36 else: code = 'else if({condition}) {action};\n'
37 allCode += code.format(condition=d["condition"],action=action);
38 return allCode;
39 '''*/
40
41/*isigen:insert@includes'''
42 includes = ''
43 for m,configJson in modulesConfigs.items():
44 if "Body" in configJson:
45 includes += '\n'.join(["#include \"../../{cellModulesPath}/{moduleName}/{cellInclude}\""\
46 .format(cellModulesPath=cellModulesPath,moduleName=m,cellInclude=ci) for ci in configJson["Body"]["cellIncludes"] ])+'\n'
47 print(includes)
48 '''*/
49
58template<template<typename> class B>
59class PrimoCell : public MecaCell::ConnectableCell<PrimoCell<B>, B> {
61public:
62 using Cell = PrimoCell;
64private:
67
74 Type type;
75
82 State state;
83
84 World& world; /* The world manages cell registration, IDs refresh, and plugins. */
85
87 bool _alreadyNextState = false;
89 bool _firstInit = true;
90
91
93 void behave() {
94 switch(this->state) {
95 /*isigen:insert@behave'''
96 behaviour = ''
97 for s in builderData["cell"]["States"]:
98 behaviour += caseTemplate.substitute({'name':s['name'], 'code': s['code'].replace('\n','\n\t')})
99 print(behaviour)
100 '''*/
101 default:
102 {
103 cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
104 break;
105 }
106 }
107 }
108
110 void nextState() {
111 switch(this->state){
112 /*isigen:insert@nextState'''
113 transition = ''
114 for t in builderData["cell"]["Transitions"]:
115 transition += caseTemplate.substitute({'name': t['from'], 'code': buildConditionsCode(t['destinations']).replace('\n','\n\t')})
116 print(transition)
117 '''*/
118 default:
119 {
120 //cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
121 break;
122 }
123 }
124 }
125
134 int idMother = this->id;
135 auto *daughter = new PrimoCell(this);
136 daughter->mother_id = idMother;
137 this->mother_id = idMother;
138 world.addCell(daughter);
139 daughter->setType(this->type);
140 daughter->init();
141 return daughter;
142 }
143
152 Cell * createCell(Type t){
153 int idMother = this->id;
154 auto *daughter = new PrimoCell(this);
155 daughter->mother_id = idMother;
156 this->mother_id = idMother;
157 world.addCell(daughter);
158 daughter->setType(t);
159 daughter->init();
160 return daughter;
161 }
162
163public:
165 int mother_id = -1;
166
173 void setWorld(World* w) {
174 assert(w == &world);
175 }
176 /*isigen:insert@attributes'''
177 print('\n'.join(["\t{type} {value};".format(type=a['type'], value=a['value']) for a in builderData["cell"]["attributes"] if a['source'] != 'core']))
178 '''*/
179
180
181 /*isigen:insert@functions'''
182 print('\n'.join([code.replace('\n','//isigen:metaDataDebug['+re.search(r'(\w+[\d_\w]+)\s*\‍(',code).group(1)+'] '+'{"idFunc":"'+idFunc+'"}\n',1) for idFunc,code in builderData["cell"]["functions"].items()]))
183 '''*/
184
185
186 /*isigen:insert@cellModuleFunctions'''
187 print('\n'.join([ '\n'.join([c['code'] for c in v['cellFunctions']]) for v in modulesConfigs.values() if 'cellFunctions' in v]))
188 '''*/
189
197 :Base(v), model(m), type((Type)0), world(w)
198 {
199 this->getBody().setPosition(v);
200 }
201
208 :Base(MecaCell::Vec(0.,0.,0.)), model(m), type((Type)0), world(w)
209 {
210 this->getBody().setPosition(MecaCell::Vec(0.,0.,0.));
211 }
212
219 :Base(mother->getBody().getPosition()),
220 model(mother->getModel()), type((Type)0), world(mother->world)
221 {
222 this->getBody().setPosition(mother->getBody().getPosition());
223 }
224
230 void init() {
231 if(!_firstInit) world.refreshId(this);
232 else _firstInit = false;
233 model.initCell(this);
234 /*isigen:insert@init'''
235 initCode = builderData["cell"]["initializationCode"]
236 if len(builderData["cell"]["initializationTransitions"])>0:
237 destinations = builderData["cell"]["initializationTransitions"][0]["destinations"].copy()
238 print(initCode+'\n'+buildConditionsCode(destinations))
239 '''*/
240 this->_alreadyNextState = true;
241 }
242
244 Model & getModel() const { return model; }
245
251 Type getType() const { return type; }
252
258 void setType(Type t) { type = t; model.initCell(this); }
259
265 State getState() { return state; }
266
272 void setState(State s) { state = s; this->_alreadyNextState = true; }
273
279 double getRadius(){ return this->getBody().getBoundingBoxRadius(); }
280
286 void setRadius(const double &_radius){ this->getBody().setRadius(_radius); }
287
293 void setPosition(const MecaCell::Vec &_pos) { this->getBody().setPosition(_pos); }
294
301 bool isType(Type t) {return this->type == t;}
302
309 bool isInContactWith(Type t){
310 for(auto *c : this->getConnectedCells())
311 if(c->isType(t)) return true;
312 return false;
313 }
314
321 int countNeighborType(Type t){
322 int count = 0;
323 for(auto *c : this->getConnectedCells())
324 if(c->isType(t)) count++;
325 return count;
326 }
327
333 bool isInContact(){ return (this->getConnectedCells().size() > 0); }
334
337 this->_alreadyNextState = false;
338 behave();
339 if(!this->_alreadyNextState) nextState();
340 }
341
347 int getId() const { return this->id; }
348
354 int getMotherId() const { return this->mother_id; }
355
356
363 const PreSetCell& getParametersFrom(Type type) const {
364 return this->model.getPreSetCell(type);
365 }
366};
367
368
369#endif //BASEPROJECT_Cell_HPP
370//'''
Model::PreSetCell PreSetCell
Definition: PrimoCell.hpp:51
Basis for every cell a user might want to use.
const std::vector< PrimoCell< B > * > & getConnectedCells() const
general purpose 3D vector/point class.
Definition: vector3D.h:20
Where "everything" happens.
Definition: world.hpp:29
void addCell(Cell *c)
adds a cell to the new cells batch (which will be added to the main cells container at the end of the...
Definition: world.hpp:246
void refreshId(Cell *c)
Definition: world.hpp:255
Definition: Model.hpp:41
const PreSetCell & getPreSetCell(Type type) const
Definition: Model.hpp:81
void initCell(Cell *c)
Definition: Model.hpp:77
Represents a cell in the simulation.
Definition: PrimoCell.hpp:59
PrimoCell(Model &m, World &w)
Constructs a PrimoCell with a model.
Definition: PrimoCell.hpp:207
bool isType(Type t)
Checks if the cell is of a specific type.
Definition: PrimoCell.hpp:301
void init()
Initializes the cell.
Definition: PrimoCell.hpp:230
void setPosition(const MecaCell::Vec &_pos)
Sets the position of the cell.
Definition: PrimoCell.hpp:293
State state
Current state of the cell's internal state machine.
Definition: PrimoCell.hpp:82
int countNeighborType(Type t)
Counts the number of neighboring cells of a specific type.
Definition: PrimoCell.hpp:321
bool isInContactWith(Type t)
Checks if the cell is in contact with a cell of a specific type.
Definition: PrimoCell.hpp:309
void behave()
@ignore
Definition: PrimoCell.hpp:93
PrimoCell(PrimoCell< B > *mother)
Constructs a PrimoCell from a mother cell.
Definition: PrimoCell.hpp:218
void updateBehavior()
@ignore
Definition: PrimoCell.hpp:336
State getState()
Gets the state of the cell.
Definition: PrimoCell.hpp:265
PrimoCell(const MecaCell::Vec &v, Model &m, World &w)
Constructs a PrimoCell with a position and model.
Definition: PrimoCell.hpp:196
bool _firstInit
@ignore
Definition: PrimoCell.hpp:89
int getId() const
Gets the ID of the cell.
Definition: PrimoCell.hpp:347
int mother_id
@ignore
Definition: PrimoCell.hpp:165
Type type
Current type of the cell.
Definition: PrimoCell.hpp:74
Type getType() const
Gets the type of the cell.
Definition: PrimoCell.hpp:251
bool isInContact()
Checks if the cell is in contact with any other cell.
Definition: PrimoCell.hpp:333
Model & model
@ignore
Definition: PrimoCell.hpp:66
double getRadius()
Gets the radius of the cell.
Definition: PrimoCell.hpp:279
void setState(State s)
Sets the state of the cell.
Definition: PrimoCell.hpp:272
Cell * createCell(Type t)
Creates a new cell of a specific type.
Definition: PrimoCell.hpp:152
int getMotherId() const
Gets the mother ID of the cell.
Definition: PrimoCell.hpp:354
World & world
Definition: PrimoCell.hpp:84
void setRadius(const double &_radius)
Sets the radius of the cell.
Definition: PrimoCell.hpp:286
const PreSetCell & getParametersFrom(Type type) const
Gets the parameters for a specific cell type.
Definition: PrimoCell.hpp:363
Model & getModel() const
@ignore
Definition: PrimoCell.hpp:244
void nextState()
@ignore
Definition: PrimoCell.hpp:110
Cell * createCell()
Creates a new cell.
Definition: PrimoCell.hpp:133
void setWorld(World *w)
Checks consistency with the world already injected at construction.
Definition: PrimoCell.hpp:173
void setType(Type t)
Sets the type of the cell and modifies parameters accordingly.
Definition: PrimoCell.hpp:258
bool _alreadyNextState
@ignore
Definition: PrimoCell.hpp:87
this file contains various miscellanious utility functions & helpers *
Vector3D Vec
alias for Vector3D
Definition: utils.hpp:22
iostream cout
Standard output stream.
Definition: std.hpp:301
iostream endl
End-of-line manipulator.
Definition: std.hpp:308