On Wed, 24 Aug 2011 08:49:19 +0200, Jacob Carlborg <d...@me.com> wrote:

On 2011-08-24 01:34, Martin Nowak wrote:
On Tue, 23 Aug 2011 17:03:12 +0200, Jacob Carlborg <d...@me.com> wrote:

On 2011-08-23 16:38, Andrei Alexandrescu wrote:
On 8/23/11 12:55 AM, Jacob Carlborg wrote:
On 2011-08-23 08:52, Andrei Alexandrescu wrote:
On 8/22/11 11:30 PM, Jacob Carlborg wrote:
Ok, then I just change "register" to a static method.

A static method of whom?

Andrei

Well, "register" currently an instance method of Serializer so I would
change it to be a static method of Serializer.

I think the ability of a class to be serialized would be independent of
the notion of a serializer. To me, "this class is serializable" really
means "this class has metadata associated with it that allows interested
parties to serialize it". But perhaps this is splitting hairs.

Andrei

You don't want to have it in the class and don't want it in the
serializer. I mean, it needs to be stored somewhere and I thought that
a static method in Serializer would better than a completely global
function.

Are you thinking about having another serialization library that can
use this information as well? I'm not sure if that's good idea,
different serialization implementations might need to do very
different things with the information.


I think the idea is to register something that provides the needed
information at runtime and separate that from the serializer because
it's useful on it's own.

Could be as simple as:

interface Serializable {
string[] allMembers();
Member getMember(string name);
}

interface Member {
final void set(T)(T t) {
setRaw(typeid(t), cast(void*)&t);
}
void setRaw(TypeInfo ti, void* p);

final T get(T)() {
return *cast(T*)enforce(getRaw(typeid(T)));
}
void* getRaw();
}

It's clearly interesting to make this available if you implement
something along that line.
But I would not overstress it for there are dozen of different
requirements profiles (performance, versioning, pre/post-serialize hooks).
So even if I am interested to use something similar for undo/redo or
delta creation, I'm not sure one can find a one-for-all solution here
(i.e. the above approach seems way to dynamic for my needs).
Maybe Variant could help in setting/getting values.

martin

As soon as "setRaw" is called all static information is gone. I need to be able to iterate over T.tupleof.


Not sure, I get what you mean.
Let me try to clarify this:

static Serializeable[TypeInfo] infos;

void register(T)() {
        infos[typeid(T)] = new SerializableImpl!T();
}

// Serializable binds static reflection to dynamic interface
class SerializeableImpl!T : Serializable {
        string[] allMembers() { array(__traits(allMembers, T)); }
        Member getMember(string name) {
          if (mi = findMemberInfo(name)) {
auto res = mi.clone(); // found immutable info, now create wrapper
            res.address = this + mi.offset; // tell the clone where to find
            return res;
          }
          return null;
        }
}

// Member binds purely static info to dynamic interface and an actual address
class MemberInfo!T : Member {
  override void setRaw(TypeInfo ti, void* p) {
    if (ti is typeid(T))
      *address = *cast(T*)p;
  }

  override void* getRaw(TypeInfo ti) {
    if (ti is typeid(T))
      return address;
  }

  T* address;
}

In object.d there is a lot of this partly implemented. Have a closer look at OffsetTypeInfo and MemberInfo_field. You can definitely get all the information the compiler could provide for RTTI at compile time. If you try hard enough you may even be able to store them at compile time. The only difference remaining is that you could not
access it through instance.classinfo but have to use a table lookup.

It would be great if there was a way to append data to classinfo at compile time. Like an extra pointer or an array of ubyte that can be set.
martin

Reply via email to