Sylvain G. Vignaud | 24 Jun 2010 06:24
Favicon

Re: c++ reflection (was (no subject))

Actually you can get something quite similar if you're not too regarding on mixing metaprogramming and
macros. The result looks like:

	class Foo
	{
	public:
		Foo() {}
		virtual ~Foo() {}

	private:
		DefineClass(Foo);
	
		Member(int, test, 0);
		Member(char *, mName, "foo");
	
		Member(int*, mBuffer, NULL);
	
		EndClass(Foo);
	};

	Foo foo;
	foo.InitializeMembersToDefaultValue();

	const Foo::ClassDescription &desc = Foo::GetClassDescription();

	printf("type: %s\n", desc.name());
	printf("size: %d\n", desc.size());

	for( int i=0; i<Foo::NbrMembers; ++i )
	{
(Continue reading)

Sylvain Vignaud | 30 Jun 2010 04:49
Favicon

Re: c++ reflection (was (no subject))

Not sure anyone is still following this thread. I've just spent 10mn to improve the interface so that the Member macro doesn't have such a rigid number of arguments:

I think the following code is quite easily expandable, and it now looks quite much like what Jarkko wanted: easy to have lots of parameters, no code generation tool, no precompilation pass.
class Foo
{
public:
    Foo() {}
    virtual ~Foo() {}

private:
    DefineClass(Foo);

    Member(int, test, Default(0); Description("Some int") );
    Member(char *, mName, Default("foo"); Description("Some static text"); Serialized());

    Member(int*, mBuffer, Default(NULL), Description("Some ptr to nowhere"); Serialized());

    Member(int, foo);

    Member(int, foo2, Description("this one has a desc, unlike foo"));
    Member(int, foo3, Default(0xDead));

    EndClass();
};
Updated code is still in the same place: http://tfpsly.free.fr/Files/Reflection.cpp



On 24/06/10 00:24, Sylvain G. Vignaud wrote:
Actually you can get something quite similar if you're not too regarding on mixing metaprogramming and macros. The result looks like: class Foo { public: Foo() {} virtual ~Foo() {} private: DefineClass(Foo); Member(int, test, 0); Member(char *, mName, "foo"); Member(int*, mBuffer, NULL); EndClass(Foo); }; Foo foo; foo.InitializeMembersToDefaultValue(); const Foo::ClassDescription &desc = Foo::GetClassDescription(); printf("type: %s\n", desc.name()); printf("size: %d\n", desc.size()); for( int i=0; i<Foo::NbrMembers; ++i ) { const member_t &member = desc.m_Members[i]; printf(" %s: offset %d size %d type %s\n", member.name, member.offset, member.type->size(), member.type->name()); } And it seems the "Member" macro doesn't prevent Intellisense and the likes to know about members :) Also it could be expended to take more parameters, like a flag to decide which members are serialized, a text description... Quick proof of concept with full code - hacked using Jon Watte's Reflexion.cpp as a basis: http://tfpsly.free.fr/Files/Reflection.cpp From: Jarkko Lempiainen [Profoundic] <jarkko
[...] But it would be nicer to have something like: struct my_struct { int a {serialized, editable, desc("Car velocity"), color(0x123456)}; int b {serialized, editable, call(foobar())}; int c, d, e {serialized}; int f; // non-reflected variable }; Cheers, Jarkko From: sweng-gamedev-bounces <at> lists.midnightryder.com [mailto:sweng-gamedev-bounces <at> lists.midnightryder.com] On Behalf Of Jon Watte Sent: Thursday, June 17, 2010 1:13 AM Am 17.06.2010 00:12, schrieb Jon Watte:
Mail formatting still all messed up :-( Anyway, the example you had (PFC_MONO()) doesn't actually add all the annotations you want for editing and serialization in addition to the general reflection information. You can get rid of the ellipsis requirement by doing something like: #define MEMBERS(Type, x) \ typedef mytype Type; \ inline static Member *GetMembers() { \ static Member<mytype>[] members = { \ x \ }; \ return x; \ } #define MEMBER(x, desc) Member<mytype>(&mytype::x, #x, desc), Use it like so: struct MyStruct { int x; float b; MEMBERS(MyStruct, MEMBER(x, "Some integer value") MEMBER(b, "The amount of float-ness")) }; Note that the comma lives in the MEMBER() macro, and the members are just listed without comma within the MEMBERS() macro. The MEMBER() macro should take the union of all information you need about the member (editor information, networking, etc). Sincerely, jw
_______________________________________________ Sweng-Gamedev mailing list Sweng-Gamedev <at> lists.midnightryder.com http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com

_______________________________________________
Sweng-Gamedev mailing list
Sweng-Gamedev <at> lists.midnightryder.com
http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com
OvermindDL1 | 1 Jul 2010 23:50
Picon

Re: c++ reflection (was (no subject))

On Tue, Jun 29, 2010 at 8:49 PM, Sylvain Vignaud <vignsyl <at> iit.edu> wrote:
> Not sure anyone is still following this thread. I've just spent 10mn to
> improve the interface so that the Member macro doesn't have such a rigid
> number of arguments:
>
> I think the following code is quite easily expandable, and it now looks
> quite much like what Jarkko wanted: easy to have lots of parameters, no code
> generation tool, no precompilation pass.
>
> class Foo
> {
> public:
>     Foo() {}
>     virtual ~Foo() {}
>
> private:
>     DefineClass(Foo);
>
>     Member(int, test, Default(0); Description("Some int") );
>     Member(char *, mName, Default("foo"); Description("Some static text");
> Serialized());
>
>     Member(int*, mBuffer, Default(NULL), Description("Some ptr to nowhere");
> Serialized());
>
>     Member(int, foo);
>
>     Member(int, foo2, Description("this one has a desc, unlike foo"));
>     Member(int, foo3, Default(0xDead));
>
>     EndClass();
> };
>
> Updated code is still in the same place:
> http://tfpsly.free.fr/Files/Reflection.cpp
>
>
>
> On 24/06/10 00:24, Sylvain G. Vignaud wrote:
>
> Actually you can get something quite similar if you're not too regarding on
> mixing metaprogramming and macros. The result looks like:
> 	class Foo
> 	{
> 	public:
> 		Foo() {}
> 		virtual ~Foo() {}
> 	private:
> 		DefineClass(Foo);
> 	
> 		Member(int, test, 0);
> 		Member(char *, mName, "foo");
> 	
> 		Member(int*, mBuffer, NULL);
> 	
> 		EndClass(Foo);
> 	};
> 	Foo foo;
> 	foo.InitializeMembersToDefaultValue();
> 	const Foo::ClassDescription &desc = Foo::GetClassDescription();
> 	printf("type: %s\n", desc.name());
> 	printf("size: %d\n", desc.size());
> 	for( int i=0; i<Foo::NbrMembers; ++i )
> 	{
> 		const member_t &member = desc.m_Members[i];
> 		printf("  %s: offset %d  size %d  type %s\n",
> 			member.name, member.offset,
> 			member.type->size(), member.type->name());
> 	}
> And it seems the "Member" macro doesn't prevent Intellisense and the likes
> to know about members :)
> Also it could be expended to take more parameters, like a flag to decide
> which members are serialized, a text description...
> Quick proof of concept with full code - hacked using Jon Watte's
> Reflexion.cpp as a basis:
> http://tfpsly.free.fr/Files/Reflection.cpp
> From: Jarkko Lempiainen [Profoundic] <jarkko
>
> [...] But it would be nicer to have something like:
> struct my_struct
> {
>   int a {serialized, editable, desc("Car velocity"), color(0x123456)};
>   int b {serialized, editable, call(foobar())};
>   int c, d, e {serialized};
>   int f; // non-reflected variable
> };
> Cheers, Jarkko
> From: sweng-gamedev-bounces <at> lists.midnightryder.com
> [mailto:sweng-gamedev-bounces <at> lists.midnightryder.com] On Behalf Of Jon
> Watte
> Sent: Thursday, June 17, 2010 1:13 AM
> Am 17.06.2010 00:12, schrieb Jon Watte:
>
> Mail formatting still all messed up :-(
> Anyway, the example you had (PFC_MONO()) doesn't actually add all the
> annotations you want for editing and serialization in addition to the
> general reflection information.
> You can get rid of the ellipsis requirement by doing something like:
> #define MEMBERS(Type, x) \
>   typedef mytype Type; \
>   inline static Member *GetMembers() { \
>     static Member<mytype>[] members = { \
>       x \
>     }; \
>     return x; \
>   }
> #define MEMBER(x, desc) Member<mytype>(&mytype::x, #x, desc),
> Use it like so:
> struct MyStruct {
>   int x;
>   float b;
>   MEMBERS(MyStruct,
>     MEMBER(x, "Some integer value")
>     MEMBER(b, "The amount of float-ness"))
> };
> Note that the comma lives in the MEMBER() macro, and the members are
> just listed without comma within the MEMBERS() macro. The MEMBER()
> macro should take the union of all information you need about the
> member (editor information, networking, etc).

Still seems like it has a lot of oddity in its syntax, what about
something like this, which is completely possible and rather easily
done actually:

class Foo
{
public:
    Foo() {}
    virtual ~Foo() {}

private:
    DefineClass(Foo); // Why not make this define the actual class in
its entirety?

    Member((type(int))(name(test))(default(0))(description("Some int"));
    Member((type(char*))(name(mName))(default("foo"))(description("Some
static text"))(serialized));

    Member((type(int*))(name(mBuffer))(default(NULL))(description("Some
ptr to nowhere"))(serialized);

    Member((type(int))(name(foo)));

    Member((type(int))(name(foo2))(description("this one has a desc,
unlike foo")));
    Member((type(int))(name(foo3))(default(0xDead)));

    EndClass();
};

That style lets you add new capabilities arbitrarily without
introducing new Member overloads or what-not, just adding a keyword,
simple to do.  Or if you want to use the Boost proposed Mirror C++
reflection library, it would be this (this is non-intrusive for note):

class Foo
{
public:
    Foo() {}
    virtual ~Foo() {}

    int test;
    char *mName;

    int *mBuffer;

    int foo;

    int foo2;

    int get_foo3() const;
    void set_foo3(const int i);

    float someFunc(int);

private:
    int foo3;
};

BOOST_MIRROR_REG_BEGIN

BOOST_MIRROR_REG_CLASS_GLOBAL_SCOPE_BEGIN(class, foo)
  BOOST_MIRROR_REG_CLASS_MEM_VARS_BEGIN
    BOOST_MIRROR_REG_CLASS_MEM_VAR(public, _, _, test)
    BOOST_MIRROR_REG_CLASS_MEM_VAR(public, _, _, mName)
    BOOST_MIRROR_REG_CLASS_MEM_VAR(public, _, _, mBuffer)
    BOOST_MIRROR_REG_CLASS_MEM_VAR(public, _, _, foo)
    BOOST_MIRROR_REG_CLASS_MEM_VAR(public, _, _, foo2)
    BOOST_MIRROR_REG_CLASS_MEM_VAR_GET_SET(
        private,
        _, int, foo3,
        _.get_foo3(),
        _.set_foo3(_a)
      )
  BOOST_MIRROR_REG_CLASS_MEM_VARS_END
    float someFunc(int);
    BOOST_MIRROR_REG_MEM_FUNCTION_BEGIN(public, _, float, someFunc, someFuncI)
      BOOST_MIRROR_REG_MEM_FUNCTION_PARAM(int, i)
    BOOST_MIRROR_REG_MEM_FUNCTION_END(someFunc, someFuncI)
BOOST_MIRROR_REG_CLASS_END

And it has things to handle type conversions supported and much more.
The docs are at:  http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/
_______________________________________________
Sweng-Gamedev mailing list
Sweng-Gamedev <at> lists.midnightryder.com
http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com

Gmane