CellModules
PrimoCell.hpp
Go to the documentation of this file.
1
6#ifndef BASEPROJECT_Cell_HPP
7#define BASEPROJECT_Cell_HPP
8
9#include <mecacell/mecacell.h>
10#include "../core/Model.hpp"
11#include "../tools/TimeConvert.hpp"
12#include "../tools/RandomManager.hpp"
13
14/*isigen:eval@utilityDeclarations'''
15 from string import Template
16 from functools import cmp_to_key
17 caseTemplate = Template("""
18 case State::$name : {
19 \t$code
20 \tbreak;
21 }""")
22 def buildConditionsCode(destinations):
23 destinations = sorted(destinations, key=cmp_to_key(lambda a, b: (a["condition"] == '')-(b["condition"] == '')))
24 allCode = ''
25 for i,d in enumerate(destinations):
26 if d["to"] == 'CellInstantiation':
27 action = 'this->init()'
28 elif d["to"] == 'DeadCell':
29 action = 'this->die()'
30 else:
31 action = 'this->state = State::{state}'.format(state=d["to"])
32 if (i == 0) & (d["condition"] != ''): code = 'if({condition}) {action};\n'
33 elif (i == 0) & (d["condition"] == ''): code = '{action};\n'
34 elif d["condition"] == '': code = 'else {action};\n'
35 else: code = 'else if({condition}) {action};\n'
36 allCode += code.format(condition=d["condition"],action=action);
37 return allCode;
38 '''*/
39
40/*isigen:insert@includes'''
41 includes = ''
42 for m,configJson in modulesConfigs.items():
43 if "Body" in configJson:
44 includes += '\n'.join(["#include \"../../{cellModulesPath}/{moduleName}/{cellInclude}\""\
45 .format(cellModulesPath=cellModulesPath,moduleName=m,cellInclude=ci) for ci in configJson["Body"]["cellIncludes"] ])+'\n'
46 print(includes)
47 '''*/
48
57template<template<typename> class B>
58class PrimoCell : public MecaCell::ConnectableCell<PrimoCell<B>, B> {
60public:
61 using Cell = PrimoCell;
63private:
66 Type type;
67 State state;
70 bool _alreadyNextState = false;
72 bool _firstInit = true;
73
74
76 void behave() {
77 switch(this->state) {
78 /*isigen:insert@behave'''
79 behaviour = ''
80 for s in builderData["cell"]["States"]:
81 behaviour += caseTemplate.substitute({'name':s['name'], 'code': s['code'].replace('\n','\n\t')})
82 print(behaviour)
83 '''*/
84 default:
85 {
86 cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
87 break;
88 }
89 }
90 }
91
93 void nextState() {
94 switch(this->state){
95 /*isigen:insert@nextState'''
96 transition = ''
97 for t in builderData["cell"]["Transitions"]:
98 transition += caseTemplate.substitute({'name': t['from'], 'code': buildConditionsCode(t['destinations']).replace('\n','\n\t')})
99 print(transition)
100 '''*/
101 default:
102 {
103 //cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
104 break;
105 }
106 }
107 }
108
117 int idMother = this->id;
118 auto *daughter = new PrimoCell(this);
119 daughter->mother_id = idMother;
120 this->mother_id = idMother;
121 world->addCell(daughter);
122 daughter->setType(this->type);
123 daughter->init();
124 return daughter;
125 }
126
135 Cell * createCell(Type t){
136 int idMother = this->id;
137 auto *daughter = new PrimoCell(this);
138 daughter->mother_id = idMother;
139 this->mother_id = idMother;
140 world->addCell(daughter);
141 daughter->setType(t);
142 daughter->init();
143 return daughter;
144 }
145
146public:
148 int mother_id = -1;
149
155 void setWorld(World* w) {
156 this->world = w;
157 }
158 /*isigen:insert@attributes'''
159 print('\n'.join(["\t{type} {value};".format(type=a['type'], value=a['value']) for a in builderData["cell"]["attributes"] if a['source'] != 'core']))
160 '''*/
161
162
163 /*isigen:insert@functions'''
164 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()]))
165 '''*/
166
167
168 /*isigen:insert@cellModuleFunctions'''
169 print('\n'.join([ '\n'.join([c['code'] for c in v['cellFunctions']]) for v in modulesConfigs.values() if 'cellFunctions' in v]))
170 '''*/
171
179 :Base(v), model(m), type((Type)0)
180 {
181 this->getBody().setPosition(v);
182 }
183
190 :Base(MecaCell::Vec(0.,0.,0.)), model(m), type((Type)0)
191 {
192 this->getBody().setPosition(MecaCell::Vec(0.,0.,0.));
193 }
194
201 :Base(mother->getBody().getPosition()),
202 model(mother->getModel()), type((Type)0)
203 {
204 this->getBody().setPosition(mother->getBody().getPosition());
205 }
206
212 void init() {
213 if(!_firstInit) world->refreshId(this);
214 else _firstInit = false;
215 model->initCell(this);
216 /*isigen:insert@init'''
217 initCode = builderData["cell"]["initializationCode"]
218 if len(builderData["cell"]["initializationTransitions"])>0:
219 destinations = builderData["cell"]["initializationTransitions"][0]["destinations"].copy()
220 print(initCode+'\n'+buildConditionsCode(destinations))
221 '''*/
222 this->_alreadyNextState = true;
223 }
224
226 Model * getModel() const { return model; }
227
233 Type getType() const { return type; }
234
240 void setType(Type t) { type = t; model->initCell(this); }
241
247 State getState() { return state; }
248
254 void setState(State s) { state = s; this->_alreadyNextState = true; }
255
261 double getRadius(){ return this->getBody().getBoundingBoxRadius(); }
262
268 void setRadius(const double &_radius){ this->getBody().setRadius(_radius); }
269
275 void setPosition(const MecaCell::Vec &_pos) { this->getBody().setPosition(_pos); }
276
283 bool isType(Type t) {return this->type == t;}
284
291 bool isInContactWith(Type t){
292 for(auto *c : this->getConnectedCells())
293 if(c->isType(t)) return true;
294 return false;
295 }
296
303 int countNeighborType(Type t){
304 int count = 0;
305 for(auto *c : this->getConnectedCells())
306 if(c->isType(t)) count++;
307 return count;
308 }
309
315 bool isInContact(){ return (this->getConnectedCells().size() > 0); }
316
319 this->_alreadyNextState = false;
320 behave();
321 if(!this->_alreadyNextState) nextState();
322 }
323
329 int getId() const { return this->id; }
330
336 int getMotherId() const { return this->mother_id; }
337
338
345 const PreSetCell& getParametersFrom(Type type) const {
346 return this->model->getPreSetCell(type);
347 }
348};
349
350
351#endif //BASEPROJECT_Cell_HPP
352//'''
Model::PreSetCell PreSetCell
Definition: PrimoCell.hpp:50
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:58
bool isType(Type t)
Checks if the cell is of a specific type.
Definition: PrimoCell.hpp:283
void init()
Initializes the cell.
Definition: PrimoCell.hpp:212
World * world
Definition: PrimoCell.hpp:68
void setPosition(const MecaCell::Vec &_pos)
Sets the position of the cell.
Definition: PrimoCell.hpp:275
PrimoCell(const MecaCell::Vec &v, Model *m)
Constructs a PrimoCell with a position and model.
Definition: PrimoCell.hpp:178
State state
Definition: PrimoCell.hpp:67
int countNeighborType(Type t)
Counts the number of neighboring cells of a specific type.
Definition: PrimoCell.hpp:303
bool isInContactWith(Type t)
Checks if the cell is in contact with a cell of a specific type.
Definition: PrimoCell.hpp:291
void behave()
@ignore
Definition: PrimoCell.hpp:76
PrimoCell(PrimoCell< B > *mother)
Constructs a PrimoCell from a mother cell.
Definition: PrimoCell.hpp:200
void updateBehavior()
@ignore
Definition: PrimoCell.hpp:318
State getState()
Gets the state of the cell.
Definition: PrimoCell.hpp:247
bool _firstInit
@ignore
Definition: PrimoCell.hpp:72
int getId() const
Gets the ID of the cell.
Definition: PrimoCell.hpp:329
int mother_id
@ignore
Definition: PrimoCell.hpp:148
Type type
Definition: PrimoCell.hpp:66
Type getType() const
Gets the type of the cell.
Definition: PrimoCell.hpp:233
Model * getModel() const
@ignore
Definition: PrimoCell.hpp:226
PrimoCell(Model *m)
Constructs a PrimoCell with a model.
Definition: PrimoCell.hpp:189
bool isInContact()
Checks if the cell is in contact with any other cell.
Definition: PrimoCell.hpp:315
double getRadius()
Gets the radius of the cell.
Definition: PrimoCell.hpp:261
void setState(State s)
Sets the state of the cell.
Definition: PrimoCell.hpp:254
Cell * createCell(Type t)
Creates a new cell of a specific type.
Definition: PrimoCell.hpp:135
int getMotherId() const
Gets the mother ID of the cell.
Definition: PrimoCell.hpp:336
void setRadius(const double &_radius)
Sets the radius of the cell.
Definition: PrimoCell.hpp:268
const PreSetCell & getParametersFrom(Type type) const
Gets the parameters for a specific cell type.
Definition: PrimoCell.hpp:345
void nextState()
@ignore
Definition: PrimoCell.hpp:93
Cell * createCell()
Creates a new cell.
Definition: PrimoCell.hpp:116
void setWorld(World *w)
Sets the world for the cell.
Definition: PrimoCell.hpp:155
void setType(Type t)
Sets the type of the cell and modifies parameters accordingly.
Definition: PrimoCell.hpp:240
Model * model
@ignore
Definition: PrimoCell.hpp:65
bool _alreadyNextState
@ignore
Definition: PrimoCell.hpp:70
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