컴포넌트는 디자인 패턴의 한 종류인데, 지금 개발 중인 엔진에 해당 패턴이 적용되어 있다.
엔진에서 돌아가는 시스템의 단위는 컴포넌트를 상속하여 구현하였는지에 따라 달라진다.
다음의 코드를 보면 컴포넌트의 간단한 구조를 알 수 있다.
namespace trigger
{
class transform;
class component;
//런타임 중 Instancing 이 가능한 클래스는 해당 Map 에 들어있어야만 한다.
// 등록을 위한 매크로는 REGI_CLASS 이다.
// 생성하기 위해 만들어지는
static std::map<std::string, trigger::transform*> CLASS_ARRAY =
std::map<std::string, trigger::transform*>();
class component
{
protected:
//해당 클래스의 변수들 중 Engine이 Save, Control 할 수 있는 대상들
std::shared_ptr<cpptoml::table> _params;
std::shared_ptr<cpptoml::table> _tmp;
//클래스의 이름을 hash_code 만들어 보관함
size_t type_code;
//클래스의 이름이 들어있음
std::string type_name;
//생성된 ID - 생성시 만들어짐
int instance_id;
public:
//World 에서 해당 객체의 Update 여부를 확인하는 용도
bool active = true;
public:
component();
//상속시 해당 생성자를 호출하여 T_CLASS 를 넘겨주면 된다.
component( std::string type );
//클래스에서 추가적으로 저장해야 할 변수가 생길 시 구현
virtual void save();
virtual ~component();
size_t get_type_id();
std::string get_type_name();
// Save 시 사용할 TOML Table
auto get_params()->decltype(_params);
// 해당 객체를 업데이트 해야 할 경우 자손이 구현
virtual void update(float delta) noexcept = 0;
};
}
아래의 코드는 위의 컴포넌트를 상속 & 구현한 transform 클래스 입니다.
#include "component.h"
static int make_hash_code();
namespace trigger
{
class component;
class transform;
//CLASS_ARRAY 에 들어있는 값을 찾아 복사한다.
static auto instance(std::string type) -> decltype(auto)
{
decltype(trigger::CLASS_ARRAY[type]) tmp = trigger::CLASS_ARRAY[type];
return tmp;
};
class transform : public trigger::component
{
protected:
vec3 real_position;
vec3 real_scale;
vec3 real_rotation;
std::vector<trigger::component*> components;
std::string name;
public:
vec3 position;
vec3 scale;
vec3 rotation;
bool active;
float time_scale = 1.0f;
transform
(
vec3 pos = vec3(0.0f, 0.0f, 0.0f),
vec3 scale = vec3(1.0f, 1.0f, 1.0f),
vec3 rot = vec3(0.0f, 0.0f, 0.0f),
std::string name = "Object"
) : trigger::component(T_CLASS)
{
save();
};
std::shared_ptr<cpptoml::table> get_component_toml(std::vector<trigger::component*> vec);
std::string get_string_from_table(std::shared_ptr<cpptoml::table> table);
void set_name(std::string name);
std::string get_name();
void set_instance_id(int code);
virtual void save()
{
SAVE_TOML(components, get_component_toml(components));
SAVE_STR(name, name);
SAVE_STR(real_position , glm::to_string(real_position));
SAVE_VAR(size_t, type_code);
SAVE_STR(data, cast<char*>(this));
}
virtual ~transform();
void update(float delta) noexcept;
template<typename T>
T* get_component();
template<typename T>
bool add_component();
template<typename T>
bool add_component(T* component);
const int get_instance_id() const;
auto get_components() const;
};
};