Skip to content

Commit d79f834

Browse files
committed
gamestate: Add activity node type for enum handling.
1 parent 598a58b commit d79f834

File tree

6 files changed

+179
-9
lines changed

6 files changed

+179
-9
lines changed

doc/code/game_simulation/activity.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ you can use available [BPMN tools](https://bpmn.io/) to draw activity node graph
4848
## Node Types
4949

5050

51-
| Type | Inputs | Outputs | Description |
52-
| ---------------- | ------ | ------- | ------------------------- |
53-
| `START` | 0 | 1 | Start of activity |
54-
| `END` | 1 | 0 | End of activity |
55-
| `TASK_SYSTEM` | 1 | 1 | Run built-in system |
56-
| `TASK_CUSTOM` | 1 | 1 | Run custom function |
57-
| `XOR_EVENT_GATE` | 1 | 1+ | Wait for event and branch |
58-
| `XOR_GATE` | 1 | 1+ | Branch on condition |
51+
| Type | Inputs | Outputs | Description |
52+
| ----------------- | ------ | ------- | --------------------------- |
53+
| `START` | 0 | 1 | Start of activity |
54+
| `END` | 1 | 0 | End of activity |
55+
| `TASK_SYSTEM` | 1 | 1 | Run built-in system |
56+
| `TASK_CUSTOM` | 1 | 1 | Run custom function |
57+
| `XOR_EVENT_GATE` | 1 | 1+ | Wait for event and branch |
58+
| `XOR_GATE` | 1 | 1+ | Branch on condition |
59+
| `XOR_SWITCH_GATE` | 1 | 1+ | Branch on enum value lookup |

libopenage/gamestate/activity/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_sources(libopenage
99
types.cpp
1010
xor_event_gate.cpp
1111
xor_gate.cpp
12+
xor_switch_gate.cpp
1213
)
1314

1415
add_subdirectory("event")

libopenage/gamestate/activity/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ enum class node_t {
1313
END,
1414
XOR_EVENT_GATE,
1515
XOR_GATE,
16+
XOR_SWITCH_GATE,
1617
TASK_CUSTOM,
1718
TASK_SYSTEM,
1819
};

libopenage/gamestate/activity/xor_gate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace activity {
2424
/**
2525
* Function that determines if an output node is chosen.
2626
*
27-
* @param time Current game time.
27+
* @param time Current simulation time.
2828
* @param entity Entity that is executing the activity.
2929
*
3030
* @return true if the output node is chosen, false otherwise.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
2+
3+
#include "xor_switch_gate.h"
4+
5+
6+
namespace openage::gamestate::activity {
7+
8+
} // namespace openage::gamestate::activity
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright 2024-2024 the openage authors. See copying.md for legal info.
2+
3+
#pragma once
4+
5+
#include <concepts>
6+
#include <functional>
7+
#include <memory>
8+
#include <string>
9+
#include <unordered_map>
10+
#include <vector>
11+
12+
#include "gamestate/activity/node.h"
13+
#include "gamestate/activity/types.h"
14+
#include "time/time.h"
15+
16+
17+
namespace openage::gamestate {
18+
class GameEntity;
19+
20+
namespace activity {
21+
22+
/**
23+
* Concept for XOR switch gate conditions.
24+
*/
25+
template <typename T>
26+
concept EnumLike = std::is_enum_v<T>;
27+
28+
29+
/**
30+
* Chooses one of its output nodes based on enum values.
31+
*
32+
* In comparison to the XOR gate, this node type does not assign individual
33+
* conditions to each node. Instead, it extracts an enum value from the game
34+
* entity and uses that as a key for retriving the node from a lookup table.
35+
* Thus, the behavior is more similar to a \p switch statement.
36+
*/
37+
template <EnumLike E>
38+
class XorSwitchGate : public Node {
39+
public:
40+
/**
41+
* Function that retrieves a lookup key for the lookup table from
42+
* the current state.
43+
*
44+
* @param time Current simulation time.
45+
* @param entity Entity that is executing the activity.
46+
*
47+
* @return Lookup key.
48+
*/
49+
using lookup_function_t = std::function<E(const time::time_t &,
50+
const std::shared_ptr<gamestate::GameEntity> &)>;
51+
52+
/**
53+
* Lookup table that maps lookup keys to output node IDs.
54+
*/
55+
using lookup_table_t = std::unordered_map<E, std::shared_ptr<Node>>;
56+
57+
/**
58+
* Creates a new XOR switch gate node.
59+
*
60+
* @param id Unique identifier of the node.
61+
* @param label Human-readable label of the node (optional).
62+
*/
63+
XorSwitchGate(node_id_t id,
64+
node_label_t label = "ExclusiveSwitchGateway") :
65+
Node{id, label} {}
66+
67+
/**
68+
* Creates a new XOR switch gate node.
69+
*
70+
* @param id Unique identifier of the node.
71+
* @param label Human-readable label of the node.
72+
* @param lookup_func Function that looks up the key to the lookup table.
73+
* @param lookup_table Initial lookup table that maps lookup keys to output node IDs.
74+
* @param default_node Default output node. Chosen if no lookup entry is defined.
75+
*/
76+
XorSwitchGate(node_id_t id,
77+
node_label_t label,
78+
const lookup_function_t &lookup_func,
79+
const lookup_table_t &lookup_table,
80+
const std::shared_ptr<Node> &default_node) :
81+
Node{id, label},
82+
lookup_func{lookup_func},
83+
lookup_table{lookup_table},
84+
default_node{default_node} {}
85+
86+
virtual ~XorSwitchGate() = default;
87+
88+
inline node_t get_type() const override {
89+
return node_t::XOR_SWITCH_GATE;
90+
}
91+
92+
/**
93+
* Set the output node for a given enumeration value.
94+
*
95+
* @param output Output node.
96+
* @param enum_value Enumeration value.
97+
*/
98+
void set_output(const std::shared_ptr<Node> &output,
99+
const E enum_value) {
100+
this->lookup_table[enum_value] = output;
101+
}
102+
103+
/**
104+
* Get the lookup function for the output nodes.
105+
*
106+
* @return Lookup function.
107+
*/
108+
const lookup_function_t &get_lookup_func() const {
109+
return this->lookup_func;
110+
}
111+
112+
/**
113+
* Get the lookup table for the output nodes.
114+
*
115+
* @return Lookup table.
116+
*/
117+
const lookup_table_t &get_lookup_table() const {
118+
return this->lookup_table;
119+
}
120+
121+
/**
122+
* Get the default output node.
123+
*
124+
* @return Default output node.
125+
*/
126+
const std::shared_ptr<Node> &get_default() const {
127+
return this->default_node;
128+
}
129+
130+
/**
131+
* Set the the default output node.
132+
*
133+
* This node is chosen if no condition is true.
134+
*
135+
* @param node Default output node.
136+
*/
137+
void set_default(const std::shared_ptr<Node> &node) {
138+
this->default_node = node;
139+
}
140+
141+
private:
142+
/**
143+
* Determines the lookup key for the lookup table from the current state.
144+
*/
145+
lookup_function_t lookup_func;
146+
147+
/**
148+
* Maps lookup keys to output nodes.
149+
*/
150+
lookup_table_t lookup_table;
151+
152+
/**
153+
* Default output node. Chosen if no lookup entry is defined.
154+
*/
155+
std::shared_ptr<Node> default_node;
156+
};
157+
158+
} // namespace activity
159+
} // namespace openage::gamestate

0 commit comments

Comments
 (0)