Browse Source

Move behavior tree to new ai namespace, move entity behavior tree to ecs namespace

master
C. J. Howard 3 years ago
parent
commit
7add3f54cf
8 changed files with 89 additions and 58 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +28
    -0
      src/ai/ai.hpp
  3. +9
    -6
      src/ai/behavior-tree.hpp
  4. +1
    -1
      src/ecs/components/behavior-component.hpp
  5. +3
    -4
      src/ecs/ebt.cpp
  6. +23
    -23
      src/ecs/ebt.hpp
  7. +22
    -22
      src/resources/behavior-tree-loader.cpp
  8. +2
    -2
      src/resources/entity-archetype-loader.cpp

+ 1
- 0
CMakeLists.txt View File

@ -14,6 +14,7 @@ find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2-static SDL2::SDL2main CONFIG)
find_package(OpenAL REQUIRED CONFIG) find_package(OpenAL REQUIRED CONFIG)
find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib") find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib")
# Determine dependencies # Determine dependencies
set(STATIC_LIBS set(STATIC_LIBS
dr_wav dr_wav

+ 28
- 0
src/ai/ai.hpp View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_AI_HPP
#define ANTKEEPER_AI_HPP
/// Artificial intelligence (AI)
namespace ai {}
#include "behavior-tree.hpp"
#endif // ANTKEEPER_AI_HPP

src/game/behavior/behavior-tree.hpp → src/ai/behavior-tree.hpp View File

@ -17,13 +17,16 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ANTKEEPER_BEHAVIOR_TREE_HPP
#define ANTKEEPER_BEHAVIOR_TREE_HPP
#ifndef ANTKEEPER_AI_BEHAVIOR_TREE_HPP
#define ANTKEEPER_AI_BEHAVIOR_TREE_HPP
#include <functional> #include <functional>
#include <list> #include <list>
namespace behavior_tree {
namespace ai {
/// Behavior tree (BT)
namespace bt {
/// Behavior tree node return status enumerations. /// Behavior tree node return status enumerations.
enum class status enum class status
@ -187,7 +190,7 @@ status selector::execute(context_type& context) const
return status::failure; return status::failure;
} }
} // namespace behavior_tree
#endif // ANTKEEPER_BEHAVIOR_TREE_HPP
} // namespace bt
} // namespace ai
#endif // ANTKEEPER_AI_BEHAVIOR_TREE_HPP

+ 1
- 1
src/ecs/components/behavior-component.hpp View File

@ -20,7 +20,7 @@
#ifndef ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP #ifndef ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP
#define ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP #define ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP
#include "game/behavior/ebt.hpp"
#include "ecs/ebt.hpp"
namespace ecs { namespace ecs {

src/game/behavior/ebt.cpp → src/ecs/ebt.cpp View File

@ -17,12 +17,11 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "game/behavior/ebt.hpp"
#include "ecs/ebt.hpp"
#include "ecs/components/transform-component.hpp" #include "ecs/components/transform-component.hpp"
#include <iostream> #include <iostream>
using namespace ecs;
namespace ecs {
namespace ebt { namespace ebt {
status print(context& context, const std::string& text) status print(context& context, const std::string& text)
@ -51,4 +50,4 @@ bool is_carrying_food(const context& context)
} }
} // namespace ebt } // namespace ebt
} // namespace ecs

src/game/behavior/ebt.hpp → src/ecs/ebt.hpp View File

@ -17,17 +17,16 @@
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ANTKEEPER_EBT_HPP
#define ANTKEEPER_EBT_HPP
#ifndef ANTKEEPER_ECS_EBT_HPP
#define ANTKEEPER_ECS_EBT_HPP
#include "game/behavior/behavior-tree.hpp"
#include <entt/entt.hpp>
#include "ai/behavior-tree.hpp"
#include "ecs/entity.hpp"
#include "ecs/registry.hpp"
/// Entity Behavior Tree
namespace ecs {
/**
* The `ebt` namespace defines Entity Behavior Tree (EBT) nodes and an EBT context, on which EBT nodes operate.
*/
/// Entity behavior tree (EBT) nodes and context.
namespace ebt { namespace ebt {
/** /**
@ -35,22 +34,22 @@ namespace ebt {
*/ */
struct context struct context
{ {
entt::registry* registry;
entt::entity entity;
ecs::registry* registry;
ecs::entity entity;
}; };
typedef behavior_tree::status status;
typedef behavior_tree::node<context> node;
typedef behavior_tree::leaf_node<context> leaf_node;
typedef behavior_tree::decorator_node<context> decorator_node;
typedef behavior_tree::composite_node<context> composite_node;
typedef behavior_tree::action<context> action;
typedef behavior_tree::condition<context> condition;
typedef behavior_tree::inverter<context> inverter;
typedef behavior_tree::repeater<context> repeater;
typedef behavior_tree::succeeder<context> succeeder;
typedef behavior_tree::sequence<context> sequence;
typedef behavior_tree::selector<context> selector;
typedef ai::bt::status status;
typedef ai::bt::node<context> node;
typedef ai::bt::leaf_node<context> leaf_node;
typedef ai::bt::decorator_node<context> decorator_node;
typedef ai::bt::composite_node<context> composite_node;
typedef ai::bt::action<context> action;
typedef ai::bt::condition<context> condition;
typedef ai::bt::inverter<context> inverter;
typedef ai::bt::repeater<context> repeater;
typedef ai::bt::succeeder<context> succeeder;
typedef ai::bt::sequence<context> sequence;
typedef ai::bt::selector<context> selector;
// Actions // Actions
status print(context& context, const std::string& text); status print(context& context, const std::string& text);
@ -61,6 +60,7 @@ status warp_to(context& context, float x, float y, float z);
bool is_carrying_food(const context& context); bool is_carrying_food(const context& context);
} // namespace ebt } // namespace ebt
} // namespace ecs
#endif // ANTKEEPER_EBT_HPP
#endif // ANTKEEPER_ECS_EBT_HPP

+ 22
- 22
src/resources/behavior-tree-loader.cpp View File

@ -19,7 +19,7 @@
#include "resource-loader.hpp" #include "resource-loader.hpp"
#include "resource-manager.hpp" #include "resource-manager.hpp"
#include "game/behavior/ebt.hpp"
#include "ecs/ebt.hpp"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <functional> #include <functional>
#include <map> #include <map>
@ -43,7 +43,7 @@ void parse_argument(std::string& value, const std::string& string)
} }
template <class T, class... Args> template <class T, class... Args>
std::function<ebt::status(ebt::context&)> pack_function(T (*function)(ebt::context&, Args...), std::list<std::string> argv)
std::function<ecs::ebt::status(ecs::ebt::context&)> pack_function(T (*function)(ecs::ebt::context&, Args...), std::list<std::string> argv)
{ {
//if (argv.size() != sizeof...(Args)) //if (argv.size() != sizeof...(Args))
@ -60,18 +60,18 @@ std::function pack_function(T (*function)(ebt::conte
} }
return std::bind( return std::bind(
[function, arguments](ebt::context& context) -> ebt::status
[function, arguments](ecs::ebt::context& context) -> ecs::ebt::status
{ {
return std::apply(function, std::tuple_cat(std::make_tuple(context), arguments)); return std::apply(function, std::tuple_cat(std::make_tuple(context), arguments));
}, },
std::placeholders::_1); std::placeholders::_1);
} }
static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager);
static void load_node_child(ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager);
static void load_node_children(ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager);
static ecs::ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager);
static void load_node_child(ecs::ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager);
static void load_node_children(ecs::ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager);
static ebt::node* load_action_node(const nlohmann::json& json, resource_manager* resource_manager)
static ecs::ebt::node* load_action_node(const nlohmann::json& json, resource_manager* resource_manager)
{ {
// Get function name // Get function name
auto function_it = json.find("function"); auto function_it = json.find("function");
@ -85,31 +85,31 @@ static ebt::node* load_action_node(const nlohmann::json& json, resource_manager*
for (auto it = arguments_it.value().cbegin(); it != arguments_it.value().cend(); ++it) for (auto it = arguments_it.value().cbegin(); it != arguments_it.value().cend(); ++it)
arguments.push_back(it.value().get<std::string>()); arguments.push_back(it.value().get<std::string>());
ebt::action* action_node = new ebt::action();
if (function_name == "print") action_node->function = pack_function(ebt::print, arguments);
else if (function_name == "print_eid") action_node->function = pack_function(ebt::print_eid, arguments);
else if (function_name == "warp_to") action_node->function = pack_function(ebt::warp_to, arguments);
ecs::ebt::action* action_node = new ecs::ebt::action();
if (function_name == "print") action_node->function = pack_function(ecs::ebt::print, arguments);
else if (function_name == "print_eid") action_node->function = pack_function(ecs::ebt::print_eid, arguments);
else if (function_name == "warp_to") action_node->function = pack_function(ecs::ebt::warp_to, arguments);
return action_node; return action_node;
} }
static ebt::node* load_selector_node(const nlohmann::json& json, resource_manager* resource_manager)
static ecs::ebt::node* load_selector_node(const nlohmann::json& json, resource_manager* resource_manager)
{ {
ebt::selector* selector_node = new ebt::selector();
ecs::ebt::selector* selector_node = new ecs::ebt::selector();
load_node_children(selector_node, json, resource_manager); load_node_children(selector_node, json, resource_manager);
return selector_node; return selector_node;
} }
static ebt::node* load_sequence_node(const nlohmann::json& json, resource_manager* resource_manager)
static ecs::ebt::node* load_sequence_node(const nlohmann::json& json, resource_manager* resource_manager)
{ {
ebt::sequence* sequence_node = new ebt::sequence();
ecs::ebt::sequence* sequence_node = new ecs::ebt::sequence();
load_node_children(sequence_node, json, resource_manager); load_node_children(sequence_node, json, resource_manager);
return sequence_node; return sequence_node;
} }
static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager)
static ecs::ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager)
{ {
static const std::map<std::string, std::function<ebt::node*(const nlohmann::json&, ::resource_manager*)>> node_loaders =
static const std::map<std::string, std::function<ecs::ebt::node*(const nlohmann::json&, ::resource_manager*)>> node_loaders =
{ {
{"action", &load_action_node}, {"action", &load_action_node},
{"selector", &load_selector_node}, {"selector", &load_selector_node},
@ -125,24 +125,24 @@ static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource
return node_loader->second(json.value(), resource_manager); return node_loader->second(json.value(), resource_manager);
} }
static void load_node_child(ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager)
static void load_node_child(ecs::ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager)
{ {
auto it = json.find("child"); auto it = json.find("child");
node->child = load_node(it.value().cbegin(), resource_manager); node->child = load_node(it.value().cbegin(), resource_manager);
} }
static void load_node_children(ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager)
static void load_node_children(ecs::ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager)
{ {
auto children_it = json.find("children"); auto children_it = json.find("children");
for (auto it = children_it.value().cbegin(); it != children_it.value().cend(); ++it) for (auto it = children_it.value().cbegin(); it != children_it.value().cend(); ++it)
{ {
ebt::node* child = load_node(it.value().begin(), resource_manager);
ecs::ebt::node* child = load_node(it.value().begin(), resource_manager);
node->children.push_back(child); node->children.push_back(child);
} }
} }
template <> template <>
ebt::node* resource_loader<ebt::node>::load(resource_manager* resource_manager, PHYSFS_File* file)
ecs::ebt::node* resource_loader<ecs::ebt::node>::load(resource_manager* resource_manager, PHYSFS_File* file)
{ {
// Read file into buffer // Read file into buffer
std::size_t size = static_cast<int>(PHYSFS_fileLength(file)); std::size_t size = static_cast<int>(PHYSFS_fileLength(file));
@ -155,7 +155,7 @@ ebt::node* resource_loader::load(resource_manager* resource_manager,
if (json.size() != 1) if (json.size() != 1)
{ {
throw std::runtime_error("resource_loader<ebt::node>::load(): Behavior tree must have exactly one root node.");
throw std::runtime_error("resource_loader<ecs::ebt::node>::load(): Behavior tree must have exactly one root node.");
} }
return load_node(json.cbegin(), resource_manager); return load_node(json.cbegin(), resource_manager);

+ 2
- 2
src/resources/entity-archetype-loader.cpp View File

@ -31,7 +31,7 @@
#include "ecs/components/marker-component.hpp" #include "ecs/components/marker-component.hpp"
#include "ecs/components/brush-component.hpp" #include "ecs/components/brush-component.hpp"
#include "ecs/archetype.hpp" #include "ecs/archetype.hpp"
#include "game/behavior/ebt.hpp"
#include "ecs/ebt.hpp"
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
@ -46,7 +46,7 @@ static bool load_behavior_component(archetype& archetype, resource_manager& reso
std::string filename = parameters[1]; std::string filename = parameters[1];
behavior_component component; behavior_component component;
component.behavior_tree = resource_manager.load<ebt::node>(filename);
component.behavior_tree = resource_manager.load<ecs::ebt::node>(filename);
if (!component.behavior_tree) if (!component.behavior_tree)
{ {
std::string message = std::string("load_behavior_component(): Failed to load behavior tree \"") + filename + std::string("\""); std::string message = std::string("load_behavior_component(): Failed to load behavior tree \"") + filename + std::string("\"");

Loading…
Cancel
Save