-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
153 lines (127 loc) · 5.48 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// Created by Bittner on 05.12.2019.
//
#include <iostream>
#include <polypropylene/log/Assert.h>
#include "polypropylene/Polypropylene.h"
#include "polypropylene/memory/PropertyPool.h"
#ifdef PAX_WITH_JSON
#include "polypropylene/serialisation/json/JsonLoader.h"
#include "polypropylene/serialisation/json/property/JsonEntityPrefabLoader.h"
#endif
#include "Pizza.h"
#include "toppings/Mozzarella.h"
#include "toppings/Champignon.h"
/**
* Each type of property has to be registered before it can be used in prefabs.
* A property is registered by exactly that name given to PAX_PROPERTY_REGISTER.
* For instance,
* \code{.cpp}
* PAX_PROPERTY_REGISTER(PAX::Examples::Mozzarella)
* \endcode
* registers Mozzarella as "PAX::Examples::Mozzarella",
* whereas
* \code{.cpp}
* using namespace PAX::Examples;
* PAX_PROPERTY_REGISTER(Mozzarella)
* \endcode
* registers Mozzarella as "Mozzarella".
* The registered name is used for identifiying property types upon deserialisation, e.g., in json files.
* Custom names can be specified with PAX_PROPERTY_REGISTER_AS(propertyType, strName)
*/
void registerPropertyTypes() {
PAX_PROPERTY_REGISTER(PAX::Examples::Mozzarella);
PAX_PROPERTY_REGISTER(PAX::Examples::Champignon);
PAX_PROPERTY_REGISTER(PAX::Examples::TomatoSauce);
}
int main(int argc, char** argv) {
using namespace PAX;
using namespace PAX::Examples;
Log::Instance().currentLevel = Log::Level::Info;
PAX_LOG(Log::Level::Info, "Running Pizza Example");
/// INITIAL SETUP
registerPropertyTypes();
#ifdef PAX_WITH_JSON
using namespace PAX::Json;
JsonFieldWriterRegister writerRegister; /// contains parsers from nlohmann::json to fields
JsonEntityPrefabLoader<Pizza> prefabLoader; /// loads json files from disk to EntityPrefab<Pizza>
JsonEntityPrefab<Pizza>::initialize(writerRegister);
#endif
/// EXAMPLE
/// Create a property pool for champignons.
/// The pool will hold all allocated instances of champignons.
/// It will do so by communicating with the AllocationService of Pizza.
/// It's usage is optional.
PropertyPool<Champignon> champignonPool;
std::cout << "How hot do you like your pizza (in scoville)?\n";
#ifdef PAX_WITH_JSON
std::string hotness;
std::cin >> hotness;
JsonEntityPrefab<Pizza> prefab = prefabLoader.load("res/pizza/funghi.json");
Pizza * pizzaFunghi = prefab.create({{"hotness", hotness}});
#else
int hotness;
std::cin >> hotness;
Pizza * pizzaFunghi = new Pizza();
/// Either allocate properties where and how you like ...
TomatoSauce tomatoSauce(hotness);
Mozzarella * mozzarella = new Mozzarella();
/// ... or (optionally) use the allocation service.
/// Using the allocation service has the following benefits:
/// - PropertyPools only know the properties allocated by the allocation service.
/// Manually allocated properties as done here won't be recognised.
/// - Entities take ownership of properties added to them. Deleting an entity also deletes
/// all contained properties but only those that were allocated with the allocation service.
/// Thus, beware of memory leaks as customly allocated properties have to be deleted manually!
/// PropertyFactories and Prefabs always use the allocation service.
Champignon * champignon = pax_new(Champignon)();
/// Add TomatoSauce first because Cheeses (e.g., Mozzarella) depend on it.
pizzaFunghi->add(&tomatoSauce);
pizzaFunghi->add(mozzarella);
pizzaFunghi->add(champignon);
#endif
pizzaFunghi->yummy();
pizzaFunghi->bake();
/// Let's take a look at all allocated champignons.
PAX_LOG(Log::Level::Info, "List of allocated champignons:");
for (Champignon * c : champignonPool) {
PAX_LOG(Log::Level::Info, " " << c);
assert(c->getOwner() == pizzaFunghi);
}
/// example for property access via templates
{
const std::vector<Cheese *> & cheeses = pizzaFunghi->get<Cheese>();
Mozzarella * m = pizzaFunghi->get<Mozzarella>();
}
/// example for property access without templates
{
/// use the get function according to properties multiplicity if you know it ...
const std::vector<Topping *> & cheeses = pizzaFunghi->getMultiple(paxtypeid(Cheese));
Mozzarella * m = dynamic_cast<Mozzarella*>(pizzaFunghi->getSingle(paxtypeid(Mozzarella)));
/// ... or if you do not:
std::vector<Topping *> mozzarellas = pizzaFunghi->get(paxtypeid(Mozzarella));
}
#ifdef PAX_WITH_JSON
/// Export pizzaFunghi as json.
{ /// Open a scope here to remove the temporary prefabs we create.
Path outPath = "res/pizza/out/funghiWith" + hotness + "scoville.json";
PrototypeEntityPrefab<Pizza> prefabToSerialise = pizzaFunghi->toPrefab();
JsonEntityPrefab<Pizza> asJson = JsonEntityPrefab<Pizza>::FromPrefab(prefabToSerialise);
prefabLoader.write(asJson, outPath);
PAX_LOG(Log::Level::Info, "Your pizza was delivered to '" << outPath << "'.");
}
#endif
// Actually, I don't want mushrooms at all ...
{
Champignon *mushroom = pizzaFunghi->removeAll<Champignon>();
PAX_LOG(Log::Level::Info, "Why was it delivered with champignons?! Removing and deleting " << mushroom);
pax_delete(mushroom);
}
#ifdef PAX_WITH_JSON
/// Entities created with prefabs (or with the allocation service) have to be deleted via the allocation service.
PAX_ASSERT(pax_delete(pizzaFunghi));
#else
delete pizzaFunghi;
#endif
return 0;
}