Skip to content

Commit

Permalink
gamestate: Add activity node type for enum handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Nov 4, 2024
1 parent 598a58b commit d79f834
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 9 deletions.
17 changes: 9 additions & 8 deletions doc/code/game_simulation/activity.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ you can use available [BPMN tools](https://bpmn.io/) to draw activity node graph
## Node Types


| Type | Inputs | Outputs | Description |
| ---------------- | ------ | ------- | ------------------------- |
| `START` | 0 | 1 | Start of activity |
| `END` | 1 | 0 | End of activity |
| `TASK_SYSTEM` | 1 | 1 | Run built-in system |
| `TASK_CUSTOM` | 1 | 1 | Run custom function |
| `XOR_EVENT_GATE` | 1 | 1+ | Wait for event and branch |
| `XOR_GATE` | 1 | 1+ | Branch on condition |
| Type | Inputs | Outputs | Description |
| ----------------- | ------ | ------- | --------------------------- |
| `START` | 0 | 1 | Start of activity |
| `END` | 1 | 0 | End of activity |
| `TASK_SYSTEM` | 1 | 1 | Run built-in system |
| `TASK_CUSTOM` | 1 | 1 | Run custom function |
| `XOR_EVENT_GATE` | 1 | 1+ | Wait for event and branch |
| `XOR_GATE` | 1 | 1+ | Branch on condition |
| `XOR_SWITCH_GATE` | 1 | 1+ | Branch on enum value lookup |
1 change: 1 addition & 0 deletions libopenage/gamestate/activity/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_sources(libopenage
types.cpp
xor_event_gate.cpp
xor_gate.cpp
xor_switch_gate.cpp
)

add_subdirectory("event")
Expand Down
1 change: 1 addition & 0 deletions libopenage/gamestate/activity/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum class node_t {
END,
XOR_EVENT_GATE,
XOR_GATE,
XOR_SWITCH_GATE,
TASK_CUSTOM,
TASK_SYSTEM,
};
Expand Down
2 changes: 1 addition & 1 deletion libopenage/gamestate/activity/xor_gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace activity {
/**
* Function that determines if an output node is chosen.
*
* @param time Current game time.
* @param time Current simulation time.
* @param entity Entity that is executing the activity.
*
* @return true if the output node is chosen, false otherwise.
Expand Down
8 changes: 8 additions & 0 deletions libopenage/gamestate/activity/xor_switch_gate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#include "xor_switch_gate.h"


namespace openage::gamestate::activity {

} // namespace openage::gamestate::activity
159 changes: 159 additions & 0 deletions libopenage/gamestate/activity/xor_switch_gate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#pragma once

#include <concepts>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "gamestate/activity/node.h"
#include "gamestate/activity/types.h"
#include "time/time.h"


namespace openage::gamestate {
class GameEntity;

namespace activity {

/**
* Concept for XOR switch gate conditions.
*/
template <typename T>
concept EnumLike = std::is_enum_v<T>;


/**
* Chooses one of its output nodes based on enum values.
*
* In comparison to the XOR gate, this node type does not assign individual
* conditions to each node. Instead, it extracts an enum value from the game
* entity and uses that as a key for retriving the node from a lookup table.
* Thus, the behavior is more similar to a \p switch statement.
*/
template <EnumLike E>
class XorSwitchGate : public Node {
public:
/**
* Function that retrieves a lookup key for the lookup table from
* the current state.
*
* @param time Current simulation time.
* @param entity Entity that is executing the activity.
*
* @return Lookup key.
*/
using lookup_function_t = std::function<E(const time::time_t &,
const std::shared_ptr<gamestate::GameEntity> &)>;

/**
* Lookup table that maps lookup keys to output node IDs.
*/
using lookup_table_t = std::unordered_map<E, std::shared_ptr<Node>>;

/**
* Creates a new XOR switch gate node.
*
* @param id Unique identifier of the node.
* @param label Human-readable label of the node (optional).
*/
XorSwitchGate(node_id_t id,
node_label_t label = "ExclusiveSwitchGateway") :
Node{id, label} {}

/**
* Creates a new XOR switch gate node.
*
* @param id Unique identifier of the node.
* @param label Human-readable label of the node.
* @param lookup_func Function that looks up the key to the lookup table.
* @param lookup_table Initial lookup table that maps lookup keys to output node IDs.
* @param default_node Default output node. Chosen if no lookup entry is defined.
*/
XorSwitchGate(node_id_t id,
node_label_t label,
const lookup_function_t &lookup_func,
const lookup_table_t &lookup_table,
const std::shared_ptr<Node> &default_node) :
Node{id, label},
lookup_func{lookup_func},
lookup_table{lookup_table},
default_node{default_node} {}

virtual ~XorSwitchGate() = default;

inline node_t get_type() const override {
return node_t::XOR_SWITCH_GATE;
}

/**
* Set the output node for a given enumeration value.
*
* @param output Output node.
* @param enum_value Enumeration value.
*/
void set_output(const std::shared_ptr<Node> &output,
const E enum_value) {
this->lookup_table[enum_value] = output;
}

/**
* Get the lookup function for the output nodes.
*
* @return Lookup function.
*/
const lookup_function_t &get_lookup_func() const {
return this->lookup_func;
}

/**
* Get the lookup table for the output nodes.
*
* @return Lookup table.
*/
const lookup_table_t &get_lookup_table() const {
return this->lookup_table;
}

/**
* Get the default output node.
*
* @return Default output node.
*/
const std::shared_ptr<Node> &get_default() const {
return this->default_node;
}

/**
* Set the the default output node.
*
* This node is chosen if no condition is true.
*
* @param node Default output node.
*/
void set_default(const std::shared_ptr<Node> &node) {
this->default_node = node;
}

private:
/**
* Determines the lookup key for the lookup table from the current state.
*/
lookup_function_t lookup_func;

/**
* Maps lookup keys to output nodes.
*/
lookup_table_t lookup_table;

/**
* Default output node. Chosen if no lookup entry is defined.
*/
std::shared_ptr<Node> default_node;
};

} // namespace activity
} // namespace openage::gamestate

0 comments on commit d79f834

Please sign in to comment.