.clang-format
This commit is contained in:
parent
432673fa0e
commit
d89827046a
6 changed files with 295 additions and 237 deletions
4
.clang-format
Normal file
4
.clang-format
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
IndentWidth: 4
|
68
dbc.cpp
68
dbc.cpp
|
@ -1,44 +1,54 @@
|
||||||
#include "dbc.hpp"
|
#include "dbc.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void dbc::log(const string &message) {
|
void dbc::log(const string &message)
|
||||||
std::cerr << "!!!!!!!!!!" << message << std::endl;
|
{
|
||||||
|
std::cerr << "!!!!!!!!!!" << message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbc::sentinel(const string &message) {
|
void dbc::sentinel(const string &message)
|
||||||
string err = fmt::format("[SENTINEL!] {}", message);
|
{
|
||||||
dbc::log(err);
|
string err = fmt::format("[SENTINEL!] {}", message);
|
||||||
throw dbc::SentinelError{err};
|
|
||||||
}
|
|
||||||
|
|
||||||
void dbc::pre(const string &message, bool test) {
|
|
||||||
if(!test) {
|
|
||||||
string err = fmt::format("[PRE!] {}", message);
|
|
||||||
dbc::log(err);
|
dbc::log(err);
|
||||||
throw dbc::PreCondError{err};
|
throw dbc::SentinelError{err};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbc::pre(const string &message, std::function<bool()> tester) {
|
void dbc::pre(const string &message, bool test)
|
||||||
dbc::pre(message, tester());
|
{
|
||||||
|
if (!test)
|
||||||
|
{
|
||||||
|
string err = fmt::format("[PRE!] {}", message);
|
||||||
|
dbc::log(err);
|
||||||
|
throw dbc::PreCondError{err};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbc::post(const string &message, bool test) {
|
void dbc::pre(const string &message, std::function<bool()> tester)
|
||||||
if(!test) {
|
{
|
||||||
string err = fmt::format("[POST!] {}", message);
|
dbc::pre(message, tester());
|
||||||
dbc::log(err);
|
|
||||||
throw dbc::PostCondError{err};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbc::post(const string &message, std::function<bool()> tester) {
|
void dbc::post(const string &message, bool test)
|
||||||
dbc::post(message, tester());
|
{
|
||||||
|
if (!test)
|
||||||
|
{
|
||||||
|
string err = fmt::format("[POST!] {}", message);
|
||||||
|
dbc::log(err);
|
||||||
|
throw dbc::PostCondError{err};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbc::check(bool test, const string &message) {
|
void dbc::post(const string &message, std::function<bool()> tester)
|
||||||
if(!test) {
|
{
|
||||||
string err = fmt::format("[CHECK!] {}\n", message);
|
dbc::post(message, tester());
|
||||||
dbc::log(err);
|
}
|
||||||
throw dbc::CheckError{err};
|
|
||||||
}
|
void dbc::check(bool test, const string &message)
|
||||||
|
{
|
||||||
|
if (!test)
|
||||||
|
{
|
||||||
|
string err = fmt::format("[CHECK!] {}\n", message);
|
||||||
|
dbc::log(err);
|
||||||
|
throw dbc::CheckError{err};
|
||||||
|
}
|
||||||
}
|
}
|
50
dbc.hpp
50
dbc.hpp
|
@ -1,29 +1,39 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
namespace dbc {
|
namespace dbc
|
||||||
class Error {
|
{
|
||||||
public:
|
class Error
|
||||||
const string message;
|
{
|
||||||
Error(string m) : message{m} {}
|
public:
|
||||||
Error(const char *m) : message{m} {}
|
const string message;
|
||||||
};
|
Error(string m) : message{m} {}
|
||||||
|
Error(const char *m) : message{m} {}
|
||||||
|
};
|
||||||
|
|
||||||
class CheckError : public Error {};
|
class CheckError : public Error
|
||||||
class SentinelError : public Error {};
|
{
|
||||||
class PreCondError : public Error {};
|
};
|
||||||
class PostCondError : public Error {};
|
class SentinelError : public Error
|
||||||
|
{
|
||||||
|
};
|
||||||
|
class PreCondError : public Error
|
||||||
|
{
|
||||||
|
};
|
||||||
|
class PostCondError : public Error
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
void log(const string &message);
|
void log(const string &message);
|
||||||
void sentinel(const string &message);
|
void sentinel(const string &message);
|
||||||
void pre(const string &message, bool test);
|
void pre(const string &message, bool test);
|
||||||
void pre(const string &message, std::function<bool()> tester);
|
void pre(const string &message, std::function<bool()> tester);
|
||||||
void post(const string &message, bool test);
|
void post(const string &message, bool test);
|
||||||
void post(const string &message, std::function<bool()> tester);
|
void post(const string &message, std::function<bool()> tester);
|
||||||
void check(bool test, const string &message);
|
void check(bool test, const string &message);
|
||||||
}
|
} // namespace dbc
|
||||||
|
|
177
dinkyecs.hpp
177
dinkyecs.hpp
|
@ -1,156 +1,169 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dbc.hpp"
|
||||||
|
#include <any>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <queue>
|
||||||
|
#include <tuple>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <any>
|
|
||||||
#include <tuple>
|
|
||||||
#include <queue>
|
|
||||||
#include "dbc.hpp"
|
|
||||||
|
|
||||||
namespace DinkyECS {
|
namespace DinkyECS
|
||||||
typedef unsigned long Entity;
|
{
|
||||||
|
typedef unsigned long Entity;
|
||||||
|
|
||||||
using EntityMap = std::unordered_map<Entity, std::any>;
|
using EntityMap = std::unordered_map<Entity, std::any>;
|
||||||
|
|
||||||
struct Event {
|
struct Event
|
||||||
|
{
|
||||||
int event = 0;
|
int event = 0;
|
||||||
Entity entity = 0;
|
Entity entity = 0;
|
||||||
std::any data;
|
std::any data;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::queue<Event> EventQueue;
|
typedef std::queue<Event> EventQueue;
|
||||||
|
|
||||||
struct World {
|
struct World
|
||||||
|
{
|
||||||
unsigned long entity_count = 0;
|
unsigned long entity_count = 0;
|
||||||
std::unordered_map<std::type_index, EntityMap> $components;
|
std::unordered_map<std::type_index, EntityMap> $components;
|
||||||
std::unordered_map<std::type_index, std::any> $facts;
|
std::unordered_map<std::type_index, std::any> $facts;
|
||||||
std::unordered_map<std::type_index, EventQueue> $events;
|
std::unordered_map<std::type_index, EventQueue> $events;
|
||||||
std::vector<Entity> $constants;
|
std::vector<Entity> $constants;
|
||||||
|
|
||||||
Entity entity() {
|
Entity entity() { return ++entity_count; }
|
||||||
return ++entity_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clone_into(DinkyECS::World &to_world) {
|
void clone_into(DinkyECS::World &to_world)
|
||||||
to_world.$constants = $constants;
|
{
|
||||||
to_world.$facts = $facts;
|
to_world.$constants = $constants;
|
||||||
to_world.entity_count = entity_count;
|
to_world.$facts = $facts;
|
||||||
|
to_world.entity_count = entity_count;
|
||||||
|
|
||||||
for(auto eid : $constants) {
|
for (auto eid : $constants)
|
||||||
for(const auto &[tid, eid_map] : $components) {
|
{
|
||||||
auto& their_map = to_world.$components[tid];
|
for (const auto &[tid, eid_map] : $components)
|
||||||
if(eid_map.contains(eid)) {
|
{
|
||||||
their_map.insert_or_assign(eid, eid_map.at(eid));
|
auto &their_map = to_world.$components[tid];
|
||||||
}
|
if (eid_map.contains(eid))
|
||||||
|
{
|
||||||
|
their_map.insert_or_assign(eid, eid_map.at(eid));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void make_constant(DinkyECS::Entity entity) {
|
void make_constant(DinkyECS::Entity entity)
|
||||||
|
{
|
||||||
$constants.push_back(entity);
|
$constants.push_back(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> EntityMap &entity_map_for()
|
||||||
EntityMap& entity_map_for() {
|
{
|
||||||
return $components[std::type_index(typeid(Comp))];
|
return $components[std::type_index(typeid(Comp))];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> EventQueue &queue_map_for()
|
||||||
EventQueue& queue_map_for() {
|
{
|
||||||
return $events[std::type_index(typeid(Comp))];
|
return $events[std::type_index(typeid(Comp))];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> void remove(Entity ent)
|
||||||
void remove(Entity ent) {
|
{
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
map.erase(ent);
|
map.erase(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> void set_the(Comp val)
|
||||||
void set_the(Comp val) {
|
{
|
||||||
$facts.insert_or_assign(std::type_index(typeid(Comp)), val);
|
$facts.insert_or_assign(std::type_index(typeid(Comp)), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> Comp &get_the()
|
||||||
Comp &get_the() {
|
{
|
||||||
auto comp_id = std::type_index(typeid(Comp));
|
auto comp_id = std::type_index(typeid(Comp));
|
||||||
dbc::check($facts.contains(comp_id),
|
dbc::check($facts.contains(comp_id),
|
||||||
fmt::format("!!!! ATTEMPT to access world fact that hasn't been set yet: {}", typeid(Comp).name()));
|
fmt::format("!!!! ATTEMPT to access world fact that hasn't "
|
||||||
|
"been set yet: {}",
|
||||||
|
typeid(Comp).name()));
|
||||||
|
|
||||||
// use .at to get std::out_of_range if fact not set
|
// use .at to get std::out_of_range if fact not set
|
||||||
std::any &res = $facts.at(comp_id);
|
std::any &res = $facts.at(comp_id);
|
||||||
return std::any_cast<Comp&>(res);
|
return std::any_cast<Comp &>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> bool has_the()
|
||||||
bool has_the() {
|
{
|
||||||
auto comp_id = std::type_index(typeid(Comp));
|
auto comp_id = std::type_index(typeid(Comp));
|
||||||
return $facts.contains(comp_id);
|
return $facts.contains(comp_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> void set(Entity ent, Comp val)
|
||||||
void set(Entity ent, Comp val) {
|
{
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
map.insert_or_assign(ent, val);
|
map.insert_or_assign(ent, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> Comp &get(Entity ent)
|
||||||
Comp &get(Entity ent) {
|
{
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
// use .at for bounds checking
|
// use .at for bounds checking
|
||||||
std::any &res = map.at(ent);
|
std::any &res = map.at(ent);
|
||||||
return std::any_cast<Comp&>(res);
|
return std::any_cast<Comp &>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Comp>
|
template <typename Comp> bool has(Entity ent)
|
||||||
bool has(Entity ent) {
|
{
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
return map.contains(ent);
|
return map.contains(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Comp>
|
template <typename Comp>
|
||||||
void query(std::function<void(const Entity&, Comp&)> cb) {
|
void query(std::function<void(const Entity &, Comp &)> cb)
|
||||||
|
{
|
||||||
EntityMap &map = entity_map_for<Comp>();
|
EntityMap &map = entity_map_for<Comp>();
|
||||||
for(auto& [entity, any_comp] : map) {
|
for (auto &[entity, any_comp] : map)
|
||||||
Comp &res = std::any_cast<Comp&>(any_comp);
|
{
|
||||||
cb(entity, res);
|
Comp &res = std::any_cast<Comp &>(any_comp);
|
||||||
|
cb(entity, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CompA, typename CompB>
|
template <typename CompA, typename CompB>
|
||||||
void query(std::function<void(const Entity&, CompA&, CompB&)> cb) {
|
void query(std::function<void(const Entity &, CompA &, CompB &)> cb)
|
||||||
|
{
|
||||||
EntityMap &map_a = entity_map_for<CompA>();
|
EntityMap &map_a = entity_map_for<CompA>();
|
||||||
EntityMap &map_b = entity_map_for<CompB>();
|
EntityMap &map_b = entity_map_for<CompB>();
|
||||||
|
|
||||||
for(auto& [entity, any_a] : map_a) {
|
for (auto &[entity, any_a] : map_a)
|
||||||
if(map_b.contains(entity)) {
|
{
|
||||||
CompA &res_a = std::any_cast<CompA&>(any_a);
|
if (map_b.contains(entity))
|
||||||
CompB &res_b = get<CompB>(entity);
|
{
|
||||||
cb(entity, res_a, res_b);
|
CompA &res_a = std::any_cast<CompA &>(any_a);
|
||||||
}
|
CompB &res_b = get<CompB>(entity);
|
||||||
|
cb(entity, res_a, res_b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Comp>
|
template <typename Comp> void send(Comp event, Entity entity, std::any data)
|
||||||
void send(Comp event, Entity entity, std::any data) {
|
{
|
||||||
EventQueue &queue = queue_map_for<Comp>();
|
EventQueue &queue = queue_map_for<Comp>();
|
||||||
queue.push({event, entity, data});
|
queue.push({event, entity, data});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Comp>
|
template <typename Comp> Event recv()
|
||||||
Event recv() {
|
{
|
||||||
EventQueue &queue = queue_map_for<Comp>();
|
EventQueue &queue = queue_map_for<Comp>();
|
||||||
Event evt = queue.front();
|
Event evt = queue.front();
|
||||||
queue.pop();
|
queue.pop();
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Comp>
|
template <typename Comp> bool has_event()
|
||||||
bool has_event() {
|
{
|
||||||
EventQueue &queue = queue_map_for<Comp>();
|
EventQueue &queue = queue_map_for<Comp>();
|
||||||
return !queue.empty();
|
return !queue.empty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace DinkyECS
|
||||||
|
|
204
main.cpp
204
main.cpp
|
@ -10,137 +10,155 @@ using namespace fmt;
|
||||||
using DinkyECS::Entity;
|
using DinkyECS::Entity;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
struct Player {
|
struct Player
|
||||||
string name;
|
{
|
||||||
Entity eid;
|
string name;
|
||||||
|
Entity eid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Position {
|
struct Position
|
||||||
Point location;
|
{
|
||||||
|
Point location;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DINKY_HAS_COMPONENT(Point, x, y);
|
// DINKY_HAS_COMPONENT(Point, x, y);
|
||||||
// DINKY_HAS_COMPONENT(Position, location);
|
// DINKY_HAS_COMPONENT(Position, location);
|
||||||
|
|
||||||
struct Motion {
|
struct Motion
|
||||||
int dx;
|
{
|
||||||
int dy;
|
int dx;
|
||||||
bool random=false;
|
int dy;
|
||||||
|
bool random = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DINKY_HAS_COMPONENT(Motion, dx, dy, random);
|
// DINKY_HAS_COMPONENT(Motion, dx, dy, random);
|
||||||
|
|
||||||
struct Velocity {
|
struct Velocity
|
||||||
double x, y;
|
{
|
||||||
|
double x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DINKY_HAS_COMPONENT(Velocity, x, y);
|
// DINKY_HAS_COMPONENT(Velocity, x, y);
|
||||||
|
|
||||||
struct Gravity {
|
struct Gravity
|
||||||
double level;
|
{
|
||||||
|
double level;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DINKY_HAS_COMPONENT(Gravity, level);
|
// DINKY_HAS_COMPONENT(Gravity, level);
|
||||||
|
|
||||||
struct DaGUI {
|
struct DaGUI
|
||||||
int event;
|
{
|
||||||
|
int event;
|
||||||
};
|
};
|
||||||
|
|
||||||
void configure(DinkyECS::World &world, Entity &test) {
|
void configure(DinkyECS::World &world, Entity &test)
|
||||||
println("---Configuring the base system.");
|
{
|
||||||
Entity test2 = world.entity();
|
println("---Configuring the base system.");
|
||||||
|
Entity test2 = world.entity();
|
||||||
|
|
||||||
world.set<Position>(test, {10,20});
|
world.set<Position>(test, {10, 20});
|
||||||
world.set<Velocity>(test, {1,2});
|
world.set<Velocity>(test, {1, 2});
|
||||||
|
|
||||||
world.set<Position>(test2, {1,1});
|
world.set<Position>(test2, {1, 1});
|
||||||
world.set<Velocity>(test2, {9,19});
|
world.set<Velocity>(test2, {9, 19});
|
||||||
|
|
||||||
println("---- Setting up the player as a fact in the system.");
|
println("---- Setting up the player as a fact in the system.");
|
||||||
|
|
||||||
auto player_eid = world.entity();
|
auto player_eid = world.entity();
|
||||||
Player player_info{"Zed", player_eid};
|
Player player_info{"Zed", player_eid};
|
||||||
// just set some player info as a fact with the entity id
|
// just set some player info as a fact with the entity id
|
||||||
world.set_the<Player>(player_info);
|
world.set_the<Player>(player_info);
|
||||||
|
|
||||||
world.set<Velocity>(player_eid, {0,0});
|
world.set<Velocity>(player_eid, {0, 0});
|
||||||
world.set<Position>(player_eid, {0,0});
|
world.set<Position>(player_eid, {0, 0});
|
||||||
|
|
||||||
auto enemy = world.entity();
|
auto enemy = world.entity();
|
||||||
world.set<Velocity>(enemy, {0,0});
|
world.set<Velocity>(enemy, {0, 0});
|
||||||
world.set<Position>(enemy, {0,0});
|
world.set<Position>(enemy, {0, 0});
|
||||||
|
|
||||||
println("--- Creating facts (singletons)");
|
println("--- Creating facts (singletons)");
|
||||||
world.set_the<Gravity>({0.9});
|
world.set_the<Gravity>({0.9});
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
DinkyECS::World world;
|
{
|
||||||
Entity test = world.entity();
|
DinkyECS::World world;
|
||||||
|
Entity test = world.entity();
|
||||||
|
|
||||||
configure(world, test);
|
configure(world, test);
|
||||||
|
|
||||||
Position &pos = world.get<Position>(test);
|
Position &pos = world.get<Position>(test);
|
||||||
REQUIRE(pos.location.x == 10);
|
REQUIRE(pos.location.x == 10);
|
||||||
REQUIRE(pos.location.y == 20);
|
REQUIRE(pos.location.y == 20);
|
||||||
|
|
||||||
Velocity &vel = world.get<Velocity>(test);
|
Velocity &vel = world.get<Velocity>(test);
|
||||||
REQUIRE(vel.x == 1);
|
REQUIRE(vel.x == 1);
|
||||||
REQUIRE(vel.y == 2);
|
REQUIRE(vel.y == 2);
|
||||||
|
|
||||||
world.query<Position>([](const auto &ent, auto &pos) {
|
world.query<Position>(
|
||||||
REQUIRE(ent > 0);
|
[](const auto &ent, auto &pos)
|
||||||
REQUIRE(pos.location.x >= 0);
|
{
|
||||||
REQUIRE(pos.location.y >= 0);
|
REQUIRE(ent > 0);
|
||||||
});
|
REQUIRE(pos.location.x >= 0);
|
||||||
|
REQUIRE(pos.location.y >= 0);
|
||||||
|
});
|
||||||
|
|
||||||
world.query<Velocity>([](const auto &ent, auto &vel) {
|
world.query<Velocity>(
|
||||||
REQUIRE(ent > 0);
|
[](const auto &ent, auto &vel)
|
||||||
REQUIRE(vel.x >= 0);
|
{
|
||||||
REQUIRE(vel.y >= 0);
|
REQUIRE(ent > 0);
|
||||||
});
|
REQUIRE(vel.x >= 0);
|
||||||
|
REQUIRE(vel.y >= 0);
|
||||||
|
});
|
||||||
|
|
||||||
println("--- Manually get the velocity in position system:");
|
println("--- Manually get the velocity in position system:");
|
||||||
world.query<Position>([&](const auto &ent, auto &pos) {
|
world.query<Position>(
|
||||||
Velocity &vel = world.get<Velocity>(ent);
|
[&](const auto &ent, auto &pos)
|
||||||
|
{
|
||||||
|
Velocity &vel = world.get<Velocity>(ent);
|
||||||
|
|
||||||
REQUIRE(ent > 0);
|
REQUIRE(ent > 0);
|
||||||
REQUIRE(pos.location.x >= 0);
|
REQUIRE(pos.location.x >= 0);
|
||||||
REQUIRE(pos.location.y >= 0);
|
REQUIRE(pos.location.y >= 0);
|
||||||
REQUIRE(ent > 0);
|
REQUIRE(ent > 0);
|
||||||
REQUIRE(vel.x >= 0);
|
REQUIRE(vel.x >= 0);
|
||||||
REQUIRE(vel.y >= 0);
|
REQUIRE(vel.y >= 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
println("--- Query only entities with Position and Velocity:");
|
println("--- Query only entities with Position and Velocity:");
|
||||||
world.query<Position, Velocity>([&](const auto &ent, auto &pos, auto &vel) {
|
world.query<Position, Velocity>(
|
||||||
Gravity &grav = world.get_the<Gravity>();
|
[&](const auto &ent, auto &pos, auto &vel)
|
||||||
REQUIRE(grav.level <= 1.0f);
|
{
|
||||||
REQUIRE(grav.level > 0.5f);
|
Gravity &grav = world.get_the<Gravity>();
|
||||||
REQUIRE(ent > 0);
|
REQUIRE(grav.level <= 1.0f);
|
||||||
REQUIRE(pos.location.x >= 0);
|
REQUIRE(grav.level > 0.5f);
|
||||||
REQUIRE(pos.location.y >= 0);
|
REQUIRE(ent > 0);
|
||||||
REQUIRE(ent > 0);
|
REQUIRE(pos.location.x >= 0);
|
||||||
REQUIRE(vel.x >= 0);
|
REQUIRE(pos.location.y >= 0);
|
||||||
REQUIRE(vel.y >= 0);
|
REQUIRE(ent > 0);
|
||||||
});
|
REQUIRE(vel.x >= 0);
|
||||||
|
REQUIRE(vel.y >= 0);
|
||||||
|
});
|
||||||
|
|
||||||
// now remove Velocity
|
// now remove Velocity
|
||||||
REQUIRE(world.has<Velocity>(test));
|
REQUIRE(world.has<Velocity>(test));
|
||||||
world.remove<Velocity>(test);
|
world.remove<Velocity>(test);
|
||||||
//REQUIRE_THROWS(world.get<Velocity>(test));
|
// REQUIRE_THROWS(world.get<Velocity>(test));
|
||||||
REQUIRE(!world.has<Velocity>(test));
|
REQUIRE(!world.has<Velocity>(test));
|
||||||
|
|
||||||
println("--- After remove test, should only result in test2:");
|
println("--- After remove test, should only result in test2:");
|
||||||
world.query<Position, Velocity>([&](const auto &ent, auto &pos, auto &vel) {
|
world.query<Position, Velocity>(
|
||||||
auto &in_position = world.get<Position>(ent);
|
[&](const auto &ent, auto &pos, auto &vel)
|
||||||
auto &in_velocity = world.get<Velocity>(ent);
|
{
|
||||||
REQUIRE(pos.location.x >= 0);
|
auto &in_position = world.get<Position>(ent);
|
||||||
REQUIRE(pos.location.y >= 0);
|
auto &in_velocity = world.get<Velocity>(ent);
|
||||||
REQUIRE(in_position.location.x == pos.location.x);
|
REQUIRE(pos.location.x >= 0);
|
||||||
REQUIRE(in_position.location.y == pos.location.y);
|
REQUIRE(pos.location.y >= 0);
|
||||||
REQUIRE(in_velocity.x == vel.x);
|
REQUIRE(in_position.location.x == pos.location.x);
|
||||||
REQUIRE(in_velocity.y == vel.y);
|
REQUIRE(in_position.location.y == pos.location.y);
|
||||||
});
|
REQUIRE(in_velocity.x == vel.x);
|
||||||
return 0;
|
REQUIRE(in_velocity.y == vel.y);
|
||||||
|
});
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
27
point.hpp
27
point.hpp
|
@ -1,21 +1,24 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Point {
|
struct Point
|
||||||
size_t x = 0;
|
{
|
||||||
size_t y = 0;
|
size_t x = 0;
|
||||||
|
size_t y = 0;
|
||||||
|
|
||||||
bool operator==(const Point& other) const {
|
bool operator==(const Point &other) const
|
||||||
return other.x == x && other.y == y;
|
{
|
||||||
}
|
return other.x == x && other.y == y;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Point> PointList;
|
typedef std::vector<Point> PointList;
|
||||||
|
|
||||||
template<> struct std::hash<Point> {
|
template <> struct std::hash<Point>
|
||||||
size_t operator()(const Point& p) const {
|
{
|
||||||
auto hasher = std::hash<int>();
|
size_t operator()(const Point &p) const
|
||||||
return hasher(p.x) ^ hasher(p.y);
|
{
|
||||||
}
|
auto hasher = std::hash<int>();
|
||||||
|
return hasher(p.x) ^ hasher(p.y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue