#ifndef REFLEX_BUILD
#define REFLEX_BUILD
#endif
#include "Reflex/Builder/ClassBuilder.h"
#include "Reflex/Type.h"
#include "Reflex/Member.h"
#include "Class.h"
#include "ClassTemplateInstance.h"
#include "Reflex/Tools.h"
#include "Typedef.h"
#include "Enum.h"
#include "DataMember.h"
#include "FunctionMemberTemplateInstance.h"
Reflex::ClassBuilderImpl::ClassBuilderImpl(const char* nam, const std::type_info& ti, size_t size, unsigned int modifiers, TYPE typ)
: fClass(0)
, fLastMember()
{
std::string nam2(nam);
const Type& c = Type::ByName(nam2);
if (c) {
if (c.IsTypedef()) {
nam2 += " @HIDDEN@";
}
else if (!c.IsClass()) {
throw RuntimeError("Attempt to replace a non-class type with a class");
}
}
if (Tools::IsTemplated(nam)) {
fClass = new ClassTemplateInstance(nam2.c_str(), size, ti, modifiers);
}
else {
fClass = new Class(nam2.c_str(), size, ti, modifiers, typ);
}
}
Reflex::ClassBuilderImpl::~ClassBuilderImpl()
{
FireClassCallback(fClass->ThisType());
}
void Reflex::ClassBuilderImpl::AddBase(const Type& bas, OffsetFunction offsFP, unsigned int modifiers)
{
fClass->AddBase(bas, offsFP, modifiers);
}
void Reflex::ClassBuilderImpl::AddDataMember(const char* nam, const Type& typ, size_t offs, unsigned int modifiers)
{
fLastMember = Member(new DataMember(nam, typ, offs, modifiers));
fClass->AddDataMember(fLastMember);
}
void Reflex::ClassBuilderImpl::AddFunctionMember(const char* nam, const Type& typ, StubFunction stubFP, void* stubCtx, const char* params, unsigned int modifiers)
{
if (Tools::IsTemplated(nam)) {
fLastMember = Member(new FunctionMemberTemplateInstance(nam, typ, stubFP, stubCtx, params, modifiers, *(dynamic_cast<ScopeBase*>(fClass))));
}
else {
fLastMember = Member(new FunctionMember(nam, typ, stubFP, stubCtx, params, modifiers));
}
fClass->AddFunctionMember(fLastMember);
}
void Reflex::ClassBuilderImpl::AddTypedef(const Type& typ, const char* def)
{
Type ret = Type::ByName(def);
if (ret == typ && ! typ.IsTypedef()) {
if (typ) {
typ.ToTypeBase()->HideName();
}
else {
((TypeName*)typ.Id())->HideName();
}
}
else if (ret) {
fClass->AddSubType(ret);
}
else {
new Typedef(def , typ);
}
}
void Reflex::ClassBuilderImpl::AddEnum(const char* nam, const char* values, const std::type_info* ti, unsigned int modifiers)
{
Enum* e = new Enum(nam, *ti, modifiers);
std::vector<std::string> valVec = std::vector<std::string>();
Tools::StringSplit(valVec, values, ";");
for (
std::vector<std::string>::const_iterator it = valVec.begin();
it != valVec.end();
++it
) {
std::string name;
std::string value;
Tools::StringSplitPair(name, value, *it, "=");
unsigned long int valInt = atol(value.c_str());
e->AddDataMember(Member(new DataMember(name.c_str(), Type::ByName("int"), valInt, 0)));
}
}
void Reflex::ClassBuilderImpl::AddProperty(const char* key, const char* value)
{
AddProperty(key, Any(value));
}
void Reflex::ClassBuilderImpl::AddProperty(const char* key, Any value)
{
if (fLastMember) {
fLastMember.Properties().AddProperty(key, value);
}
else {
fClass->Properties().AddProperty(key, value);
}
}
void Reflex::ClassBuilderImpl::SetSizeOf(size_t size)
{
fClass->SetSize(size);
}
Reflex::Type Reflex::ClassBuilderImpl::ToType()
{
return fClass->ThisType();
}
Reflex::ClassBuilder::ClassBuilder(const char* nam, const std::type_info& ti, size_t size, unsigned int modifiers, TYPE typ)
: fClassBuilderImpl(nam, ti, size, modifiers, typ)
{
}
Reflex::ClassBuilder::~ClassBuilder()
{
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddBase(const Type& bas, OffsetFunction offsFP, unsigned int modifiers)
{
fClassBuilderImpl.AddBase(bas, offsFP, modifiers);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddDataMember(const Type& typ, const char* nam, size_t offs, unsigned int modifiers)
{
fClassBuilderImpl.AddDataMember(nam, typ, offs, modifiers);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddFunctionMember(const Type& typ, const char* nam, StubFunction stubFP, void* stubCtx, const char* params, unsigned int modifiers)
{
fClassBuilderImpl.AddFunctionMember(nam, typ, stubFP, stubCtx, params, modifiers);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddTypedef(const char* typ, const char* def)
{
fClassBuilderImpl.AddTypedef(TypeBuilder(typ), def);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddTypedef(const Type& typ, const char* def)
{
fClassBuilderImpl.AddTypedef(typ, def);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::AddEnum(const char* nam, const char* values, const std::type_info* ti, unsigned int modifiers)
{
fClassBuilderImpl.AddEnum(nam, values, ti, modifiers);
return *this;
}
Reflex::ClassBuilder& Reflex::ClassBuilder::SetSizeOf(size_t size)
{
fClassBuilderImpl.SetSizeOf(size);
return *this;
}
Reflex::Type Reflex::ClassBuilder::ToType()
{
return fClassBuilderImpl.ToType();
}