Re: On the benefits of reflection

Marc Hernandez <[email protected]> Tue, 19 Mar 2013 13:09:37 -0700
Newsgroups gmane.games.devel.sweng
Message-ID <CAL=mSHiQqwHWhNtOeOwzY40A2iyutybcTC5bNhLfNEgbcgAaVA@mail.gmail.com>
--===============0549258619==
Content-Type: multipart/alternative; boundary=f46d043bd93cb6b15104d84cb117

--f46d043bd93cb6b15104d84cb117
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Mar 19, 2013 at 12:15 PM, Massimo Del Zotto <[email protected]>wrote:

> Let me elaborate on those points so I hope people can get in my point of
> view.
>
> 1- "Trivial" network system. Done for ages, before reflection was in
> vogue. Considering how UDK manages that thing, I believe we're cutting a
> lot of corners. What's the problem in just doing serialization in the
> standard way?
>

  I havent seen a non reflection based network system that was as easy as a
reflection based one.  By serialization, if you mean:
send()
  health >> out;
  pos >> out;

recv()
  health << in;
  pos << in;

  A reflection system merely automates this and makes it very difficult to
get wrong even with rapid development.  Its a completely DRY (dont repeat
yourself (haha)) architecture.  With your traditional serialization you
have to touch 3 places in code when you change some structure, whereas with
reflection I only change one.  If you want to make it simpler it just
starts getting into adhoc reflection systems.


> 2- Config system. No idea what "the same hardware" is supposed to mean.
> I'd be careful in making my networking subsystem work the same as a disk IO.
>

  Sorry, what I meant was my config system uses many of the same classes as
the networking layer.  The only real difference is config uses my XML
read/write and goes to and from disk while my network does binary
read/write and goes to stream.  I also save off the binary network stream
for trivial debugging later via read(binary) -> write( xml ).  All from
fairly short classes I wrote once.


> 3- save load. In my system, just restoring VM state is going nowhere.
> Maybe the scripts will just churn along. Sure engine state isn't going to
> make it there.
>

  I dont know what you mean here.  Most games need a way to save out their
game state, then when the player comes back, to read it back in.  I do all
that with the same reflection system that reads and writes game state,
marked up if necessary.


> 4- Message passing... through the networking system? I don't see the
> connection with reflection. I'd be extra super careful in doing that.
> Message passing to who? For what purpose? At what frequency?
>

  For this I primarily mean find methods based on the signature of the
method like my handle( msg.MoveTo move ) example below.  Though, I have
also used it to spread workloads across multiple machines without the
underlying work classes knowing I did.


> 5- I am using reflection myself in my system as well. Good for your
> friend. Perhaps you could contact him and ask what exactly made his work
> easier? I'd be interested in considering those cases. As I said, I have
> this little language of mine I want to evolve in the right direction.
>

  What made it fast for him was this.  To make a new enemy, you make the
class and markup the variables.  Then with absolutely no other work, you
can load up the editor.  Using C# reflection, it autopopulates the enemy
list with this new enemy, and allows it to be placed.  You can then place
it and fill in any members that you need to for that new guy.
  Minimizing the friction of doing this is always helpful, and with
reflection you can keep code very very DRY.

   I then use reflection to automatically type safe handle the messages.
>>  So, you just put:
>> void handl( msg.MoveTo move )
>>
>>   And higher level code calls down into it.  If this shows up in
>> profiling, ill special case the heavily called messages and leave the rest.
>>
>>
> I have no idea on what you mean there. I actually don't even understand
> what's really the point. The prototype you show leaves me confused. If the
> above is the equivalent of void handl(Message *something) then I'm afraid
> this could work with dynamic_cast in some cases or with structures designed
> to be somehow analyzed, perhaps through a "property" system. What is the
> extra plus reflection gives me?
>

  What reflection gave me is a typesafe, prewritten version of all of that
which makes me more productive.  I wrote the dispatch function once, and
now I just add a handler and poof, that message is handled correctly.  I
dont need to check for things, or cast, or assert or anything, it all just
works by adding 1 function.

--
/// //

--f46d043bd93cb6b15104d84cb117
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div style>On Tue, Mar 19, 2013 at 12:15 PM, Massimo Del Z=
otto <span dir=3D"ltr">&lt;<a href=3D"mailto:[email protected]" target=
=3D"_blank">[email protected]</a>&gt;</span> wrote:<br></div><div class=
=3D"gmail_extra">

<div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204=
);border-left-style:solid;padding-left:1ex"><div>Let me elaborate on those =
points so I hope people can get in my point of view.</div>

<div><br></div>1- &quot;Trivial&quot; network system. Done for ages, before=
 reflection was in vogue. Considering how UDK manages that thing, I believe=
 we&#39;re cutting a lot of corners. What&#39;s the problem in just doing s=
erialization in the standard way?<br>


<div></div></blockquote><div><br></div><div style>=A0 I havent seen a non r=
eflection based network system that was as easy as a reflection based one. =
=A0By serialization, if you mean:</div><div style>send()</div><div style>=
=A0 health &gt;&gt; out;</div>

<div style>=A0 pos &gt;&gt; out;</div><div style><br></div><div style>recv(=
)</div><div style>=A0 health &lt;&lt; in;</div><div style>=A0 pos &lt;&lt; =
in; =A0</div><div style><br></div><div style>=A0 A reflection system merely=
 automates this and makes it very difficult to get wrong even with rapid de=
velopment. =A0Its a completely DRY (dont repeat yourself (haha)) architectu=
re. =A0With your traditional serialization you have to touch 3 places in co=
de when you change some structure, whereas with reflection I only change on=
e. =A0If you want to make it simpler it just starts getting into adhoc refl=
ection systems. =A0</div>

<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div>2- Config system. No idea what &quot;th=
e same hardware&quot; is supposed to mean. I&#39;d be careful in making my =
networking subsystem work the same as a disk IO.</div>

</blockquote><div><br></div><div style>=A0 Sorry, what I meant was my confi=
g system uses many of the same classes as the networking layer. =A0The only=
 real difference is config uses my XML read/write and goes to and from disk=
 while my network does binary read/write and goes to stream. =A0I also save=
 off the binary network stream for trivial debugging later via read(binary)=
 -&gt; write( xml ). =A0All from fairly short classes I wrote once. =A0</di=
v>

<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex"><div>3- save load. In my system, just restor=
ing VM state is going nowhere. Maybe the scripts will just churn along. Sur=
e engine state isn&#39;t going to make it there.</div>

</blockquote><div><br></div><div style>=A0 I dont know what you mean here. =
=A0Most games need a way to save out their game state, then when the player=
 comes back, to read it back in. =A0I do all that with the same reflection =
system that reads and writes game state, marked up if necessary. =A0</div>

<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">
<div>4- Message passing... through the networking system? I don&#39;t see t=
he connection with reflection. I&#39;d be extra super careful in doing that=
. Message passing to who? For what purpose? At what frequency?</div></block=
quote>

<div><br></div><div style>=A0 For this I primarily mean find methods based =
on the signature of the method like my handle( msg.MoveTo move ) example be=
low. =A0Though, I have also used it to spread workloads across multiple mac=
hines without the underlying work classes knowing I did. =A0</div>

<div style>=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);b=
order-left-style:solid;padding-left:1ex"><div>
5- I am using reflection myself in my system as well. Good for your friend.=
 Perhaps you could contact him and ask what exactly made his work easier? I=
&#39;d be interested in considering those cases. As I said, I have this lit=
tle language of mine I want to evolve in the right direction.<br>

</div></blockquote><div><br></div><div style>=A0 What made it fast for him =
was this. =A0To make a new enemy, you make the class and markup the variabl=
es. =A0Then with absolutely no other work, you can load up the editor. =A0U=
sing C# reflection, it autopopulates the enemy list with this new enemy, an=
d allows it to be placed. =A0You can then place it and fill in any members =
that you need to for that new guy. =A0</div>

<div style>=A0 Minimizing the friction of doing this is always helpful, and=
 with reflection you can keep code very very DRY. =A0</div><div><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa=
dding-left:1ex">

<div><div class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-lef=
t-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=
=3D"ltr">

<div>=A0 I then use reflection to automatically type safe handle the messag=
es. =A0So, you just put:</div>


<div>void handl( msg.MoveTo move )</div><div><br></div><div>=A0 And higher =
level code calls down into it. =A0If this shows up in profiling, ill specia=
l case the heavily called messages and leave the rest. =A0</div></div></blo=
ckquote>


</div><div>I have no idea on what you mean there. I actually don&#39;t even=
 understand what&#39;s really the point. The prototype you show leaves me c=
onfused. If the above is the equivalent of void handl(Message *something) t=
hen I&#39;m afraid this could work with dynamic_cast in some cases or with =
structures designed to be somehow analyzed, perhaps through a &quot;propert=
y&quot; system. What is the extra plus reflection gives me?</div>

</div></div></blockquote><div><br></div><div style>=A0 What reflection gave=
 me is a typesafe, prewritten version of all of that which makes me more pr=
oductive. =A0I wrote the dispatch function once, and now I just add a handl=
er and poof, that message is handled correctly. =A0I dont need to check for=
 things, or cast, or assert or anything, it all just works by adding 1 func=
tion. =A0</div>

<div style><br></div><div style>--</div><div style>/// //</div></div></div>=
</div>

--f46d043bd93cb6b15104d84cb117--

--===============0549258619==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Sweng-Gamedev mailing list
[email protected]
http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com

--===============0549258619==--