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 action = 'this->state = State::{state}'.format(state=d["to"]) if d['to'] != 'DeadCell' else 'this->die()'
27 if (i == 0) & (d["condition"] != ''): code = 'if({condition}) {action};\n'
28 elif (i == 0) & (d["condition"] == ''): code = '{action};\n'
29 elif d["condition"] == '': code = 'else {action};\n'
30 else: code = 'else if({condition}) {action};\n'
31 allCode += code.format(condition=d["condition"],action=action);
32 return allCode;
33 '''*/
34
35/*isigen:insert@includes'''
36 includes = ''
37 for m,configJson in modulesConfigs.items():
38 if "Body" in configJson:
39 includes += '\n'.join(["#include \"../../{cellModulesPath}/{moduleName}/{cellInclude}\""\
40 .format(cellModulesPath=cellModulesPath,moduleName=m,cellInclude=ci) for ci in configJson["Body"]["cellIncludes"] ])+'\n'
41 print(includes)
42 '''*/
43
45
52template<template<typename> class B>
53class PrimoCell : public MecaCell::ConnectableCell<PrimoCell<B>, B> {
55public:
56 using Cell = PrimoCell;
58private:
60 static inline int id_count = 0;
63 Type type;
64 State state;
67 bool _alreadyNextState = false;
68
69
71 void behave() {
72 switch(this->state) {
73 /*isigen:insert@behave'''
74 behaviour = ''
75 for s in builderData["cell"]["States"]:
76 behaviour += caseTemplate.substitute({'name':s['name'], 'code': s['code'].replace('\n','\n\t')})
77 print(behaviour)
78 '''*/
79 default:
80 {
81 cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
82 break;
83 }
84 }
85 }
86
88 void nextState() {
89 switch(this->state){
90 /*isigen:insert@nextState'''
91 transition = ''
92 for t in builderData["cell"]["Transitions"]:
93 transition += caseTemplate.substitute({'name': t['from'], 'code': buildConditionsCode(t['destinations']).replace('\n','\n\t')})
94 print(transition)
95 '''*/
96 default:
97 {
98 //cout << "UNSPECIFIED CELL STATE : " << static_cast<unsigned int>(this->state) << endl;
99 break;
100 }
101 }
102 }
103
112 int idMother = this->cell_id;
114 auto *daughter = new PrimoCell(this);
115 daughter->mother_id = idMother;
116 this->mother_id = idMother;
117 world->addCell(daughter);
118 daughter->setType(this->type);
119 daughter->init();
120 return daughter;
121 }
122
131 Cell * createCell(Type t){
132 int idMother = this->cell_id;
134 auto *daughter = new PrimoCell(this);
135 daughter->mother_id = idMother;
136 this->mother_id = idMother;
137 world->addCell(daughter);
138 daughter->setType(t);
139 daughter->init();
140 return daughter;
141 }
142
143public:
145 int cell_id = 0;
147 int mother_id = -1;
148
154 void setWorld(World* w) {
155 this->world = w;
156 }
157 /*isigen:insert@attributes'''
158 print('\n'.join(["\t{type} {value};".format(type=a['type'], value=a['value']) for a in builderData["cell"]["attributes"] if a['source'] != 'core']))
159 '''*/
160
161
162 /*isigen:insert@functions'''
163 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()]))
164 '''*/
165
166
167 /*isigen:insert@cellModuleFunctions'''
168 print('\n'.join([ '\n'.join([c['code'] for c in v['cellFunctions']]) for v in modulesConfigs.values() if 'cellFunctions' in v]))
169 '''*/
170
178 :Base(v), model(m), type((Type)0)
179 {
180 this->getBody().setPosition(v);
181 this->cell_id = PrimoCell::id_count++;
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 this->cell_id = PrimoCell::id_count++;
194 }
195
202 :Base(mother->getBody().getPosition()),
203 model(mother->getModel()), type((Type)0)
204 {
205 this->getBody().setPosition(mother->getBody().getPosition());
206 this->cell_id = PrimoCell::id_count++;
207 }
208
214 void init() {
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->cell_id; }
330
336 int getMotherId() const { return this->mother_id; }
337};
338
339
340#endif //BASEPROJECT_Cell_HPP
341//'''
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:25
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:219
Definition: Model.hpp:41
void initCell(Cell *c)
Definition: Model.hpp:76
Represents a cell in the simulation.
Definition: PrimoCell.hpp:53
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:214
World * world
Definition: PrimoCell.hpp:65
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:177
State state
Definition: PrimoCell.hpp:64
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:71
PrimoCell(PrimoCell< B > *mother)
Constructs a PrimoCell from a mother cell.
Definition: PrimoCell.hpp:201
void updateBehavior()
@ignore
Definition: PrimoCell.hpp:318
State getState()
Gets the state of the cell.
Definition: PrimoCell.hpp:247
int getId() const
Gets the ID of the cell.
Definition: PrimoCell.hpp:329
int mother_id
@ignore
Definition: PrimoCell.hpp:147
Type type
Definition: PrimoCell.hpp:63
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
static int id_count
@ignore
Definition: PrimoCell.hpp:60
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:131
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
void nextState()
@ignore
Definition: PrimoCell.hpp:88
Cell * createCell()
Creates a new cell.
Definition: PrimoCell.hpp:111
void setWorld(World *w)
Sets the world for the cell.
Definition: PrimoCell.hpp:154
void setType(Type t)
Sets the type of the cell and modifies parameters accordingly.
Definition: PrimoCell.hpp:240
Model * model
@ignore
Definition: PrimoCell.hpp:62
int cell_id
@ignore
Definition: PrimoCell.hpp:145
bool _alreadyNextState
@ignore
Definition: PrimoCell.hpp:67
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:267
iostream endl
End-of-line manipulator.
Definition: std.hpp:274