Created
March 6, 2022 04:50
-
-
Save yknishidate/eab13cf251cc815d5aa50519eb2ee385 to your computer and use it in GitHub Desktop.
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
#include <iostream> | |
#include <vector> | |
#include <string> | |
class GameObject; | |
class Component | |
{ | |
public: | |
virtual void update(GameObject &gameObject) = 0; | |
}; | |
class InputComponent : public Component | |
{ | |
public: | |
void update(GameObject &gameObject) override | |
{ | |
std::cout << "InputComponent::update()" << std::endl; | |
} | |
}; | |
class PhysicsComponent : public Component | |
{ | |
public: | |
void update(GameObject &gameObject) override | |
{ | |
std::cout << "PhysicsComponent::update()" << std::endl; | |
} | |
int getGravity() | |
{ | |
return gravity; | |
} | |
private: | |
int gravity = 10; | |
}; | |
class GameObject | |
{ | |
public: | |
int x, y; | |
void update() | |
{ | |
for (auto &component : components) | |
{ | |
component->update(*this); | |
} | |
} | |
template <class T> | |
T *addComponent() | |
{ | |
components.push_back(new T()); | |
return static_cast<T *>(components.back()); | |
} | |
template <class T> | |
T *getComponent() | |
{ | |
for (auto &base : components) | |
{ | |
T *component = dynamic_cast<T *>(base); | |
if (component) | |
{ | |
return component; | |
} | |
} | |
return nullptr; | |
} | |
private: | |
std::vector<Component *> components; | |
}; | |
int main() | |
{ | |
// Add Component | |
GameObject gameObject; | |
gameObject.addComponent<InputComponent>(); | |
gameObject.addComponent<PhysicsComponent>(); | |
gameObject.update(); | |
// Get Component | |
PhysicsComponent *physics = gameObject.getComponent<PhysicsComponent>(); | |
if (physics) | |
{ | |
std::cout << "gravity: " << physics->getGravity() << std::endl; | |
} | |
} |
Author
yknishidate
commented
Mar 14, 2022
•
- これ流石にgetComponentが遅すぎた
- unordered_mapにしても全然遅い
- ECSまでいかなくてももっとマシな実装がありそう
- 安直にMAX_COMPONENTS分メモリ確保したらだいぶ速いだろうけど、それも微妙な感じ
- そもそもポインタの配列が遅いという問題もある
- 線形探索とdynamic_castを削除したバージョン
- 10倍くらい高速化
extern int componentCount = 0;
template <typename T>
int getComponentType()
{
static int type = componentCount++;
return type;
}
struct Entity
{
template <class T>
T *addComponent()
{
int componentType = getComponentType<T>();
if (components.size() <= componentType)
{
components.resize(componentType + 1);
}
components[componentType] = new T();
return static_cast<T *>(components[componentType]);
}
template <class T>
T *getComponent()
{
int componentType = getComponentType<T>();
if (components.size() <= componentType || !components[componentType])
{
return nullptr;
}
return static_cast<T *>(components[componentType]);
}
std::vector<Component *> components;
};
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment