Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Jun 5, 2019
1 parent 605eebd commit e3521f3
Showing 1 changed file with 71 additions and 57 deletions.
128 changes: 71 additions & 57 deletions src/entt/entity/observer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,75 +17,84 @@
namespace entt {


template<typename>
class basic_observer;
template<typename...>
struct matcher;


template<typename... AnyOf>
struct matcher {
template<typename Entity>
static void disconnect(const basic_observer<Entity> &obs, const basic_registry<Entity> &reg) {
(reg->template on_replace<AnyOf>().disconnect(&obs), ...);
(reg->template on_destroy<AnyOf>().disconnect(&obs), ...);
}
};
struct matcher<type_list<AnyOf...>> {};


template<typename... AllOf, typename... NoneOf>
struct matcher<type_list<AllOf...>, type_list<NoneOf...>> {
template<typename Entity>
static void disconnect(const basic_observer<Entity> &obs, const basic_registry<Entity> &reg) {
(reg->template on_contruct<AllOf>().disconnect(&obs), ...);
(reg->template on_destroy<AllOf>().disconnect(&obs), ...);
(reg->template on_contruct<NoneOf>().disconnect(&obs), ...);
(reg->template on_destroy<NoneOf>().disconnect(&obs), ...);
}
};
struct matcher<type_list<AllOf...>, type_list<NoneOf...>> {};


template<typename... Matcher>
struct basic_collector {
template<typename...>
struct basic_collector;


template<typename... AnyOf, typename... Matcher>
struct basic_collector<matcher<type_list<AnyOf...>>, Matcher...> {
template<typename... AllOf, typename... NoneOf>
constexpr auto group(exclude_t<NoneOf...> = {}) {
return basic_collector<Matcher..., matcher<type_list<AllOf...>, type_list<NoneOf...>>>{};
return basic_collector<matcher<type_list<AnyOf...>>, Matcher..., matcher<type_list<AllOf...>, type_list<NoneOf...>>>{};
}

template<typename... AnyOf>
template<typename... Type>
constexpr auto replace() {
return basic_collector<Matcher..., matcher<type_list<AnyOf...>>>{};
return basic_collector<matcher<type_list<AnyOf..., Type...>>, Matcher...>{};
}
};


using collector = basic_collector<>;
using collector = basic_collector<matcher<>>;


template<typename Entity>
class basic_observer {
using traits_type = entt_traits<Entity>;

template<typename, typename>
struct matcher;
template<typename>
struct matcher_handler;

template<typename... AnyOf>
struct matcher_handler<matcher<type_list<AnyOf...>>> {
static void maybe_valid_if(basic_observer *obs, const basic_registry<Entity> &, const Entity entt) {
++(obs->view.has(entt) ? obs->view.get(entt) : obs->view.construct(entt));
}

static void disconnect(basic_registry<Entity> &reg, const basic_observer &obs) {
((reg.template on_replace<AnyOf>().disconnect(&obs)), ...);
}
};

template<typename... All, typename... None>
struct matcher<type_list<All...>, type_list<None...>> {
static void maybe_valid_if(storage<Entity, std::size_t> *view, const basic_registry<Entity> &reg, const Entity entt) {
if(reg.template has<All...>(entt) && !(reg.template has<None>(entt) || ...)) {
++(view->has(entt) ? view->get(entt) : view->construct(entt));
template<typename... AllOf, typename... NoneOf>
struct matcher_handler<matcher<type_list<AllOf...>, type_list<NoneOf...>>> {
static void maybe_valid_if(basic_observer *obs, const basic_registry<Entity> &reg, const Entity entt) {
if(reg.template has<AllOf...>(entt) && !(reg.template has<NoneOf>(entt) || ...)) {
++(obs->view.has(entt) ? obs->view.get(entt) : obs->view.construct(entt));
}
}

static void discard_if(storage<Entity, std::size_t> *view, const basic_registry<Entity> &reg, const Entity entt) {
if(reg.template has<All...>(entt) && !(reg.template has<None>(entt) || ...)) {
if(auto *value = view->try_get(entt); value && !--(*value)) {
view->destroy(entt);
static void discard_if(basic_observer *obs, const basic_registry<Entity> &reg, const Entity entt) {
if(reg.template has<AllOf...>(entt) && !(reg.template has<NoneOf>(entt) || ...)) {
if(auto *value = obs->view.try_get(entt); value && !--(*value)) {
obs->view.destroy(entt);
}
}
}

static void disconnect(basic_registry<Entity> &reg, const basic_observer &obs) {
((reg.template on_construct<AllOf>().disconnect(&obs)), ...);
((reg.template on_destroy<AllOf>().disconnect(&obs)), ...);
((reg.template on_construct<NoneOf>().disconnect(&obs)), ...);
((reg.template on_destroy<NoneOf>().disconnect(&obs)), ...);
}
};

void maybe_valid_if(const basic_registry<Entity> &, const Entity entt) {
++(view.has(entt) ? view.get(entt) : view.construct(entt));
template<auto... Disconnect>
static void disconnect(basic_registry<Entity> &reg, const basic_observer &obs) {
(Disconnect(reg, obs), ...);
}

public:
Expand All @@ -101,7 +110,11 @@ class basic_observer {
: target{&reg}
{
// TODO unpack matcher
// TODO generate disconnect
release = &disconnect<&matcher_handler<Matcher>::disconnect...>();
}

~basic_observer() {
// TODO disconnect
}

size_type size() const ENTT_NOEXCEPT {
Expand All @@ -124,32 +137,33 @@ class basic_observer {
return view.sparse_set<entity_type>::end();
}

template<typename... All, typename... None>
auto all_of(basic_registry<Entity> &reg, exclude_t<None...> = {}) {
(reg.template on_construct<All>().template connect<matcher<type_list<All...>, type_list<None...>>::maybe_valid_if>(&view), ...);
(reg.template on_destroy<None>().template connect<matcher<type_list<All...>, type_list<None...>>::maybe_valid_if>(&view), ...);
(reg.template on_destroy<All>().template connect<matcher<type_list<All...>, type_list<None...>>::discard_if>(&view), ...);
(reg.template on_construct<None>().template connect<matcher<type_list<All...>, type_list<None...>>::discard_if>(&view), ...);
}

template<typename... Type>
void observe(basic_registry<Entity> &reg) {
(reg.template on_replace<Type>().template connect<&basic_observer::maybe_valid_if>(this), ...);
}

template<typename... Type>
void disconnect(basic_registry<Entity> &reg) {
((reg.template on_construct<Type>().disconnect(this)), ...);
((reg.template on_destroy<Type>().disconnect(this)), ...);
((reg.template on_replace<Type>().disconnect(this)), ...);
}
// TODO template<typename... All, typename... None>
// TODO auto all_of(basic_registry<Entity> &reg, exclude_t<None...> = {}) {
// TODO (reg.template on_construct<All>().template connect<matcher<type_list<All...>, type_list<None...>>::maybe_valid_if>(&view), ...);
// TODO (reg.template on_destroy<None>().template connect<matcher<type_list<All...>, type_list<None...>>::maybe_valid_if>(&view), ...);
// TODO (reg.template on_destroy<All>().template connect<matcher<type_list<All...>, type_list<None...>>::discard_if>(&view), ...);
// TODO (reg.template on_construct<None>().template connect<matcher<type_list<All...>, type_list<None...>>::discard_if>(&view), ...);
// TODO }
// TODO
// TODO template<typename... Type>
// TODO void observe(basic_registry<Entity> &reg) {
// TODO (reg.template on_replace<Type>().template connect<&basic_observer::maybe_valid_if>(this), ...);
// TODO }
// TODO
// TODO template<typename... Type>
// TODO void disconnect(basic_registry<Entity> &reg) {
// TODO ((reg.template on_construct<Type>().disconnect(this)), ...);
// TODO ((reg.template on_destroy<Type>().disconnect(this)), ...);
// TODO ((reg.template on_replace<Type>().disconnect(this)), ...);
// TODO }

void reset() {
return view.reset();
}

private:
basic_registry<entity_type> *target;
void(* release)(basic_registry<Entity> &, const basic_observer &);
storage<entity_type, std::size_t> view;
};

Expand Down

0 comments on commit e3521f3

Please sign in to comment.