Browse Source

* implemented defer_proxy

* implemented step_proxy
* implemented system execution adapter
master
bergmann 5 years ago
parent
commit
9f404954ea
16 changed files with 287 additions and 19 deletions
  1. +1
    -0
      include/ecs.h
  2. +9
    -0
      include/ecs/config.h
  3. +4
    -1
      include/ecs/context.h
  4. +43
    -6
      include/ecs/context/base.h
  5. +9
    -3
      include/ecs/context/context.h
  6. +36
    -0
      include/ecs/context/defer_proxy.h
  7. +25
    -0
      include/ecs/context/step_proxy.h
  8. +1
    -0
      include/ecs/core/system.h
  9. +3
    -0
      include/ecs/core/system/scheduler.h
  10. +21
    -0
      include/ecs/core/system/scheduler/atomic_counter.h
  11. +3
    -0
      include/ecs/settings/scheduler.h
  12. +22
    -0
      include/ecs/settings/scheduler/atomic_counter.h
  13. +11
    -1
      include/ecs/settings/settings.h
  14. +9
    -0
      include/ecs/signature_list/system.h
  15. +77
    -0
      include/ecs/system_execution_adapter.h
  16. +13
    -8
      test/dummy.cpp

+ 1
- 0
include/ecs.h View File

@@ -4,4 +4,5 @@
#include "./ecs/settings.h"
#include "./ecs/signature_list.h"
#include "./ecs/signature.h"
#include "./ecs/system_execution_adapter.h"
#include "./ecs/tag.h"

+ 9
- 0
include/ecs/config.h View File

@@ -65,6 +65,9 @@ struct type_helper
#define beg_namespace_ecs_core_parallelism ecs_define_namespace_beg(beg_namespace_ecs_core_system, parallelism)
#define end_namespace_ecs_core_parallelism ecs_define_namespace_end(end_namespace_ecs_core_system)

#define beg_namespace_ecs_core_system_scheduler ecs_define_namespace_beg(beg_namespace_ecs_core_system, scheduler)
#define end_namespace_ecs_core_system_scheduler ecs_define_namespace_end(end_namespace_ecs_core_system)

#define beg_namespace_ecs_core_system_storage ecs_define_namespace_beg(beg_namespace_ecs_core_system, storage)
#define end_namespace_ecs_core_system_storage ecs_define_namespace_end(end_namespace_ecs_core_system)

@@ -80,6 +83,9 @@ struct type_helper
#define beg_namespace_ecs_settings_refresh_parallelism ecs_define_namespace_beg(beg_namespace_ecs_settings, refresh_parallelism)
#define end_namespace_ecs_settings_refresh_parallelism ecs_define_namespace_end(end_namespace_ecs_settings)

#define beg_namespace_ecs_settings_scheduler ecs_define_namespace_beg(beg_namespace_ecs_settings, scheduler)
#define end_namespace_ecs_settings_scheduler ecs_define_namespace_end(end_namespace_ecs_settings)

#define beg_namespace_ecs_settings_system_storage ecs_define_namespace_beg(beg_namespace_ecs_settings, system_storage)
#define end_namespace_ecs_settings_system_storage ecs_define_namespace_end(end_namespace_ecs_settings)

@@ -110,6 +116,9 @@ struct type_helper
#define beg_namespace_ecs_signature_list_system ecs_define_namespace_beg(beg_namespace_ecs_signature_list, system)
#define end_namespace_ecs_signature_list_system ecs_define_namespace_end(end_namespace_ecs_signature_list)

#define beg_namespace_ecs_system_execution_adapter ecs_define_namespace_beg(beg_namespace_ecs, system_execution_adapter)
#define end_namespace_ecs_system_execution_adapter ecs_define_namespace_end(end_namespace_ecs)

#define beg_namespace_ecs_tag ecs_define_namespace_beg(beg_namespace_ecs, tag)
#define end_namespace_ecs_tag ecs_define_namespace_end(end_namespace_ecs)



+ 4
- 1
include/ecs/context.h View File

@@ -1,3 +1,6 @@
#pragma once

#include "./context/context.h"
#include "./context/base.h"
#include "./context/context.h"
#include "./context/defer_proxy.h"
#include "./context/step_proxy.h"

+ 43
- 6
include/ecs/context/base.h View File

@@ -5,6 +5,12 @@
#include <ecs/core/utils/counter_blocker.h>
#include <ecs/core/component/manager.h>

#define ecs_context_proxy_func(base, name) \
template<typename... T_args> \
inline decltype(auto) name(T_args&&... args) \
noexcept(noexcept(base::name(std::forward<T_args>(args)...))) \
{ return base::name(std::forward<T_args>(args)...); }

beg_namespace_ecs_context
{

@@ -22,6 +28,7 @@ beg_namespace_ecs_context
using entity_storage_type = decltype((settings_type { }).entity_storage()(settings_type { }, hana::type_c<chunk_meta_data_type>));
using entity_handle_type = typename entity_storage_type::entity_handle_type;
using system_storage_type = decltype((settings_type { }).system_storage()(settings_type { }, hana::type_c<entity_handle_type>));
using scheduler_type = decltype((settings_type { }).scheduler()(settings_type { }));

public:
using handle_type = entity_handle_type;
@@ -33,6 +40,7 @@ beg_namespace_ecs_context
component_manager_type _components;
entity_storage_type _entities;
system_storage_type _systems;
scheduler_type _scheduler;

core::utils::thread_pool _thread_pool;

@@ -42,21 +50,22 @@ beg_namespace_ecs_context
public:
inline base_t()
: _components ()
, _entities (settings_type { }.entity_storage()(settings_type { }, hana::type_c<chunk_meta_data_type>))
, _systems (settings_type { }.system_storage()(settings_type { }, hana::type_c<entity_handle_type>))
, _entities ((settings_type { }).entity_storage()(settings_type { }, hana::type_c<chunk_meta_data_type>))
, _systems ((settings_type { }).system_storage()(settings_type { }, hana::type_c<entity_handle_type>))
, _scheduler ((settings_type { }).scheduler()(settings_type { }))
, _thread_pool (std::thread::hardware_concurrency() != 0
? std::thread::hardware_concurrency()
: 8 )
{ }

public: /* misc */
protected: /* misc */
template<typename T_func>
inline decltype(auto) post_in_thread_pool(T_func&& func)
{
return _thread_pool.post(std::forward<T_func>(func));
}

public: /* entity */
protected: /* entity */
template<typename... T_args>
inline handle_type create_entity(T_args&&... args)
{
@@ -74,7 +83,7 @@ beg_namespace_ecs_context
return _entities.is_valid(handle);
}

public: /* component */
protected: /* component */
template<typename T_component_tag>
inline decltype(auto) add_component(const handle_type& handle, T_component_tag ct)
{
@@ -115,7 +124,13 @@ beg_namespace_ecs_context
bitset.set_component(ct, false);
}

public: /* systems */
protected: /* systems */
template<typename T_system_tag>
inline auto& system(T_system_tag st)
{
return _systems.instance_by_tag(st).system();
}

template<typename T_func>
inline void for_systems_sequential(T_func&& func)
{
@@ -150,6 +165,28 @@ beg_namespace_ecs_context
_(this)->for_systems_sequential(func);
});
}

private:
template<typename... T_system_tags>
static constexpr decltype(auto) make_system_tag_list(T_system_tags&&... tags) noexcept
{
auto list = core::mp::list::make(std::forward<T_system_tags>(tags)...);
return hana::if_(
hana::equal(hana::size(list), hana::size_c<0>),
(settings_type { }).system_signatures().tags(),
list);
}

protected: /* execute */
template<typename... T_system_tags>
inline decltype(auto) execute_systems(T_system_tags&&... sts) noexcept
{
auto tags = make_system_tag_list(std::forward<T_system_tags>(sts)...);
return [tags, this](auto&&... fns) {
auto os = hana::overload_linearly(std::forward<decltype(fns)>(fns)...);
this->_scheduler.execute(*this, tags, os);
};
}
};
}



+ 9
- 3
include/ecs/context/context.h View File

@@ -3,7 +3,7 @@
#include <ecs/config.h>
#include <ecs/core/utils/scope_guard.h>

#include "./base.h"
#include "./step_proxy.h"

beg_namespace_ecs_context
{
@@ -12,8 +12,12 @@ beg_namespace_ecs_context
{
template<typename T_settings>
struct context_t
: public base_t<T_settings>
: public step_proxy_t<T_settings>
{
private:
using settings_type = T_settings;
using step_proxy_type = step_proxy_t<settings_type>;

private:
void refresh()
{
@@ -22,11 +26,13 @@ beg_namespace_ecs_context

public:
template<typename T_step_func>
inline decltype(auto) step(T_step_func&& set_func)
inline decltype(auto) step(T_step_func&& step_func)
{
ecs_make_scope_guard([this]{
this->refresh();
});

std::forward<T_step_func>(step_func)(static_cast<step_proxy_type&>(*this));
}
};



+ 36
- 0
include/ecs/context/defer_proxy.h View File

@@ -0,0 +1,36 @@
#pragma once

#include <ecs/config.h>

#include "./base.h"

beg_namespace_ecs_context
{

namespace __impl
{
template<typename T_settings>
struct defer_proxy_t
: public base_t<T_settings>
{
private:
using base_type = base_t<T_settings>;

public: /* entity */
ecs_context_proxy_func(base_type, create_entity)
ecs_context_proxy_func(base_type, kill_entity)
ecs_context_proxy_func(base_type, is_alive)

public: /* component */
ecs_context_proxy_func(base_type, add_component)
ecs_context_proxy_func(base_type, has_component)
ecs_context_proxy_func(base_type, get_component)
ecs_context_proxy_func(base_type, remove_component)

public: /* system */
ecs_context_proxy_func(base_type, system)
};
}

}
end_namespace_ecs_context

+ 25
- 0
include/ecs/context/step_proxy.h View File

@@ -0,0 +1,25 @@
#pragma once

#include <ecs/config.h>

#include "./defer_proxy.h"

beg_namespace_ecs_context
{

namespace __impl
{
template<typename T_settings>
struct step_proxy_t
: public defer_proxy_t<T_settings>
{
private:
using base_type = defer_proxy_t<T_settings>;

public: /* execute */
ecs_context_proxy_func(base_type, execute_systems)
};
}

}
end_namespace_ecs_context

+ 1
- 0
include/ecs/core/system.h View File

@@ -2,4 +2,5 @@

#include "./system/instance.h"
#include "./system/parallelism.h"
#include "./system/scheduler.h"
#include "./system/storage.h"

+ 3
- 0
include/ecs/core/system/scheduler.h View File

@@ -0,0 +1,3 @@
#pragma once

#include "./scheduler/atomic_counter.h"

+ 21
- 0
include/ecs/core/system/scheduler/atomic_counter.h View File

@@ -0,0 +1,21 @@
#pragma once

#include <ecs/config.h>

beg_namespace_ecs_core_system_scheduler
{

template<typename T_settings>
struct atomic_counter
{
public:
using settings_type = T_settings;

public:
template<typename... T_args>
inline void execute(T_args&&...)
{ }
};

}
end_namespace_ecs_core_system_scheduler

+ 3
- 0
include/ecs/settings/scheduler.h View File

@@ -0,0 +1,3 @@
#pragma once

#include "./scheduler/atomic_counter.h"

+ 22
- 0
include/ecs/settings/scheduler/atomic_counter.h View File

@@ -0,0 +1,22 @@
#pragma once

#include <ecs/config.h>
#include <ecs/core/system/scheduler/atomic_counter.h>

beg_namespace_ecs_settings_scheduler
{

namespace __impl
{
struct atomic_counter_t
{
template<typename T_settings>
constexpr decltype(auto) operator()(T_settings) const noexcept
{ return core::system::scheduler::atomic_counter<T_settings> { }; }
};
}

constexpr decltype(auto) atomic_counter = __impl::atomic_counter_t { };

}
end_namespace_ecs_settings_scheduler

+ 11
- 1
include/ecs/settings/settings.h View File

@@ -7,6 +7,7 @@
#include "./system_storage.h"
#include "./entity_storage.h"
#include "./refresh_parallelism.h"
#include "./scheduler.h"

beg_namespace_ecs_settings
{
@@ -18,6 +19,7 @@ beg_namespace_ecs_settings
constexpr decltype(auto) system_storage = hana::size_c<2>;
constexpr decltype(auto) entity_storage = hana::size_c<3>;
constexpr decltype(auto) refresh_parallelism = hana::size_c<4>;
constexpr decltype(auto) scheduler = hana::size_c<5>;
}

namespace __impl
@@ -53,6 +55,9 @@ beg_namespace_ecs_settings
constexpr decltype(auto) refresh_parallelism() const noexcept
{ return get(keys::refresh_parallelism); }

constexpr decltype(auto) scheduler() const noexcept
{ return get(keys::scheduler); }

public: /* setter */
template<typename T>
constexpr decltype(auto) component_signatures(T t) const noexcept
@@ -73,6 +78,10 @@ beg_namespace_ecs_settings
template<typename T>
constexpr decltype(auto) refresh_parallelism(T t) const noexcept
{ return change(keys::refresh_parallelism, t); }

template<typename T>
constexpr decltype(auto) scheduler(T t) const noexcept
{ return change(keys::scheduler, t); }
};

struct make_t
@@ -85,7 +94,8 @@ beg_namespace_ecs_settings
.add(keys::system_signatures, list::empty)
.add(keys::system_storage, system_storage::tuple)
.add(keys::entity_storage, entity_storage::dynamic<1024>)
.add(keys::refresh_parallelism, refresh_parallelism::enable);
.add(keys::refresh_parallelism, refresh_parallelism::enable)
.add(keys::scheduler, scheduler::atomic_counter);
return settings_t<decay_t<decltype(options)>> { };
}
};


+ 9
- 0
include/ecs/signature_list/system.h View File

@@ -20,6 +20,15 @@ beg_namespace_ecs_signature_list_system
{ return hana::size(items); }

public: /* get */
constexpr decltype(auto) tags() const noexcept
{
return hana::unpack(
hana::transform(items, [](auto& ssig){
return core::mp::unwrap(ssig).tag();
}),
core::mp::list::make);
}

template<typename T_system_tag>
constexpr decltype(auto) get_by_tag(T_system_tag st) const noexcept
{


+ 77
- 0
include/ecs/system_execution_adapter.h View File

@@ -0,0 +1,77 @@
#pragma once

#include <ecs/config.h>

beg_namespace_ecs_system_execution_adapter
{

namespace __impl
{
template<typename T_predicate>
struct predicate_holder
{
private:
using predicate_type = T_predicate;

template<typename T_instance>
using predicate_result_type = decltype(
std::declval<predicate_type>()(
std::declval<core::mp::decay_t<T_instance>>().system()));

template<typename T_predicate_result>
using enabler = std::enable_if_t<T_predicate_result { }, void>;

public:
template<typename T_func>
constexpr decltype(auto) detailed_instance(T_func&& func) noexcept
{
return [f = std::forward<T_func>(func)](auto& instance, auto& executor)
-> enabler<predicate_result_type<decltype(instance)>>
{
f(instance, executor);
};
}

template<typename T_func>
constexpr decltype(auto) detailed(T_func&& func) noexcept
{
return detailed_instance([f = std::forward<T_func>(func)](auto& instance, auto& executor) {
f(instance.system(), executor);
});
}

template<typename T_func>
constexpr decltype(auto) for_subtasks(T_func&& func) noexcept
{
return detailed([f = std::forward<T_func>(func)](auto& system, auto& executor){
executor.for_subtasks([&system, &f](auto& data){
f(system, data);
});
});
}
};
}

template<typename T_func>
constexpr decltype(auto) matching(T_func) noexcept
{
return __impl::predicate_holder<T_func> { };
}

constexpr decltype(auto) all() noexcept
{
return matching(hana::always(hana::true_c));
}

template<typename... T_system_tags>
constexpr decltype(auto) tags(T_system_tags... tags) noexcept
{
auto tag_set = hana::make_set(tags...);
return matching([tag_set](auto& system) {
auto tag = tag::system::make(system);
return hana::contains(tag_set, tag);
});
}

}
end_namespace_ecs_system_execution_adapter

+ 13
- 8
test/dummy.cpp View File

@@ -111,16 +111,21 @@ constexpr decltype(auto) settings = ::ecs::settings::make()
.component_signatures(cs_list)
.system_signatures (ss_list);

namespace sea = ::ecs::system_execution_adapter;

TEST(DummyTest, fuu)
{
std::mutex m;
auto context = ::ecs::context::make(settings);
context.for_systems_dispatch([&m](auto& instance){
std::lock_guard l(m);
std::cout
<< std::this_thread::get_id()
<< " "
<< type_helper<decltype(instance.system())>::name()
<< std::endl;
context.step([](auto& step_proxy){
step_proxy.execute_systems()(
sea::tags(st::accelerate)
.for_subtasks([](auto& s, auto& data){
std::cout << "accelerate" << std::endl;
}),
sea::tags(st::move)
.for_subtasks([](auto& s, auto& data){
std::cout << "move" << std::endl;
})
);
});
}

Loading…
Cancel
Save