feat support reflection
This commit is contained in:
parent
fd8ae6c6bd
commit
6566f11269
2
3rdparty/sled
vendored
2
3rdparty/sled
vendored
@ -1 +1 @@
|
|||||||
Subproject commit fcce11249be00ca0c7f8c2e75938de4b3e5f26da
|
Subproject commit 4402688c9c63e9885de1bf99cd718150b036ac7a
|
@ -18,6 +18,8 @@ add_executable(meta
|
|||||||
src/types/field.cc
|
src/types/field.cc
|
||||||
src/types/method.cc
|
src/types/method.cc
|
||||||
src/registry.cc
|
src/registry.cc
|
||||||
|
runtime/test.gen.cc
|
||||||
|
runtime/reflection.gen.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
### add clang
|
### add clang
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef META_APPLY_H
|
|
||||||
#define META_APPLY_H
|
|
||||||
#include <functional>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
namespace meta {
|
|
||||||
namespace reflection {
|
|
||||||
namespace detail {
|
|
||||||
template<int... Seq>
|
|
||||||
struct Sequence {};
|
|
||||||
|
|
||||||
template<int N, int... Seq>
|
|
||||||
struct MakeSeq : MakeSeq<N - 1, N - 1, Seq...> {};
|
|
||||||
|
|
||||||
template<int... Seq>
|
|
||||||
struct MakeSeq<0, Seq...> {
|
|
||||||
using type = Sequence<Seq...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ReturnT, typename Func, typename Tuple, int... Seq>
|
|
||||||
ReturnT
|
|
||||||
ApplyImpl(const Func &func, const Tuple &tuple, const Sequence<Seq...> &)
|
|
||||||
{
|
|
||||||
return std::bind(func, std::get<Seq>(tuple)...)();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VoidTag {};
|
|
||||||
|
|
||||||
}// namespace detail
|
|
||||||
|
|
||||||
template<typename ReturnT,
|
|
||||||
typename Func,
|
|
||||||
typename Tuple,
|
|
||||||
typename std::enable_if<!std::is_void<ReturnT>::value, ReturnT>::type * = nullptr>
|
|
||||||
ReturnT
|
|
||||||
apply(const Func &func, const Tuple &tuple)
|
|
||||||
{
|
|
||||||
return detail::ApplyImpl<ReturnT>(
|
|
||||||
func,
|
|
||||||
tuple,
|
|
||||||
typename detail::MakeSeq<std::tuple_size<Tuple>::value>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnT = void,
|
|
||||||
typename Func,
|
|
||||||
typename Tuple,
|
|
||||||
typename std::enable_if<std::is_void<ReturnT>::value, detail::VoidTag>::type * = nullptr>
|
|
||||||
ReturnT
|
|
||||||
apply(const Func &func, const Tuple &tuple)
|
|
||||||
{
|
|
||||||
return detail::ApplyImpl<ReturnT>(
|
|
||||||
func,
|
|
||||||
tuple,
|
|
||||||
typename detail::MakeSeq<std::tuple_size<Tuple>::value>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace reflection
|
|
||||||
}// namespace meta
|
|
||||||
#endif// META_APPLY_H
|
|
5
runtime/reflection.gen.cc
Normal file
5
runtime/reflection.gen.cc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "test.gen.h"
|
||||||
|
|
||||||
|
void ::meta::reflection::Registry::RegisterAll() { ::test::Test::Test_Class::Register(); }
|
||||||
|
|
||||||
|
void ::meta::reflection::Registry::UnregisterAll() {}
|
@ -2,7 +2,6 @@
|
|||||||
#ifndef META_RUNTIME_REFLECTION_H
|
#ifndef META_RUNTIME_REFLECTION_H
|
||||||
#define META_RUNTIME_REFLECTION_H
|
#define META_RUNTIME_REFLECTION_H
|
||||||
#include "any.h"
|
#include "any.h"
|
||||||
#include "apply.h"
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
#include <sled/log/log.h>
|
#include <sled/log/log.h>
|
||||||
@ -42,7 +41,7 @@ RemoveTypeSpace(const std::string &str, const std::string &chars = "[]()<>*&:")
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U = typename std::decay<T>::type>
|
template<typename T, typename U = typename std::decay<T>::type>
|
||||||
std::string
|
inline std::string
|
||||||
PrettyNameImpl()
|
PrettyNameImpl()
|
||||||
{
|
{
|
||||||
const std::string name = typeid(U).name();
|
const std::string name = typeid(U).name();
|
||||||
@ -71,13 +70,20 @@ PrettyName()
|
|||||||
#define META(...)
|
#define META(...)
|
||||||
#define CLASS(class_name, ...) class class_name
|
#define CLASS(class_name, ...) class class_name
|
||||||
#define STRUCT(struct_name, ...) struct struct_name
|
#define STRUCT(struct_name, ...) struct struct_name
|
||||||
#endif// __REFLECTION_PARSER_
|
#endif// __REFLECTION_PARSER_ \
|
||||||
|
|
||||||
#define META_REFLECTION_BODY(class_name) \
|
#define META_REFLECTION_BODY(class_name) \
|
||||||
friend class meta::reflection::##class_name##_Method; \
|
class class_name##_Class; \
|
||||||
friend class meta::reflection::##class_name##_Field; \
|
class class_name##_Constructor; \
|
||||||
friend class meta::reflection::##class_name##_Constructor; \
|
class class_name##_Method; \
|
||||||
friend class meta::reflection::##class_name##_Serializer;
|
class class_name##_Field; \
|
||||||
|
class class_name##_Serializer; \
|
||||||
|
friend class class_name##_Class; \
|
||||||
|
friend class class_name##_Constructor; \
|
||||||
|
friend class class_name##_Method; \
|
||||||
|
friend class class_name##_Field; \
|
||||||
|
friend class class_name##_Serializer; \
|
||||||
|
friend class ::meta::reflection::Registry;
|
||||||
|
|
||||||
class Constructor;
|
class Constructor;
|
||||||
class Method;
|
class Method;
|
||||||
@ -113,7 +119,7 @@ public:
|
|||||||
typename... Params>
|
typename... Params>
|
||||||
inline ReturnT InvokeAndCast(void *instance, Params &&...params) const
|
inline ReturnT InvokeAndCast(void *instance, Params &&...params) const
|
||||||
{
|
{
|
||||||
return ::meta::reflection::any_cast<ReturnT>(InvokeImpl(instance, {¶ms...}));
|
return ::meta::reflection::any_cast<ReturnT>(InvokeImpl(instance, {params...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ReturnT,
|
template<typename ReturnT,
|
||||||
@ -121,18 +127,18 @@ public:
|
|||||||
typename... Params>
|
typename... Params>
|
||||||
inline void InvokeAndCast(void *instance, Params &&...params) const
|
inline void InvokeAndCast(void *instance, Params &&...params) const
|
||||||
{
|
{
|
||||||
::meta::reflection::any_cast<ReturnT>(InvokeImpl(instance, {¶ms...}));
|
::meta::reflection::any_cast<ReturnT>(InvokeImpl(instance, {params...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Params>
|
template<typename... Params>
|
||||||
inline ::meta::reflection::any Invoke(void *instance, Params &&...params) const
|
inline ::meta::reflection::any Invoke(void *instance, Params &&...params) const
|
||||||
{
|
{
|
||||||
return InvokeImpl(instance, {¶ms...});
|
return InvokeImpl(instance, {params...});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ::meta::reflection::any InvokeImpl(void *instance,
|
virtual ::meta::reflection::any
|
||||||
const std::vector<void *> ¶ms) const
|
InvokeImpl(void *instance, const std::vector<::meta::reflection::any> ¶ms) const
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -167,23 +173,106 @@ public:
|
|||||||
Class(const std::string &name, std::shared_ptr<Class> base_class = nullptr)
|
Class(const std::string &name, std::shared_ptr<Class> base_class = nullptr)
|
||||||
: BaseType(name, base_class)
|
: BaseType(name, base_class)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
inline std::vector<std::shared_ptr<Class>> GetBaseClasses() const { return base_classes_; }
|
||||||
|
|
||||||
|
inline std::shared_ptr<Class> GetBaseClass(const std::string &name) const
|
||||||
|
{
|
||||||
|
auto iter = base_class_by_name_.find(name);
|
||||||
|
if (iter != base_class_by_name_.end()) { return iter->second; }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<std::shared_ptr<Method>> GetMethods() const { return methods_; }
|
||||||
|
|
||||||
|
inline std::shared_ptr<Method> GetMethod(const std::string &name) const
|
||||||
|
{
|
||||||
|
auto iter = method_by_name_.find(name);
|
||||||
|
if (iter != method_by_name_.end()) { return iter->second; }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<std::shared_ptr<Field>> GetFields() const { return fields_; }
|
||||||
|
|
||||||
|
inline std::shared_ptr<Field> GetField(const std::string &name) const
|
||||||
|
{
|
||||||
|
auto iter = field_by_name_.find(name);
|
||||||
|
if (iter != field_by_name_.end()) { return iter->second; }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void AddBaseClass(std::shared_ptr<Class> clz)
|
||||||
|
{
|
||||||
|
if (base_class_by_name_.find(clz->Name()) != base_class_by_name_.end()) { return; }
|
||||||
|
base_classes_.push_back(clz);
|
||||||
|
base_class_by_name_[clz->Name()] = clz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddMethod(std::shared_ptr<Method> method)
|
||||||
|
{
|
||||||
|
if (method_by_name_.find(method->Name()) != method_by_name_.end()) { return; }
|
||||||
|
methods_.push_back(method);
|
||||||
|
method_by_name_[method->Name()] = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddField(std::shared_ptr<Field> field)
|
||||||
|
{
|
||||||
|
fields_.push_back(field);
|
||||||
|
field_by_name_[field->Name()] = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Class>> base_class_by_name_;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Method>> method_by_name_;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Field>> field_by_name_;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Class>> base_classes_;
|
||||||
|
std::vector<std::shared_ptr<Method>> methods_;
|
||||||
|
std::vector<std::shared_ptr<Field>> fields_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define REFLECTION_BODY() \
|
class Registry {
|
||||||
friend class meta::Serializer; \
|
|
||||||
friend class meta::Class; \
|
|
||||||
friend class meta::Method; \
|
|
||||||
friend class meta::Field; \
|
|
||||||
friend class meta::Constructor;
|
|
||||||
|
|
||||||
class Reflectioin {
|
|
||||||
public:
|
public:
|
||||||
static Reflectioin *Instance();
|
static Registry *Instance()
|
||||||
~Reflectioin();
|
{
|
||||||
std::shared_ptr<Class> GetClass();
|
static Registry instance;
|
||||||
// std::shared_ptr<Constructor> GetConstructor(std::shared_ptr<Class> clz);
|
return &instance;
|
||||||
std::shared_ptr<Method> GetMethod(std::shared_ptr<Class> clz);
|
}
|
||||||
std::shared_ptr<Field> GetField(std::shared_ptr<Class> clz);
|
|
||||||
|
~Registry() {}
|
||||||
|
|
||||||
|
static void RegisterAll();
|
||||||
|
static void UnregisterAll();
|
||||||
|
|
||||||
|
static std::shared_ptr<Class> GetClass(const std::string &name)
|
||||||
|
{
|
||||||
|
return Instance()->GetClassInner(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RegisterClass(std::shared_ptr<Class> clz) { Instance()->RegisterClassInner(clz); }
|
||||||
|
|
||||||
|
static std::vector<std::shared_ptr<Class>> GetClasses() { return Instance()->classes(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Class> GetClassInner(const std::string &name) const
|
||||||
|
{
|
||||||
|
auto iter = class_by_name_.find(name);
|
||||||
|
if (iter != class_by_name_.end()) { return iter->second; }
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RegisterClassInner(std::shared_ptr<Class> clz)
|
||||||
|
{
|
||||||
|
if (class_by_name_.find(clz->Name()) != class_by_name_.end()) { return; }
|
||||||
|
classes_.push_back(clz);
|
||||||
|
class_by_name_[clz->Name()] = clz;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<std::shared_ptr<Class>> classes() const { return classes_; }
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Class>> class_by_name_;
|
||||||
|
std::vector<std::shared_ptr<Class>> classes_;
|
||||||
};
|
};
|
||||||
}// namespace reflection
|
}// namespace reflection
|
||||||
|
|
||||||
|
90
runtime/test.gen.cc
Normal file
90
runtime/test.gen.cc
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "test.gen.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class
|
||||||
|
**/
|
||||||
|
test::Test::Test_Class::Test_Class()
|
||||||
|
: ::meta::reflection::Class("test::Test", nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void test::Test::Test_Class::Register() {
|
||||||
|
auto self = new test::Test::Test_Class();
|
||||||
|
auto clz = std::shared_ptr<::meta::reflection::Class>(self);
|
||||||
|
// self->AddBaseClassProxy();
|
||||||
|
|
||||||
|
self->AddMethod(std::make_shared<test::Test::Test_Method>("size", clz));
|
||||||
|
self->AddMethod(std::make_shared<test::Test::Test_Method>("length", clz));
|
||||||
|
|
||||||
|
self->AddField(std::make_shared<test::Test::Test_Field>("length_", clz));
|
||||||
|
self->AddField(std::make_shared<test::Test::Test_Field>("size_", clz));
|
||||||
|
|
||||||
|
::meta::reflection::Registry::Instance()->RegisterClass(clz);
|
||||||
|
}
|
||||||
|
void test::Test::Test_Class::AddBaseClassProxy(std::shared_ptr<::meta::reflection::Class> base) {
|
||||||
|
AddBaseClass(base);
|
||||||
|
}
|
||||||
|
void test::Test::Test_Class::AddMethodProxy(std::shared_ptr<::meta::reflection::Method> method) {
|
||||||
|
AddMethod(method);
|
||||||
|
}
|
||||||
|
void test::Test::Test_Class::AddFieldProxy(std::shared_ptr<::meta::reflection::Field> field) {
|
||||||
|
AddField(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field
|
||||||
|
**/
|
||||||
|
|
||||||
|
test::Test::Test_Field::Test_Field(
|
||||||
|
const std::string& name,
|
||||||
|
std::shared_ptr<::meta::reflection::Class> parent)
|
||||||
|
: ::meta::reflection::Field(name, parent) {}
|
||||||
|
|
||||||
|
::meta::reflection::any test::Test::Test_Field::GetImpl(void* instance) const {
|
||||||
|
::test::Test* obj = (::test::Test*)instance;
|
||||||
|
|
||||||
|
if (strcmp(Name().c_str(), "length_") == 0) {
|
||||||
|
return obj->length_;
|
||||||
|
}
|
||||||
|
if (strcmp(Name().c_str(), "size_") == 0) {
|
||||||
|
return obj->size_;
|
||||||
|
}
|
||||||
|
return ::meta::reflection::any{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void test::Test::Test_Field::SetImpl(void* instance, const ::meta::reflection::any& value) const {
|
||||||
|
::test::Test* obj = (::test::Test*)instance;
|
||||||
|
if(strcmp(Name().c_str(), "length_") == 0) { obj->length_ = ::meta::reflection::any_cast<int>(value);}
|
||||||
|
if(strcmp(Name().c_str(), "size_") == 0) { obj->size_ = ::meta::reflection::any_cast<int>(value);}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method
|
||||||
|
**/
|
||||||
|
test::Test::Test_Method::Test_Method(
|
||||||
|
const std::string& name,
|
||||||
|
std::shared_ptr<::meta::reflection::Class> parent)
|
||||||
|
: ::meta::reflection::Method(name, parent) {}
|
||||||
|
|
||||||
|
::meta::reflection::any test::Test::Test_Method::InvokeImpl(void* instance, const std::vector<::meta::reflection::any> ¶ms) const {
|
||||||
|
::test::Test* obj = (::test::Test*)instance;
|
||||||
|
|
||||||
|
if (strcmp(Name().c_str(), "size") == 0) {
|
||||||
|
return
|
||||||
|
obj->
|
||||||
|
size(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (strcmp(Name().c_str(), "length") == 0) {
|
||||||
|
return
|
||||||
|
obj->
|
||||||
|
length(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return ::meta::reflection::any{};
|
||||||
|
}
|
||||||
|
|
41
runtime/test.gen.h
Normal file
41
runtime/test.gen.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef META_GEN_Test_PROXY_H
|
||||||
|
#define META_GEN_Test_PROXY_H
|
||||||
|
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
// namespace meta {
|
||||||
|
// namespace reflection {
|
||||||
|
|
||||||
|
class ::test::Test::Test_Class : public ::meta::reflection::Class {
|
||||||
|
public:
|
||||||
|
Test_Class();
|
||||||
|
static void Register();
|
||||||
|
private:
|
||||||
|
void AddBaseClassProxy(std::shared_ptr<::meta::reflection::Class> base) ;
|
||||||
|
void AddMethodProxy(std::shared_ptr<::meta::reflection::Method> method) ;
|
||||||
|
void AddFieldProxy(std::shared_ptr<::meta::reflection::Field> field) ;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ::test::Test::Test_Field : public ::meta::reflection::Field {
|
||||||
|
public:
|
||||||
|
Test_Field(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
::meta::reflection::any GetImpl(void* instance) const override;
|
||||||
|
void SetImpl(void* instance, const ::meta::reflection::any& value) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ::test::Test::Test_Method : public ::meta::reflection::Method {
|
||||||
|
public:
|
||||||
|
Test_Method(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
::meta::reflection::any InvokeImpl(void* instance, const std::vector<::meta::reflection::any> ¶ms) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// } // namespace reflection
|
||||||
|
// } // namespace meta
|
||||||
|
|
||||||
|
#endif // META_GEN_Test_PROXY_H
|
||||||
|
|
@ -3,38 +3,25 @@
|
|||||||
#define META_RUNTIME_TEST_H
|
#define META_RUNTIME_TEST_H
|
||||||
|
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace test {
|
namespace test {
|
||||||
class TypeDef {};
|
|
||||||
|
|
||||||
CLASS(Test)
|
CLASS(Test)
|
||||||
{
|
{
|
||||||
|
META_REFLECTION_BODY(Test);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
META("Constructor")
|
Test() {}
|
||||||
Test() : b_(0), a_(0) {}
|
|
||||||
|
|
||||||
Test(int a) : b_(0), a_(a) {}
|
const size_t size() const { return size_; }
|
||||||
|
const size_t length() const { return length_; }
|
||||||
META("Test")
|
|
||||||
int GetA() const { return a_; }
|
|
||||||
|
|
||||||
int kk(int, void *);
|
|
||||||
TypeDef GetTypeDef() const { return type_def_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Void {};
|
META("1")
|
||||||
|
int length_;
|
||||||
|
|
||||||
STRUCT(VoidMeta, "VoidMeta")
|
META("2")
|
||||||
{
|
int size_;
|
||||||
META("Enable")
|
|
||||||
int a;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int b_;
|
|
||||||
int a_;
|
|
||||||
|
|
||||||
META("TypeDef")
|
|
||||||
TypeDef type_def_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace test
|
}// namespace test
|
||||||
|
@ -59,6 +59,7 @@ Parser::Parse(const std::string &file_name, std::vector<const char *> extra_args
|
|||||||
|
|
||||||
// ignore error for reflection.h
|
// ignore error for reflection.h
|
||||||
if (sled::EndsWith(filename, "reflection.h")) { continue; }
|
if (sled::EndsWith(filename, "reflection.h")) { continue; }
|
||||||
|
if (sled::EndsWith(filename, "any.h")) { continue; }
|
||||||
|
|
||||||
LOGE("parser", "diagnostic: {}", msg);
|
LOGE("parser", "diagnostic: {}", msg);
|
||||||
}
|
}
|
||||||
|
@ -39,19 +39,38 @@ BaseGenerator::GenClassRenderData(Class *clz, inja::json &class_def)
|
|||||||
class_def["properties"] = inja::json::array();
|
class_def["properties"] = inja::json::array();
|
||||||
for (auto &prop : clz->properties()) { class_def["properties"].push_back(prop); }
|
for (auto &prop : clz->properties()) { class_def["properties"].push_back(prop); }
|
||||||
|
|
||||||
|
inja::json constructors = inja::json::array();
|
||||||
inja::json methods = inja::json::array();
|
inja::json methods = inja::json::array();
|
||||||
inja::json fields = inja::json::array();
|
inja::json fields = inja::json::array();
|
||||||
|
|
||||||
|
GenClassConstructorRenderData(clz, constructors);
|
||||||
GenClassMethodRenderData(clz, methods);
|
GenClassMethodRenderData(clz, methods);
|
||||||
GenClassFieldRenderData(clz, fields);
|
GenClassFieldRenderData(clz, fields);
|
||||||
|
|
||||||
|
class_def["class_constructors"] = constructors;
|
||||||
class_def["class_methods"] = methods;
|
class_def["class_methods"] = methods;
|
||||||
class_def["class_fields"] = fields;
|
class_def["class_fields"] = fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseGenerator::GenClassConstructorRenderData(Class *clz, inja::json &constructor_defs)
|
BaseGenerator::GenClassConstructorRenderData(Class *clz, inja::json &constructor_defs)
|
||||||
{}
|
{
|
||||||
|
for (auto &constructor : clz->constructors()) {
|
||||||
|
inja::json constructor_def;
|
||||||
|
constructor_def["name"] = constructor->Name();
|
||||||
|
constructor_def["properties"] = inja::json::array();
|
||||||
|
for (auto &prop : constructor->properties()) {
|
||||||
|
constructor_def["properties"].push_back(prop);
|
||||||
|
}
|
||||||
|
inja::json params = inja::json::array();
|
||||||
|
for (auto ¶m : constructor->arguments()) {
|
||||||
|
inja::json param_def;
|
||||||
|
param_def["name"] = "";
|
||||||
|
param_def["type"] = param.GetDisplayName();
|
||||||
|
params.push_back(param_def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseGenerator::GenClassFieldRenderData(Class *clz, inja::json &field_defs)
|
BaseGenerator::GenClassFieldRenderData(Class *clz, inja::json &field_defs)
|
||||||
@ -60,6 +79,7 @@ BaseGenerator::GenClassFieldRenderData(Class *clz, inja::json &field_defs)
|
|||||||
inja::json field_def;
|
inja::json field_def;
|
||||||
field_def["name"] = field->Name();
|
field_def["name"] = field->Name();
|
||||||
field_def["is_const"] = field->IsConst();
|
field_def["is_const"] = field->IsConst();
|
||||||
|
field_def["is_static"] = field->IsStatic();
|
||||||
field_def["properties"] = inja::json::array();
|
field_def["properties"] = inja::json::array();
|
||||||
for (auto &prop : field->properties()) { field_def["properties"].push_back(prop); }
|
for (auto &prop : field->properties()) { field_def["properties"].push_back(prop); }
|
||||||
field_def["type"] = field->cursor().GetType().GetDisplayName();
|
field_def["type"] = field->cursor().GetType().GetDisplayName();
|
||||||
@ -73,9 +93,10 @@ BaseGenerator::GenClassMethodRenderData(Class *clz, inja::json &method_defs)
|
|||||||
for (auto &method : clz->methods()) {
|
for (auto &method : clz->methods()) {
|
||||||
inja::json method_def;
|
inja::json method_def;
|
||||||
method_def["name"] = method->Name();
|
method_def["name"] = method->Name();
|
||||||
|
method_def["is_const"] = method->IsConst();
|
||||||
|
method_def["is_static"] = method->IsStatic();
|
||||||
method_def["properties"] = inja::json::array();
|
method_def["properties"] = inja::json::array();
|
||||||
for (auto &prop : method->properties()) { method_def["properties"].push_back(prop); }
|
for (auto &prop : method->properties()) { method_def["properties"].push_back(prop); }
|
||||||
method_def["is_const"] = method->IsConst();
|
|
||||||
method_def["return_type"] = method->return_type().GetDisplayName();
|
method_def["return_type"] = method->return_type().GetDisplayName();
|
||||||
inja::json params = inja::json::array();
|
inja::json params = inja::json::array();
|
||||||
for (auto ¶m : method->arguments()) {
|
for (auto ¶m : method->arguments()) {
|
||||||
|
151
src/main.cc
151
src/main.cc
@ -1,6 +1,7 @@
|
|||||||
#include "generators/base_generator.h"
|
#include "generators/base_generator.h"
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
|
#include "test.gen.h"
|
||||||
#include "types/class.h"
|
#include "types/class.h"
|
||||||
#include "clang/parser.h"
|
#include "clang/parser.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -15,12 +16,13 @@ const char *kTag = "main";
|
|||||||
|
|
||||||
class Generator : public meta::BaseGenerator {
|
class Generator : public meta::BaseGenerator {
|
||||||
public:
|
public:
|
||||||
Generator(const std::string &template_path)
|
Generator(const std::string &template_path, const std::string &output_path = "")
|
||||||
{
|
{
|
||||||
std::fstream in(template_path, std::ios::in);
|
std::fstream in(template_path, std::ios::in);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << in.rdbuf();
|
ss << in.rdbuf();
|
||||||
template_ = ss.str();
|
template_ = ss.str();
|
||||||
|
output_path_ = output_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Generator() override = default;
|
~Generator() override = default;
|
||||||
@ -33,9 +35,51 @@ public:
|
|||||||
inja::Environment env;
|
inja::Environment env;
|
||||||
env.set_trim_blocks(true);
|
env.set_trim_blocks(true);
|
||||||
env.set_lstrip_blocks(true);
|
env.set_lstrip_blocks(true);
|
||||||
|
env.add_callback("to_upper", 1, [](inja::Arguments &args) {
|
||||||
|
return sled::ToUpper(args.at(0)->get<std::string>());
|
||||||
|
});
|
||||||
|
env.add_callback("to_lower", 1, [](inja::Arguments &args) {
|
||||||
|
return sled::ToLower(args.at(0)->get<std::string>());
|
||||||
|
});
|
||||||
|
// CamelCase or SnakeCase to SnakeCase
|
||||||
|
env.add_callback("to_snake_case", 1, [](inja::Arguments &args) {
|
||||||
|
const std::string str = args.at(0)->get<std::string>();
|
||||||
|
std::string result;
|
||||||
|
for (size_t i = 0; i < str.size(); i++) {
|
||||||
|
if (i > 0 && str[i] >= 'A' && str[i] <= 'Z') { result.push_back('_'); }
|
||||||
|
result.push_back(sled::ToLower(str[i]));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
env.add_callback("to_camel_case", 1, [](inja::Arguments &args) {
|
||||||
|
const std::string str = args.at(0)->get<std::string>();
|
||||||
|
std::string result;
|
||||||
|
bool to_upper = false;
|
||||||
|
for (size_t i = 0; i < str.size(); i++) {
|
||||||
|
if (str[i] == '_') {
|
||||||
|
to_upper = true;
|
||||||
|
} else {
|
||||||
|
if (to_upper) {
|
||||||
|
result.push_back(sled::ToUpper(str.substr(i, 1))[0]);
|
||||||
|
to_upper = false;
|
||||||
|
} else {
|
||||||
|
result.push_back(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGV(kTag, "data={}", class_def.dump());
|
LOGV(kTag, "data={}", class_def.dump());
|
||||||
LOGV(kTag, "class_def={}", env.render(template_, class_def));
|
std::string result = env.render(template_, class_def);
|
||||||
|
if (output_path_.empty()) {
|
||||||
|
LOGI(kTag, "render_result=\n{}", result);
|
||||||
|
} else {
|
||||||
|
std::ofstream out(output_path_);
|
||||||
|
out << result;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
LOGE(kTag, "error: {}", e.what());
|
LOGE(kTag, "error: {}", e.what());
|
||||||
}
|
}
|
||||||
@ -44,88 +88,14 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string template_;
|
std::string template_;
|
||||||
|
std::string output_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// template<typename ClassT, typename ReturnT = void, typename... Args>
|
void TestFunc();
|
||||||
// std::function<void(sled::any)>
|
|
||||||
// MemberFunctionWrapper(void (ClassT::*func)(Args...))
|
|
||||||
// {
|
|
||||||
// return [=](sled::any obj_args) {
|
|
||||||
// using tuple = ::std::tuple<ClassT *, Args...>;
|
|
||||||
// // ::std::tuple<ClassT *, Args...> *pTuple = ::sled::any_cast<tuple *>(obj_args);
|
|
||||||
// auto tuple_ptr = ::sled::any_cast<tuple *>(obj_args);
|
|
||||||
// sled::apply(func, *tuple_ptr);
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
template<typename ClassT, typename ReturnT, typename... Args>
|
|
||||||
std::function<ReturnT(sled::any)>
|
|
||||||
MemberFunctionWrapper(ReturnT (ClassT::*func)(Args...))
|
|
||||||
{
|
|
||||||
return [=](sled::any obj_args) {
|
|
||||||
using tuple = ::std::tuple<ClassT *, Args...>;
|
|
||||||
// ::std::tuple<ClassT *, Args...> *pTuple = ::sled::any_cast<tuple *>(obj_args);
|
|
||||||
auto tuple_ptr = ::sled::any_cast<tuple *>(obj_args);
|
|
||||||
return sled::apply<ReturnT>(func, *tuple_ptr);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class Test {
|
|
||||||
public:
|
|
||||||
void Show(int a, double b, std::string c) { LOGV(kTag, "a={}, b={}, c={}", a, b, c); }
|
|
||||||
|
|
||||||
// int Show(int a, int b, const std::string &c)
|
|
||||||
// {
|
|
||||||
// LOGV(kTag, "a={}, b={}, c={}", a, b, c);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Adder {
|
|
||||||
public:
|
|
||||||
int Add(int a, int b) { return a + b; }
|
|
||||||
friend class meta::reflection::Method;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add(int, int)
|
|
||||||
class AdderMethod : public meta::reflection::Method {
|
|
||||||
public:
|
|
||||||
AdderMethod(const std::string &name, std::shared_ptr<meta::reflection::Class> parent)
|
|
||||||
: meta::reflection::Method(name, parent)
|
|
||||||
{
|
|
||||||
fun_ = MemberFunctionWrapper<Adder, int, int, int>(&Adder::Add);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Add(int a, int b) { return a + b; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
meta::reflection::any InvokeImpl(void *instance,
|
|
||||||
const std::vector<void *> ¶ms) const override
|
|
||||||
{
|
|
||||||
Adder *adder = reinterpret_cast<Adder *>(instance);
|
|
||||||
using tuple = std::tuple<int, int>;
|
|
||||||
auto t = std::make_tuple(adder,
|
|
||||||
*reinterpret_cast<int *>(params[0]),
|
|
||||||
*reinterpret_cast<int *>(params[1]));
|
|
||||||
return fun_(&t);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<int(sled::any)> fun_;
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
auto clz = std::make_shared<meta::reflection::Class>("Test");
|
|
||||||
class Adder adder;
|
|
||||||
meta::reflection::Method *method = new AdderMethod("Add", clz);
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
LOGV("", "{}+{}={}", i, i, meta::reflection::any_cast<int>(method->Invoke(&adder, i, i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void (Test::*p)(int, double, std::string) = &Test::Show;
|
|
||||||
|
|
||||||
LOGV(kTag, "{}", meta::reflection::PrettyName<meta::Registry>());
|
LOGV(kTag, "{}", meta::reflection::PrettyName<meta::Registry>());
|
||||||
// LOGI(kTag, "cwd={}", sled::Path::Current().ToString());
|
// LOGI(kTag, "cwd={}", sled::Path::Current().ToString());
|
||||||
meta::Parser parser;
|
meta::Parser parser;
|
||||||
@ -151,10 +121,31 @@ main(int argc, char *argv[])
|
|||||||
LOGI(kTag, "{}\n{}", meta::Registry::Instance()->GetQualifiedName(clz), clz->ToString());
|
LOGI(kTag, "{}\n{}", meta::Registry::Instance()->GetQualifiedName(clz), clz->ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Generator generator1("template/class_proxy_include.inja");
|
Generator generator1("template/class_proxy_include.inja", "runtime/test.gen.h");
|
||||||
generator1.Generate();
|
generator1.Generate();
|
||||||
Generator generator2("template/class_proxy_source.inja");
|
Generator generator2("template/class_proxy_source.inja", "runtime/test.gen.cc");
|
||||||
generator2.Generate();
|
generator2.Generate();
|
||||||
|
|
||||||
|
::meta::reflection::Registry::RegisterAll();
|
||||||
|
TestFunc();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestFunc()
|
||||||
|
{
|
||||||
|
auto clz = ::meta::reflection::Registry::Instance()->GetClass("test::Test");
|
||||||
|
if (clz) {
|
||||||
|
LOGI(kTag, "class={}", clz->Name());
|
||||||
|
::test::Test test;
|
||||||
|
auto size_method = clz->GetMethod("size");
|
||||||
|
auto size_field = clz->GetField("size_");
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
size_field->Set(&test, i);
|
||||||
|
LOGI(kTag, "size_field={}", size_field->GetAndCast<int>(&test));
|
||||||
|
LOGI(kTag, "size_invoke={}", size_method->InvokeAndCast<size_t>(&test));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGE(kTag, "class not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,18 @@ Field::Field(const Cursor &cursor, const std::vector<std::string> &namespaces, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Field::IsConst() const
|
||||||
|
{
|
||||||
|
return cursor().GetType().IsConst();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Field::IsStatic() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Field::ToString() const
|
Field::ToString() const
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,8 @@ public:
|
|||||||
Field(const Cursor &cursor, const std::vector<std::string> &namespaces, const Class &parent);
|
Field(const Cursor &cursor, const std::vector<std::string> &namespaces, const Class &parent);
|
||||||
|
|
||||||
~Field() override = default;
|
~Field() override = default;
|
||||||
|
bool IsConst() const override;
|
||||||
|
bool IsStatic() const;
|
||||||
|
|
||||||
std::string ToString() const override;
|
std::string ToString() const override;
|
||||||
std::string TypeName() const override;
|
std::string TypeName() const override;
|
||||||
|
@ -46,4 +46,10 @@ Method::IsConst() const
|
|||||||
return clang_CXXMethod_isConst(cursor_.handle());
|
return clang_CXXMethod_isConst(cursor_.handle());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
Method::IsStatic() const
|
||||||
|
{
|
||||||
|
return clang_CXXMethod_isStatic(cursor().handle());
|
||||||
|
}
|
||||||
|
|
||||||
}// namespace meta
|
}// namespace meta
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
std::string TypeName() const override;
|
std::string TypeName() const override;
|
||||||
|
|
||||||
bool IsConst() const override;
|
bool IsConst() const override;
|
||||||
|
bool IsStatic() const;
|
||||||
|
|
||||||
CursorType return_type() const { return return_type_; }
|
CursorType return_type() const { return return_type_; }
|
||||||
|
|
||||||
|
@ -2,15 +2,22 @@
|
|||||||
#ifndef META_GEN_{{class_name}}_PROXY_H
|
#ifndef META_GEN_{{class_name}}_PROXY_H
|
||||||
#define META_GEN_{{class_name}}_PROXY_H
|
#define META_GEN_{{class_name}}_PROXY_H
|
||||||
|
|
||||||
#include "runtime/reflection.h"
|
#include "test.h"
|
||||||
|
|
||||||
namespace meta {
|
// namespace meta {
|
||||||
namespace reflection {
|
// namespace reflection {
|
||||||
|
|
||||||
class {{class_name}}_Class : public ::meta::reflection::Class {
|
class ::{{class_namespace}}::{{class_name}}::{{class_name}}_Class : public ::meta::reflection::Class {
|
||||||
|
public:
|
||||||
|
{{class_name}}_Class();
|
||||||
|
static void Register();
|
||||||
|
private:
|
||||||
|
void AddBaseClassProxy(std::shared_ptr<::meta::reflection::Class> base) ;
|
||||||
|
void AddMethodProxy(std::shared_ptr<::meta::reflection::Method> method) ;
|
||||||
|
void AddFieldProxy(std::shared_ptr<::meta::reflection::Field> field) ;
|
||||||
};
|
};
|
||||||
|
|
||||||
class {{class_name}}_Field : public ::meta::reflection::Field {
|
class ::{{class_namespace}}::{{class_name}}::{{class_name}}_Field : public ::meta::reflection::Field {
|
||||||
public:
|
public:
|
||||||
{{class_name}}_Field(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
{{class_name}}_Field(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
||||||
|
|
||||||
@ -19,16 +26,16 @@ protected:
|
|||||||
void SetImpl(void* instance, const ::meta::reflection::any& value) const override;
|
void SetImpl(void* instance, const ::meta::reflection::any& value) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class {{class_name}}_Method : public ::meta::reflection::Method {
|
class ::{{class_namespace}}::{{class_name}}::{{class_name}}_Method : public ::meta::reflection::Method {
|
||||||
public:
|
public:
|
||||||
{{class_name}}_Method(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
{{class_name}}_Method(const std::string& name, std::shared_ptr<::meta::reflection::Class> parent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
::meta::reflection::any InvokeImpl(void* instance, const std::vector<void *> ¶ms) const override;
|
::meta::reflection::any InvokeImpl(void* instance, const std::vector<::meta::reflection::any> ¶ms) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace reflection
|
// } // namespace reflection
|
||||||
} // namespace meta
|
// } // namespace meta
|
||||||
|
|
||||||
#endif // META_GEN_{{class_name}}_PROXY_H
|
#endif // META_GEN_{{class_name}}_PROXY_H
|
||||||
|
|
||||||
|
@ -1,31 +1,69 @@
|
|||||||
#include "{{class_name}}.gen.h"
|
#include "{{to_lower(class_name)}}.gen.h"
|
||||||
#include <string.h>
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class
|
||||||
|
**/
|
||||||
|
{{class_namespace}}::{{class_name}}::{{class_name}}_Class::{{class_name}}_Class()
|
||||||
|
: ::meta::reflection::Class("{{class_namespace}}::{{class_name}}", nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void {{class_namespace}}::{{class_name}}::{{class_name}}_Class::Register() {
|
||||||
|
auto self = new {{class_namespace}}::{{class_name}}::{{class_name}}_Class();
|
||||||
|
auto clz = std::shared_ptr<::meta::reflection::Class>(self);
|
||||||
|
// self->AddBaseClassProxy();
|
||||||
|
|
||||||
|
{% for method in class_methods %}
|
||||||
|
self->AddMethod(std::make_shared<{{class_namespace}}::{{class_name}}::{{class_name}}_Method>("{{method.name}}", clz));
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for field in class_fields %}
|
||||||
|
self->AddField(std::make_shared<{{class_namespace}}::{{class_name}}::{{class_name}}_Field>("{{field.name}}", clz));
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
::meta::reflection::Registry::Instance()->RegisterClass(clz);
|
||||||
|
}
|
||||||
|
void {{class_namespace}}::{{class_name}}::{{class_name}}_Class::AddBaseClassProxy(std::shared_ptr<::meta::reflection::Class> base) {
|
||||||
|
AddBaseClass(base);
|
||||||
|
}
|
||||||
|
void {{class_namespace}}::{{class_name}}::{{class_name}}_Class::AddMethodProxy(std::shared_ptr<::meta::reflection::Method> method) {
|
||||||
|
AddMethod(method);
|
||||||
|
}
|
||||||
|
void {{class_namespace}}::{{class_name}}::{{class_name}}_Class::AddFieldProxy(std::shared_ptr<::meta::reflection::Field> field) {
|
||||||
|
AddField(field);
|
||||||
|
}
|
||||||
|
|
||||||
namespace meta {
|
|
||||||
namespace reflection {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field
|
* Field
|
||||||
**/
|
**/
|
||||||
|
|
||||||
{{class_name}}_Field::{{class_name}}_Field(
|
{{class_namespace}}::{{class_name}}::{{class_name}}_Field::{{class_name}}_Field(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
std::shared_ptr<::meta::reflection::Class> parent)
|
std::shared_ptr<::meta::reflection::Class> parent)
|
||||||
: ::meta::reflection::Field(name, parent) {}
|
: ::meta::reflection::Field(name, parent) {}
|
||||||
|
|
||||||
::meta::reflection::any GetImpl(void* instance) const {
|
::meta::reflection::any {{class_namespace}}::{{class_name}}::{{class_name}}_Field::GetImpl(void* instance) const {
|
||||||
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
||||||
|
|
||||||
{% for field in class_fields %}
|
{% for field in class_fields %}
|
||||||
if (strcmp(name().c_str(), "{{field.name}}") == 0) { return obj->{{field.name}}; }
|
if (strcmp(Name().c_str(), "{{field.name}}") == 0) {
|
||||||
|
{% if field.is_static %}
|
||||||
|
return ::{{class_namespace}}::{{class_name}}::{{field.name}};
|
||||||
|
{% else %}
|
||||||
|
return obj->{{field.name}};
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
return ::meta::reflection::any{};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetImpl(void* instance, const ::meta::reflection::any& value) const {
|
void {{class_namespace}}::{{class_name}}::{{class_name}}_Field::SetImpl(void* instance, const ::meta::reflection::any& value) const {
|
||||||
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
||||||
{% for field in class_fields %}
|
{% for field in class_fields %}
|
||||||
{% if not field.is_const %}
|
{% if not field.is_const %}
|
||||||
if(strcmp(name().c_str(), "{{field.name}}") == 0) { obj->{{field.name}} = value.as<{{field.type}}>();}
|
if(strcmp(Name().c_str(), "{{field.name}}") == 0) { obj->{{field.name}} = ::meta::reflection::any_cast<{{field.type}}>(value);}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
@ -35,44 +73,42 @@ void SetImpl(void* instance, const ::meta::reflection::any& value) const {
|
|||||||
/**
|
/**
|
||||||
* Method
|
* Method
|
||||||
**/
|
**/
|
||||||
{{class_name}}_Method::{{class_name}}_Method(
|
{{class_namespace}}::{{class_name}}::{{class_name}}_Method::{{class_name}}_Method(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
std::shared_ptr<::meta::reflection::Class> parent)
|
std::shared_ptr<::meta::reflection::Class> parent)
|
||||||
: ::meta::reflection::Method(name, parent) {}
|
: ::meta::reflection::Method(name, parent) {}
|
||||||
|
|
||||||
::meta::reflection::any InvokeImpl(void* instance, const std::vector<void *> ¶ms) const {
|
::meta::reflection::any {{class_namespace}}::{{class_name}}::{{class_name}}_Method::InvokeImpl(void* instance, const std::vector<::meta::reflection::any> ¶ms) const {
|
||||||
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
::{{class_namespace}}::{{class_name}}* obj = (::{{class_namespace}}::{{class_name}}*)instance;
|
||||||
|
|
||||||
{% for method in class_methods %}
|
{% for method in class_methods %}
|
||||||
{# start if(, else if(, #}
|
if (strcmp(Name().c_str(), "{{method.name}}") == 0) {
|
||||||
{% if loop.is_first %}
|
|
||||||
if (strcmp(name.c_str(), "{{method.name}}") == 0) {
|
|
||||||
{% else %}
|
|
||||||
} else if (strcmp(name.c_str(), "{{method.name}}") == 0) {
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if method.return_type != "void" %}
|
{% if method.return_type != "void" %}
|
||||||
return obj->{{method.name}}(
|
return
|
||||||
|
{% if method.is_static %}
|
||||||
|
::{{class_namespace}}::{{class_name}}::
|
||||||
|
{% else %}
|
||||||
|
obj->
|
||||||
|
{% endif %}{{method.name}}(
|
||||||
{% for param in method.params%}
|
{% for param in method.params%}
|
||||||
*({{param.type}}*)params[{{loop.index}}]{% if not loop.is_last %}, {% endif %}
|
::meta::reflection::any_cast<{{param.type}}>(params[{{loop.index}}]){% if not loop.is_last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
);
|
);
|
||||||
{% else %}
|
{% else %}
|
||||||
obj->{{method.name}}(
|
{% if method.is_static %}
|
||||||
|
::{{class_namespace}}::{{class_name}}::
|
||||||
|
{% else %}
|
||||||
|
obj->
|
||||||
|
{%endif%}}
|
||||||
|
{{method.name}}(
|
||||||
{% for param in method.params%}
|
{% for param in method.params%}
|
||||||
*({{param.type}}*)params[{{loop.index}}]{% if not loop.last %}, {% endif %}
|
::meta::reflection::any_cast<{{param.type}}>(params[{{loop.index}}]){% if not loop.last %}, {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
);
|
);
|
||||||
return;
|
return ::meta::reflection::any{};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if loop.is_last %}
|
|
||||||
}
|
}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
return ::meta::reflection::any{};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace reflection
|
|
||||||
} // namespace meta
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user