-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
317 changed files
with
2,217 additions
and
43,214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,4 @@ | |
# Directories | ||
cmake/ | ||
cmake-build-debug/ | ||
*.TMP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[submodule "putils"] | ||
path = putils | ||
url = git@github.com:phiste/putils | ||
url = git@github.com:phisko/putils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,72 @@ | ||
// | ||
// Created by naliwe on 6/24/16. | ||
// | ||
|
||
#pragma once | ||
|
||
#include <string> | ||
#include "IComponent.hpp" | ||
#ifndef NDEBUG | ||
#include <iostream> | ||
#include "reflection/Reflectible.hpp" | ||
#endif | ||
|
||
#include <cstddef> | ||
#include <unordered_map> | ||
#include <memory> | ||
#include <vector> | ||
#include "meta/type.hpp" | ||
|
||
namespace kengine { | ||
template<typename CRTP, typename ...DataPackets> | ||
class Component : public IComponent, public putils::Module<CRTP, DataPackets...> { | ||
public: | ||
pmeta::type_index getType() const noexcept final { return pmeta::type<CRTP>::index; } | ||
}; | ||
namespace detail { | ||
static constexpr size_t INVALID = (size_t)-1; | ||
|
||
struct MetadataBase { | ||
virtual ~MetadataBase() = default; | ||
}; | ||
using GlobalCompMap = std::unordered_map<pmeta::type_index, std::unique_ptr<MetadataBase>>; | ||
static inline GlobalCompMap * components = nullptr; | ||
} | ||
|
||
template<typename Comp> | ||
class Component { | ||
private: | ||
struct Metadata : detail::MetadataBase { | ||
std::vector<Comp> array; | ||
size_t id = detail::INVALID; | ||
}; | ||
|
||
public: | ||
static inline Comp & get(size_t id) { auto & meta = metadata(); | ||
while (id >= meta.array.size()) | ||
meta.array.resize(meta.array.size() * 2); | ||
return meta.array[id]; | ||
} | ||
|
||
static inline size_t id() { | ||
static const size_t ret = metadata().id; | ||
return ret; | ||
} | ||
|
||
|
||
private: | ||
static inline Metadata & metadata() { | ||
static Metadata * ret = nullptr; | ||
|
||
if (ret == nullptr) { | ||
const auto typeIndex = pmeta::type<Comp>::index; | ||
const auto it = detail::components->find(typeIndex); | ||
if (it != detail::components->end()) | ||
ret = static_cast<Metadata *>(it->second.get()); | ||
else { | ||
auto ptr = std::make_unique<Metadata>(); | ||
ret = static_cast<Metadata *>(ptr.get()); | ||
(*detail::components)[typeIndex] = std::move(ptr); | ||
ret->id = detail::components->size() - 1; | ||
ret->array.resize(64); | ||
|
||
#ifndef NDEBUG | ||
if constexpr (putils::is_reflectible<Comp>::value) | ||
std::cout << ret->id << ' ' << Comp::get_class_name() << '\n'; | ||
#endif | ||
} | ||
} | ||
|
||
return *ret; | ||
} | ||
}; | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#pragma once | ||
|
||
#include <bitset> | ||
#include <cstddef> | ||
#include "Component.hpp" | ||
#include "reflection/Reflectible.hpp" | ||
|
||
#ifndef KENGINE_COMPONENT_COUNT | ||
# define KENGINE_COMPONENT_COUNT 64 | ||
#endif | ||
|
||
namespace kengine { | ||
class EntityManager; | ||
|
||
class EntityView { | ||
public: | ||
using ID = size_t; | ||
using Mask = std::bitset<KENGINE_COMPONENT_COUNT>; | ||
static constexpr auto INVALID_ID = detail::INVALID; | ||
|
||
EntityView(ID id = INVALID_ID, Mask componentMask = 0) : id(id), componentMask(componentMask) {} | ||
|
||
~EntityView() = default; | ||
EntityView(const EntityView &) = default; | ||
EntityView & operator=(const EntityView & rhs) = default; | ||
|
||
public: | ||
template<typename T> | ||
T & get() { | ||
assert("No such component" && has<T>()); | ||
return Component<T>::get(id); | ||
} | ||
template<typename T> | ||
const T & get() const { | ||
assert("No such component" && has<T>()); | ||
return Component<T>::get(id); | ||
} | ||
|
||
template<typename T> | ||
bool has() const { | ||
return componentMask.test(getId<T>()); | ||
} | ||
|
||
ID id; | ||
Mask componentMask = 0; | ||
|
||
protected: | ||
template<typename T> | ||
size_t getId() const { | ||
static const auto id = Component<T>::id(); | ||
assert("You are using too many component types" && id < KENGINE_COMPONENT_COUNT); | ||
return id; | ||
} | ||
|
||
public: | ||
pmeta_get_class_name(EntityView); | ||
pmeta_get_attributes( | ||
pmeta_reflectible_attribute(&EntityView::id), | ||
pmeta_reflectible_attribute(&EntityView::componentMask) | ||
); | ||
pmeta_get_methods(); | ||
pmeta_get_parents(); | ||
}; | ||
|
||
class Entity : public EntityView { | ||
public: | ||
Entity(ID id = detail::INVALID, Mask componentMask = 0, EntityManager * manager = nullptr) : EntityView(id, componentMask), manager(manager) {} | ||
~Entity() = default; | ||
Entity(const Entity &) = default; | ||
Entity & operator=(const Entity & rhs) { | ||
id = rhs.id; | ||
componentMask = rhs.componentMask; | ||
return *this; | ||
} | ||
|
||
template<typename T> | ||
Entity & operator+=(T && comp) { | ||
attach<T>() = FWD(comp); | ||
return *this; | ||
} | ||
|
||
template<typename T> | ||
T & attach(); | ||
|
||
template<typename T> | ||
void detach(); | ||
|
||
private: | ||
EntityManager * manager; | ||
}; | ||
} | ||
|
||
#include "EntityManager.hpp" | ||
|
||
template<typename T> | ||
T & kengine::Entity::attach() { | ||
componentMask.set(getId<T>(), true); | ||
manager->updateMask(id, componentMask); | ||
return get<T>(); | ||
} | ||
|
||
template<typename T> | ||
void kengine::Entity::detach() { | ||
assert("No such component" && has<T>()); | ||
componentMask.set(getId<T>(), false); | ||
manager->updateMask(id, componentMask); | ||
} |
Oops, something went wrong.