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
73 Type type;
74
81 State state;
82
83 World* world; /* The world manages cell registration, IDs refresh, and plugins. */
84
86 bool _alreadyNextState = false;
88 bool _firstInit = true;
89
90
92 void behave() {
93 switch(this->state) {
94 /*isigen:insert@behave'''
95 behaviour = ''
96 for s in builderData["cell"]["States"]:
97 behaviour += caseTemplate.substitute({'name':s['name'], 'code': s['code'].replace('\n','\n\t')})
98 print(behaviour)
99 '''*/
100 default:
101 {
102 cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
103 break;
104 }
105 }
106 }
107
109 void nextState() {
110 switch(this->state){
111 /*isigen:insert@nextState'''
112 transition = ''
113 for t in builderData["cell"]["Transitions"]:
114 transition += caseTemplate.substitute({'name': t['from'], 'code': buildConditionsCode(t['destinations']).replace('\n','\n\t')})
115 print(transition)
116 '''*/
117 default:
118 {
119 //cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
120 break;
121 }
122 }
123 }
124
133 int idMother = this->id;
134 auto *daughter = new PrimoCell(this);
135 daughter->mother_id = idMother;
136 this->mother_id = idMother;
137 world->addCell(daughter);
138 daughter->setType(this->type);
139 daughter->init();
140 return daughter;
141 }
142
151 Cell * createCell(Type t){
152 int idMother = this->id;
153 auto *daughter = new PrimoCell(this);
154 daughter->mother_id = idMother;
155 this->mother_id = idMother;
156 world->addCell(daughter);
157 daughter->setType(t);
158 daughter->init();
159 return daughter;
160 }
161
162public:
164 int mother_id = -1;
165
172 void setWorld(World* w) {
173 this->world = w;
174 }
175 /*isigen:insert@attributes'''
176 print('\n'.join(["\t{type} {value};".format(type=a['type'], value=a['value']) for a in builderData["cell"]["attributes"] if a['source'] != 'core']))
177 '''*/
178
179
180 /*isigen:insert@functions'''
181 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()]))
182 '''*/
183
184
185 /*isigen:insert@cellModuleFunctions'''
186 print('\n'.join([ '\n'.join([c['code'] for c in v['cellFunctions']]) for v in modulesConfigs.values() if 'cellFunctions' in v]))
187 '''*/
188
196 :Base(v), model(m), type((Type)0)
197 {
198 this->getBody().setPosition(v);
199 }
200
207 :Base(MecaCell::Vec(0.,0.,0.)), model(m), type((Type)0)
208 {
209 this->getBody().setPosition(MecaCell::Vec(0.,0.,0.));
210 }
211
218 :Base(mother->getBody().getPosition()),
219 model(mother->getModel()), type((Type)0)
220 {
221 this->getBody().setPosition(mother->getBody().getPosition());
222 }
223
229 void init() {
230 if(!_firstInit) world->refreshId(this);
231 else _firstInit = false;
232 model->initCell(this);
233 /*isigen:insert@init'''
234 initCode = builderData["cell"]["initializationCode"]
235 if len(builderData["cell"]["initializationTransitions"])>0:
236 destinations = builderData["cell"]["initializationTransitions"][0]["destinations"].copy()
237 print(initCode+'\n'+buildConditionsCode(destinations))
238 '''*/
239 this->_alreadyNextState = true;
240 }
241
243 Model * getModel() const { return model; }
244
250 Type getType() const { return type; }
251
257 void setType(Type t) { type = t; model->initCell(this); }
258
264 State getState() { return state; }
265
271 void setState(State s) { state = s; this->_alreadyNextState = true; }
272
278 double getRadius(){ return this->getBody().getBoundingBoxRadius(); }
279
285 void setRadius(const double &_radius){ this->getBody().setRadius(_radius); }
286
292 void setPosition(const MecaCell::Vec &_pos) { this->getBody().setPosition(_pos); }
293
300 bool isType(Type t) {return this->type == t;}
301
308 bool isInContactWith(Type t){
309 for(auto *c : this->getConnectedCells())
310 if(c->isType(t)) return true;
311 return false;
312 }
313
320 int countNeighborType(Type t){
321 int count = 0;
322 for(auto *c : this->getConnectedCells())
323 if(c->isType(t)) count++;
324 return count;
325 }
326
332 bool isInContact(){ return (this->getConnectedCells().size() > 0); }
333
336 this->_alreadyNextState = false;
337 behave();
338 if(!this->_alreadyNextState) nextState();
339 }
340
346 int getId() const { return this->id; }
347
353 int getMotherId() const { return this->mother_id; }
354
355
362 const PreSetCell& getParametersFrom(Type type) const {
363 return this->model->getPreSetCell(type);
364 }
365};
366
367
368#endif //BASEPROJECT_Cell_HPP
369//'''
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:300
void init()
Initializes the cell.
Definition: PrimoCell.hpp:229
World * world
Definition: PrimoCell.hpp:83
void setPosition(const MecaCell::Vec &_pos)
Sets the position of the cell.
Definition: PrimoCell.hpp:292
PrimoCell(const MecaCell::Vec &v, Model *m)
Constructs a PrimoCell with a position and model.
Definition: PrimoCell.hpp:195
State state
Current state of the cell's internal state machine.
Definition: PrimoCell.hpp:81
int countNeighborType(Type t)
Counts the number of neighboring cells of a specific type.
Definition: PrimoCell.hpp:320
bool isInContactWith(Type t)
Checks if the cell is in contact with a cell of a specific type.
Definition: PrimoCell.hpp:308
void behave()
@ignore
Definition: PrimoCell.hpp:92
PrimoCell(PrimoCell< B > *mother)
Constructs a PrimoCell from a mother cell.
Definition: PrimoCell.hpp:217
void updateBehavior()
@ignore
Definition: PrimoCell.hpp:335
State getState()
Gets the state of the cell.
Definition: PrimoCell.hpp:264
bool _firstInit
@ignore
Definition: PrimoCell.hpp:88
int getId() const
Gets the ID of the cell.
Definition: PrimoCell.hpp:346
int mother_id
@ignore
Definition: PrimoCell.hpp:164
Type type
Current type of the cell.
Definition: PrimoCell.hpp:73
Type getType() const
Gets the type of the cell.
Definition: PrimoCell.hpp:250
Model * getModel() const
@ignore
Definition: PrimoCell.hpp:243
PrimoCell(Model *m)
Constructs a PrimoCell with a model.
Definition: PrimoCell.hpp:206
bool isInContact()
Checks if the cell is in contact with any other cell.
Definition: PrimoCell.hpp:332
double getRadius()
Gets the radius of the cell.
Definition: PrimoCell.hpp:278
void setState(State s)
Sets the state of the cell.
Definition: PrimoCell.hpp:271
Cell * createCell(Type t)
Creates a new cell of a specific type.
Definition: PrimoCell.hpp:151
int getMotherId() const
Gets the mother ID of the cell.
Definition: PrimoCell.hpp:353
void setRadius(const double &_radius)
Sets the radius of the cell.
Definition: PrimoCell.hpp:285
const PreSetCell & getParametersFrom(Type type) const
Gets the parameters for a specific cell type.
Definition: PrimoCell.hpp:362
void nextState()
@ignore
Definition: PrimoCell.hpp:109
Cell * createCell()
Creates a new cell.
Definition: PrimoCell.hpp:132
void setWorld(World *w)
Sets the world for the cell.
Definition: PrimoCell.hpp:172
void setType(Type t)
Sets the type of the cell and modifies parameters accordingly.
Definition: PrimoCell.hpp:257
Model * model
@ignore
Definition: PrimoCell.hpp:65
bool _alreadyNextState
@ignore
Definition: PrimoCell.hpp:86
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