<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ingrater's 3D Blog</title>
	<atom:link href="http://3d.benjamin-thaut.de/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://3d.benjamin-thaut.de</link>
	<description>3D Developement Blog</description>
	<lastBuildDate>Mon, 18 Mar 2013 07:10:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Compiling MinGW-GDC on Windows</title>
		<link>http://3d.benjamin-thaut.de/?p=71</link>
		<comments>http://3d.benjamin-thaut.de/?p=71#comments</comments>
		<pubDate>Sun, 10 Mar 2013 18:05:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=71</guid>
		<description><![CDATA[In the past days is struggeled compiling MinGW-GDC on Windows, so here is a full list of instructions what needs to be done: Install msys-git aviable from http://git-scm.com/ Start a git console and type [crayon-519dbf58d1dfc/] if this prints &#8220;true&#8221; you &#8230; <a href="http://3d.benjamin-thaut.de/?p=71">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the past days is struggeled compiling MinGW-GDC on Windows, so here is a full list of instructions what needs to be done:<br />
<span id="more-71"></span></p>
<ul>
<li>Install msys-git aviable from <a href="http://git-scm.com/">http://git-scm.com/</a></li>
<li>Start a git console and type<br />
  <pre class="crayon-plain-tag">git config core.autocrlf</pre><br />
  if this prints &#8220;true&#8221; you need to run<br />
  <pre class="crayon-plain-tag">git config --global core.autocrlf false</pre><br />
  For more information see: <a href="https://help.github.com/articles/dealing-with-line-endings">https://help.github.com/articles/dealing-with-line-endings</a>
</li>
<li> cd to the folder where you want the GDC sources stored and then do<br />
  <pre class="crayon-plain-tag">git clone git://github.com/venix1/GDC
git checkout mingw</pre>
</li>
<li>Open a random text file in the GDC folder and make sure it actually has LF (Linux-Style) line endings. If not you did something wrong.</li>
<li>Download the mingw-get installer from <a href="http://www.mingw.org/">www.mingw.org</a><br />
  During installation make sure you pick the &#8220;Download latest repository catalogues&#8221; option.<br />
  When you are asked which components to install pick:
<ul>
<li>C Compiler</li>
<li>C++ Compiler</li>
<li>MSYS Basic System</li>
<li>MinGW Developer ToolKit</li>
</ul>
</li>
<li>Now start a msys command shell</li>
<li>Execute<br />
  <pre class="crayon-plain-tag">mingw-get install msys-rsync
mingw-get install msys-wget
mingw-get install msys-unzip</pre>
</li>
<li>Create a folder named &#8220;crossdev&#8221; directly in the root of your C: drive. (Make sure you have at least 4 gigs of space left)
<li>Execute<br />
  <pre class="crayon-plain-tag">notepad /etc/fstab</pre> And make sure it has the follwing contents (assuming you installed MinGW to C:\MinGW)<br />
  <pre class="crayon-plain-tag">C:\MinGW\   /mingw
C:\crossdev\ /crossdev</pre>
</li>
<li> Now cd to the directory where you checked the sources out to and execute <pre class="crayon-plain-tag">./build-tdm-gdc.sh</pre><br />
When the script is done the compiled gdc will be stored in C:\crossdev\gdc64\v2\release</li>
</ul>
<h2>Known Issues</h2>
<li><strong>The script gets stuck after printing &#8220;Checking if the compiler has the remainder bug&#8230;&#8221;</strong><br />
If this happens just kill the conftext.exe with the taskmanager</li>
<li><strong>Compile errors in options.c</strong><br />
GDC/gcc/d/lang.opt has CRLF line endings, make sure you have LF line endings in the whole GDC source tree
</li>
<li><strong>Compile errors while building libppl containting &#8220;itimervalue&#8221;</strong><br />
Once again CRLF line ending issues. Make sure that all the source files you checked out have LF line endings.
</li>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=71</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Runtime code reloading in D, part 1</title>
		<link>http://3d.benjamin-thaut.de/?p=25</link>
		<comments>http://3d.benjamin-thaut.de/?p=25#comments</comments>
		<pubDate>Sun, 30 Dec 2012 12:30:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=25</guid>
		<description><![CDATA[One of the biggest problems in game developement are turnaround times. Tournaround time is the time you have to wait until you can see what your change actually did. Shorter turnaround times improve productivity as you don&#8217;t spend that much &#8230; <a href="http://3d.benjamin-thaut.de/?p=25">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the biggest problems in game developement are turnaround times. Tournaround time is the time you have to wait until you can see what your change actually did. Shorter turnaround times improve productivity as you don&#8217;t spend that much time waiting for changes to become visible. Also shorter turnaround times support the creative process as humans have huge dificulties connecting an action and a result that happens with a huge delay. For mappers, 3d artists, effect artists and sound designers the turnaround times in modern 3d engines are almost zero. A lot of work is put into their tools to keep turnaround times to a minimum. Programmers however usually have very long turnaround times. Mostly this is due to the fact that compile times of the C++ language, which is mostly used in game developement, can go into multipe minutes. This problem is almost solved in the D programming language, as compile times are really quick and it usually only takes a few seconds to compile a project. But after making changes to the code you still have to restart the game, wait for it to load all the resources and then fly/walk to the spot in the level you are currently interrested in. I got really tired of this process so I decided to build a runtime reloading for certian parts of my own little game engine.<br />
<span id="more-25"></span><br />
Game simulations in general have nice properties for runtime code reloading. The simulation is performed in steps, and after each step there usually is a synchronisation point. At that point you exactly know what part of your code is currently executing, so this is ideal to patch other parts of the code as it is currently not executing. For a start I wanted to build a simple system that allows reloading modified algorithms but does not support changes in the structure of the data. This has the advantage that objects remain at the same position on the heap and only the vptrs have to be patched. This makes patching easier for a start.</p>
<h2>Runtime type information</h2>
<p>To be able to patch existing object instances you will usually need some kind of runtime type infomration (RTTI) system. Usually you need to know</p>
<ul>
<li>Where are the vptrs inside the class</li>
<li>Which members point to other objects</li>
</ul>
<p>The first point is already covered by the D&#8217;s TypeInfo instances that exist for every type at runtime. To have information about the members I wrote my own little RTTI system that uses the RTInfo template inside object_.d. This template is instanciated for every type that is used during compilation and thus is ideal to generate RTTI information. At runtime the generated information can be accessed via the &#8220;rtInfo&#8221; member of the respective &#8220;TypeInfo&#8221; object. At some point this template will be used for a percise garbage collector but at the time of this writing it is unused (dmd 2.061). Additionally I&#8217;m not using D&#8217;s GC so even if it is used at some point, I can replace it with my own version because I won&#8217;t need percise GC data.</p>
<p>The RTTI info stored for each member looks as follows:</p>
<p></p><pre class="crayon-plain-tag">struct thMemberInfo 
{
  string name;
  TypeInfo type;
  size_t offset;
  thMemberInfo[]* next;
}</pre><p> </p>
<p>I use D&#8217;s compile time function execution (CTFE) to generate the code which creates the RTTI info. Note the &#8220;static if&#8221; statements that avoid cyclic references.</p>
<p></p><pre class="crayon-plain-tag">string makeRttiInfo(T)()
{
  string result = "[thMemberInfo(\"" ~ T.mangleof ~ "\", typeid(T), instanceSize!T, null)";
  size_t i=0;
  foreach(m; __traits(allMembers, T))
  {
    static if(is(T == struct))
    {
      static if(is(typeof(__traits(getMember, T, m).offsetof)))
      {
        size_t offset = __traits(getMember, T, m).offsetof;
        static if(is(typeof(__traits(getMember, T, m)) == struct))
          result ~= ",\nthMemberInfo(" ~ m.stringof ~ ", typeid(typeof(T." ~ m ~ ")), " ~ formatOffset(offset) ~ ", &amp;RttiInfo!(typeof(T." ~ m ~ ")))";
        else
          result ~= ",\nthMemberInfo(" ~ m.stringof ~ ", typeid(typeof(T." ~ m ~ ")), " ~ formatOffset(offset) ~ ", null)";
      }
    }
    else
    {
      static if(__traits(compiles, mixin("(T." ~ m ~ ").offsetof")))
      {
        size_t offset = mixin("(T." ~ m ~ ").offsetof");
        static if(is(typeof(__traits(getMember, T, m)) == T) || !is(typeof(__traits(getMember, T, m)) == struct))
          result ~= ",\nthMemberInfo(" ~ m.stringof ~ ", typeid(typeof(T." ~ m ~ ")), " ~ formatOffset(offset) ~ ", null)";
        else
        {
          //pragma(msg, "Reference for " ~ T.stringof);
          result ~= ",\nthMemberInfo(" ~ m.stringof ~ ", typeid(typeof(T." ~ m ~ ")), " ~ formatOffset(offset) ~ ", &amp;RttiInfo!(typeof(T." ~ m ~ ")))";
        }
      }
    }
  }
  return result ~ "]";
}</pre><p> </p>
<p>For the class &#8220;RigidBody&#8221;:</p>
<p></p><pre class="crayon-plain-tag">abstract class IRigidBody
{
public:
  Position position;
  Quaternion rotation;
  vec3 velocity;
}

class RigidBody : IRigidBody
{
  CollisionHull m_collision;
  float m_inverseMass;

  public:
    float remainingTime;
}</pre><p> </p>
<p>This will produce the following RTTI information:</p>
<p></p><pre class="crayon-plain-tag">[thMemberInfo("C7physics9rigidbody9RigidBody", typeid(T), instanceSize!T, null),
thMemberInfo("m_collision", typeid(typeof(T.m_collision)), 80, null),
thMemberInfo("m_inverseMass", typeid(typeof(T.m_inverseMass)), 84, null),
thMemberInfo("remainingTime", typeid(typeof(T.remainingTime)), 88, null),
thMemberInfo("position", typeid(typeof(T.position)), 8, &amp;RttiInfo!(typeof(T.position))),
thMemberInfo("rotation", typeid(typeof(T.rotation)), 52, &amp;RttiInfo!(typeof(T.rotation))),
thMemberInfo("velocity", typeid(typeof(T.velocity)), 68, &amp;RttiInfo!(typeof(T.velocity)))]</pre><p> </p>
<p>The first line of the RTTI info contains the mangeled name of the type this information was generated for, the TypeInfo object for the current type and the size for the current type. The manageld name can be used as a unique identifier when building lookup tables for type information. The remaining entries of the array contain information about all members (including the members of the base classes) in the following order: </p>
<ul>
<li>Member name</li>
<li>member type info</li>
<li>member size</li>
<li>pointer to the RTTI information for this member</li>
</ul>
<p>The pointer to the RTTI information for each member is a workaround for a strange bug I encountered. For POD structs the rtInfo template will be instancated, but for some reason you can not query the results at runtime. It is possible that the linker stripps the information away but I could not yet investigate this issue further. If I can not query the RTTI information at runtime I fallback to the RTTI info pointer stored in the &#8220;next&#8221; member of thMemberInfo.</p>
<p>To trigger the generation of the RTTI info the following code is used:</p>
<p></p><pre class="crayon-plain-tag">template RttiInfo(T)
{
  __gshared RttiInfo = mixin(makeRttiInfo!T());
}</pre><p> </p>
<p>And the RTInfo template inside object_.d and object.di looks like this:</p>
<p></p><pre class="crayon-plain-tag">template RTInfo(T)
{
	version(RTTI)
	{
		static if(is(T : TypeInfo) || !(is(T == struct) || is(T == class)))
		{
			enum RTInfo = null;
			//pragma(msg, "ignoring " ~ T.stringof);
		}
		else
			enum RTInfo = &amp;RttiInfo!T;
	}
	else
	{
		enum RTInfo = null;
	}
}</pre><p> </p>
<p>As soon as you pass the &#8220;RTTI&#8221; version identifier to the compiler all types will have RTTI generated for them. As you might notice I only generate RTTI for structs and classes with the exception of classes that are dervived from TypeInfo. TypeInfo classes are ignored because you don&#8217;t really need reflection data for the refelection data <img src='http://3d.benjamin-thaut.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<h2>Plugin system</h2>
<p>To be able to actually reload code at runtime, I did split of the part of the code that should reloadable into a own dll. This was quite compilcated as D does currently not support shared dlls and I had to make small modifications to the runtime to allow for this feature. I might write another article about this in the future.<br />
All calls into this dlls are done over D interfaces, which means that they are virtual and always go through a vtable. By patching the vptrs all these calls can be redirected to the new code. Each plugin also has a few &#8220;roots&#8221;. For the system to work, all objects that have been allocated by a plugin should be findable by wakling down the object hirarchy from the roots of a plugin.</p>
<h2>Patching</h2>
<p>To be able to recompile and reload the dll at run time, the dll and its debugging info (.pdb file) is copied to a temporary subfolder before it is loaded with a LoadLibrary call. To detect modifications to the plugin dll ReadDirectoryChangesW is used. (see <a href="https://github.com/Ingrater/thBase/blob/master/src/thBase/directory.d" target="_blank">my standard library on github</a>). After a modification has been detected the reloading works as follows:</p>
<ul>
<li>Wait for the end of the current simulation cycle</li>
<li>Copy the dll and pdb file to a new subdirectory</li>
<li>Load the new dll</li>
<li>Walk the type hirarchy of the new dll and build a dictionary of all type information objects</li>
<li>Iterate over all objects allocated by the old dll and patch them</li>
<li>Continue the simulation</li>
</ul>
<p>The old plugin remains loaded to keep references to static or TLS memory valid. Each plugin has a small proxy allocator that keeps a list of all allocations done by a plugin so that iterating over them becomes possible. Refernces to objects that are not allocated by the plugin that is currently reloaded remain untouched.</p>
<h3>Building a type info dictionary</h3>
<p>The following function runs down the type hirarchy to build a hashmap with all type info objects for the newly loaded plugin. Please note that it does not operate on actual object instances but merely on the pure type information. This gets a lot easier with a small extension to D&#8217;s TypeInfo classes that has been submitted as a pull request to the regular druntime at the point of this writing: <a href="https://github.com/D-Programming-Language/druntime/pull/370">druntime pull request 370</a>. This exstension adds a &#8220;type&#8221; property to all TypeInfo classes which returns the type of the TypeInfo object as a enum value. This has the advantage that it works flawlessly across dll bounadries which would not be possible with the &#8220;is&#8221; operator. This is due to the fact that currently the TypeInfo instances are duplicated for each dll, which results in different addresses for instances of the same TypeInfo object across dll boundaries.</p>
<p></p><pre class="crayon-plain-tag">struct ScanPair
{
  void* addr;
  TypeInfo type;
}

private final void BuildPluginTypeInfo(IPlugin plugin, Hashmap!(string, const(thMemberInfo)[], StringHashPolicy) types)
{
    ScanPair[10] roots;
    size_t numRoots = plugin.GetScanRoots(roots);
    foreach(ref root; roots[0..numRoots])
    {
      auto rttiInfo = getRttiInfo(root.type);
      auto context = BuildTypeInfoContext(types);
      context.buildInfo(rttiInfo);
    }
}

static struct BuildTypeInfoContext
{
  Hashmap!(string, const(thMemberInfo)[], StringHashPolicy) types;

  void buildInfo(const(thMemberInfo[]) rttiInfo)
  {
    if(rttiInfo.length > 0)
    {
      //avoid endless recursion
      if(types.exists(rttiInfo[0].name))
        return;
      types[rttiInfo[0].name] = rttiInfo;

      //iterate all members
      foreach(ref info; rttiInfo[1..$])
      {
        if(info.next !is null)
          buildInfo(*info.next);
        else
        {
          auto tt = info.type.type;
          //For compond types use the next type
          if(tt == TypeInfo.Type.Array || tt == TypeInfo.Type.StaticArray || tt == TypeInfo.Type.Pointer)
          {
            buildInfo(getRttiInfo(info.type.next));
          }
          else
          {
            buildInfo(getRttiInfo(info.type));
          }
        }
      }
    }
  }
}</pre><p> </p>
<h3>Patching the objects</h3>
<p>After a dictionary of all type info objects has been build the runtime objects can be patched. All runtime objects are iterated by running down the object hirarchy starting at the plugin roots. For each plugin it is checked if it was allocated by the object to be patched, and if yes its new type information is recieved from the hashmap and all vptrs are patched. This is quite easy because D&#8217;s TypeInfo system already provides enough information to locate all vptrs. The memory layout of a D object is as follows (tested with DMD 2.060, no garantuees for correctness):</p>
<div style="text-align:center;width:100%;"><img src="http://3d.benjamin-thaut.de/Bilder/d_object_layout.svg" alt="memory layout of a D object" width="60%" /></div>
<p>We are only interrested in the location of the vptrs. The object vptr is always at the very start of the instance so we can easily patch that.<br />
The location of all interface vptrs can obtained from the &#8220;interfaces&#8221; member of the TypeInfo_Class type information. Additionally the inheritance chain has to be walked until the very top is reached to find all interface vptrs. The new values for all vptrs can be obtained from the TypeInfo &#8220;init&#8221; property. Which is a void[] containing the values a class instance should be initialized with. This will result in the following code for patching interface vptrs.</p>
<p></p><pre class="crayon-plain-tag">//Now patch all the interface vtbls
for(TypeInfo_Class cur = newType; cur !is null; cur = cur.base)
{
  foreach(ref i; cur.interfaces)
  {
    *cast(void**)(addr + i.offset) = *cast(void**)(newType.init.ptr + i.offset);
  }
}</pre><p> </p>
<p>The code for patching a entire object hirarchy looks currently like this:</p>
<p></p><pre class="crayon-plain-tag">final IPlugin ReloadPlugin(const(char)[] pluginName)
{
  IPlugin oldPlugin;
  size_t pluginIndex;
  foreach(size_t i, ref info; m_loadedPlugins.toArray())
  {
    if(info.name[] == pluginName)
    {
      oldPlugin = info.plugin;
      pluginIndex = i;
      break;
    }
  }
  if(oldPlugin is null)
  {
    throw New!RCException(format("Can't reload plugin '%s' because it is not yet loaded", pluginName));
  }

  HMODULE hModule = CopyAndLoadPlugin(pluginName);

  PluginInitFunc initFunc = cast(PluginInitFunc)GetProcAddress(hModule, "InitPlugin");
  PluginDeinitFunc deinitFunc = cast(PluginDeinitFunc)GetProcAddress(hModule, "DeinitPlugin");
  PluginGetFunc getFunc = cast(PluginGetFunc)GetProcAddress(hModule, "GetPlugin");
  if(initFunc is null || getFunc is null || deinitFunc is null)
  {
    throw New!RCException(format("Loading plugin '%s' failed because %s%s%s", pluginName, 
                                  (initFunc is null) ? "InitPlugin entry point not found " : "",
                                  (getFunc is null) ? "GetPlugin entry point not found " : "",
                                  (deinitFunc is null) ? "DeinitPlugin entry point not found " : ""));
  }

  if(!initFunc(g_pluginRegistry, null))
  {
    throw New!RCException(format("Initializing plugin '%s' failed", pluginName));
  }

  IPlugin newPlugin = getFunc();
  if(newPlugin is null)
  {
    throw New!RCException(format("Getting reloaded plugin '%s' failed", pluginName));
  }

  //First build the type info for the new plugin
  auto types = New!(Hashmap!(string, const(thMemberInfo)[], StringHashPolicy))();
  scope(exit) Delete(types);
  BuildPluginTypeInfo(newPlugin, types);

  //Now patch the roots
  ScanPair[10] oldRoots;
  ScanPair[10] newRoots;
  size_t numOldRoots = oldPlugin.GetScanRoots(oldRoots);
  size_t numNewRoots = newPlugin.GetScanRoots(newRoots);
  if(numOldRoots != numNewRoots)
  {
    throw New!RCException(format("Error reloading plugin '%s': number of roots does not match", pluginName));
  }

  for(size_t i=0; i<numOldRoots; i++)
  {
    //If the address is null its a pure type root, and not a global variable
    if( oldRoots[i].addr !is null)
    {
      if(oldRoots[i].type != newRoots[i].type)
      {
        asm { int 3; } //root type does not match
      }
      //Patch the root
      memcpy(newRoots[i].addr, oldRoots[i].addr, oldRoots[i].type.tsize);
    }
  }

  //Now patch all vptrs
  {
    auto context = PatchObjectsContext(types, oldPlugin);
    foreach(ref root; oldRoots[0..numOldRoots])
    {
      if(root.addr !is null)
      {
        void* p = *cast(void**)root.addr;
        if(p !is null)
          context.PatchObject(p, root.type);
      }
    }
  }

  m_loadedPlugins[pluginIndex].plugin = newPlugin;
}

struct PatchObjectsContext
{
  Hashmap!(string, const(thMemberInfo)[], StringHashPolicy) types;
  Hashmap!(void*, bool, PointerHashPolicy) alreadyPatched;
  IPlugin plugin;

  this(Hashmap!(string, const(thMemberInfo)[], StringHashPolicy) types, IPlugin plugin)
  {
    this.types = types;
    this.plugin = plugin;
    alreadyPatched = New!(typeof(alreadyPatched))();
  }

  ~this()
  {
    Delete(alreadyPatched);
  }

  //returns the TypeInfo for the given address and TypeInfo object. For class instances a additional lookup has to be done.
  static const(TypeInfo) resolveType(void* addr, const TypeInfo type)
  {
    if(type.type != TypeInfo.Type.Class)
      return type;
    Object o = cast(Object)addr;
    return o.classinfo;
  }

  //casts a interface to an object
  static Object resolveInterface(void* addr)
  {
    auto pi = **cast(Interface***)addr;
    auto o = cast(Object)(addr - pi.offset);
    return o;
  }

  //Patches an object
  void PatchObject(void* addr, const TypeInfo type)
  {
    if(addr is null)
      return;
    if(!plugin.isInPluginMemory(addr))
      return;

    //Make sure to patch each address only once
    if(alreadyPatched.exists(addr))
      return;
    alreadyPatched[addr] = true;

    auto rttiInfo = getRttiInfo(type);
    if(type.type == TypeInfo.Type.Class)
    {
      string mangeledTypeName = rttiInfo[0].name;
      if(!types.exists(mangeledTypeName))
      {
        asm { int 3; } //type not found in type list
      }
      TypeInfo_Class newType = cast(TypeInfo_Class)cast(void*)(types[mangeledTypeName][0].type);
      debug writefln("Patching %s at %x", newType.GetName(), addr);
      //Patch the vtbl and the rest of the object header
      void[] initMem = newType.init;
      memcpy(addr, initMem.ptr, __traits(classInstanceSize, Object)); 

      //Now patch all the interface vtbls
      for(TypeInfo_Class cur = newType; cur !is null; cur = cur.base)
      {
        foreach(ref i; cur.interfaces)
        {
          *cast(void**)(addr + i.offset) = *cast(void**)(newType.init.ptr + i.offset);
        }
      }
    }
    else if(type.type == TypeInfo.Type.Interface)
    {
      auto o = resolveInterface(addr);
      if(o.classinfo !is null) //if the object has already been deleted the classinfo is null
        PatchObject(cast(void*)o, o.classinfo);
      return;
    }

    if(rttiInfo.length <= 1)
      return;

    foreach(ref info; rttiInfo[1..$])
    {
      auto plainType = unqualHelper(info.type);
      switch(plainType.type)
      {
        case TypeInfo.Type.Class:
        case TypeInfo.Type.Interface:
          {
            void* p = *cast(void**)(addr + info.offset);
            if(p !is null)
              PatchObject(p, plainType);
          }
          break;
        case TypeInfo.Type.Struct:
          PatchObject(addr + info.offset, plainType);
          break;
        case TypeInfo.Type.Pointer:
          {
            void* p = addr + info.offset;
            if(p !is null)
              PatchObject(*cast(void**)p, plainType.next);
          }
          break;
        case TypeInfo.Type.Array:
          {
            auto elementType = unqualHelper(plainType.next);
            immutable elementSize = elementType.tsize();
            void[] array = *cast(void[]*)(addr + info.offset);

            void* cur = array.ptr;
            void* end = cur + (elementSize * array.length);
            if(elementType.type == TypeInfo.Type.Class || elementType.type == TypeInfo.Type.Interface)
            {
              for(; cur < end; cur += elementSize)
              {
                void* p = *cast(void**)cur;
                if(p !is null)
                  PatchObject(p, elementType);
              }
            }
            else if(elementType.type == TypeInfo.Type.Pointer)
            {
              for(; cur < end; cur += elementSize)
              {
                void* p = *cast(void**)cur;
                if(p !is null)
                  PatchObject(p, elementType.next);
              }
            }
            else
            {
              for(; cur < end; cur += elementSize)
              {
                PatchObject(cur, elementType);
              }
            }
          }
          break;
        case TypeInfo.Type.StaticArray:
          {
            auto t = cast(const(TypeInfo_StaticArray))cast(void*)plainType;
            auto elementType = unqualHelper(plainType.next);
            immutable elementSize = elementType.tsize();

            void* cur = addr + info.offset;
            void* end = cur + (t.len * elementSize);
            if(elementType.type == TypeInfo.Type.Class || elementType.type == TypeInfo.Type.Interface)
            {
              for(; cur < end; cur += elementSize)
              {
                void* p = *cast(void**)cur;
                if(p !is null)
                  PatchObject(p, elementType);
              }
            }
            else if(elementType.type == TypeInfo.Type.Pointer)
            {
              for(; cur < end; cur += elementSize)
              {
                void* p = *cast(void**)cur;
                if(p !is null)
                  PatchObject(p, elementType.next);
              }
            }
            else
            {
              for(; cur < end; cur += elementSize)
              {
                PatchObject(cur, elementType);
              }
            }
          }
          break;
        default:
          //non-recursive type, nothing to do
          break;
      }
    }
  }
}</pre><p> </p>
<p>For my current physics simulation plugin this is already enough to reload it at runtime. Usually I have two visual studio instances open at the same time. One running the main application in the debugger. I use this instance to debug issues and make changes. When the changes are done I switch to the second visual studio instance which only has a solution with the physics simulation plugin in it. This visual studio instance is only used to recompile the plugin. When I then give the focus back to the game application, it checks for modified files, reloads the plugin because it was modified and then I can see the results of my changes right away.</p>
<p>There are obviously many issues left to be addressed. The next one I will focus on is reloading a plugin, which changed the structure of some of its classes. I plan to serialize all class instances and deserialize them again with the new plugin code. As the address of all these instances will change all references to these instances have to be found and patched, witch will be the hard part of it. </p>
<p>I recognize that the solution presented here only works with all the preconditions I listed and might not be aplicable for other fields of software developement, which is a huge downside. Despite this, I hope that it holds some interresting information for other fields of software developement too.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=25</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Real World Comparison, GC vs. Manual Memory Management</title>
		<link>http://3d.benjamin-thaut.de/?p=20</link>
		<comments>http://3d.benjamin-thaut.de/?p=20#comments</comments>
		<pubDate>Wed, 05 Sep 2012 10:54:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>
		<category><![CDATA[OpenGL Demos]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=20</guid>
		<description><![CDATA[During the 4th Semester of my studies I wrote a small 3d spaceship deathmatch shooter with the D-Programming language. It was created within 3 Months time and allows multiple players to play deathmatch over local area network. All of the &#8230; <a href="http://3d.benjamin-thaut.de/?p=20">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><iframe width="560" height="315" src="http://www.youtube.com/embed/mR2EQy3RRyM" frameborder="0" allowfullscreen></iframe></p>
<p>During the 4th Semester of my studies I wrote a small 3d spaceship deathmatch shooter with the D-Programming language. It was created within 3 Months time and allows multiple players to play deathmatch over local area network. All of the code was written with a garbage collector in mind and made wide usage of the D standard library phobos. After the project was finished I noticed how much time is spend every frame for garbage collection, so I decided to create a version of the game which does not use a GC, to improve performance.</p>
<p><span id="more-20"></span></p>
<p>In a pc game you usually want to achive 60 FPS (frames per second). That means you<br />
have 16.6 ms time to simulate and render a single frame. Also you have to prevent big variations in frame time, as this will lead to visual stuttering or other issues. </p>
<p>I created three version of the game for comparsion:</p>
<ul>
<li><strong>GC Version compiled with DMD</strong>: The original version of the game. Compiled with dmd 2.058 (-O -release -noboundscheck -inline). Not all memory is managed by the garbage collector. Large blocks of memory that only contain data and no pointers are allocated manually to improve garbage collector performance. In this version the GC is run manually once every frame, otherwise the frame times would vary to much, as you would get collection times of multiple seconds, which is not acceptable for games.</li>
<li><strong>GC Version compiled with GDC</strong>: Same as above just compiled with 2.058 GDC eqivalent. (-fno-bounds-check -frelease -O -finline-small-functions -findirect-inlining -fpartial-inlining -fpeephole2 -fregmove)</li>
<li><strong>Manually Memory Managed Version compiled with DMD</strong>: I throw away most of phobos and wrote my own replacements for it with different interfaces, as the phobos interfaces are usually not suitable for manual memory management. Small parts of phobos could be reused, for example std.traits. Also I made quite some changes to druntime. I added a reference counting mechanism to druntime to make threads reference counted. Also I added a memory tracker which would track and report memory leaks on program ending. Also all parts of druntime that did leak memory during developement have been fixed. For example I implemented a non leaking cache friendly hashmap. This version of the game uses manual memory management most of the time. If manual management is not feasable reference counting is used instead. </li>
</ul>
<p>Other then the memory management code, the code of the GC version and the manual memory management version are exactly the same. This is the ideal real world comparison for GC vs. manual memory management. </p>
<p><strong>Results</strong></p>
<ul>
<li>DMD GC Version: 71 FPS, 14.0 ms frametime</li>
<li>GDC GC Version: 128.6 FPS, 7.72 ms frametime</li>
<li>DMD MMM Version: 142.8 FPS, 7.02 ms frametime</li>
</ul>
<p>GC collection times:</p>
<ul>
<li>DMD GC Version: 8.9 ms</li>
<li>GDC GC Version: 4.1 ms</li>
</ul>
<p>The astonishing thing here is, that the manual managed version compiled with dmd is still faster then the highly optimized GC version GDC generates. I could not compile my manually managed version with GDC yet as druntime for GDC has a completely different folder structure and quite some modifications.</p>
<p>Most of this performance improvements come from the fact that the garbage collector does not eat any time. But also if you write code with a GC in mind you often do not think about the consequences when allocating memory, because the GC will deal with it. This often leads to highly imperformant code, the best example is the comparison of TypeInfo objects in druntime, which is described below.</p>
<p><strong>Biggest Performance and Memory Leaking Issues in D 2.0:</strong></p>
<p>Here is a list of the most severe problems I found during developement:</p>
<ul>
<li>Comparision of TypeInfo objects in druntime is done by building two strings and then comparing those two strings. This will always leak memory and do a lot of unneccesary allocations which are a performance bottleneck. I reworte the comparison so it does not allocate a single byte.</li>
<li>Calls to the druntime invariant handler are emitted in release build also and there is no way to turn them off. Even if the class does not have any invariants the invariant handler will always be called, walk the class hirarchy and generate multiple cache misses without actually doing anything.</li>
<li>The new statement will not free any memory if the constructor throws a exception. So you are forced to replace both the new and the delete statement. But you can not replace the new statement with similar nice syntax especially for inner classes and arrays.</li>
<li>Inlining of DMD. Inlining of DMD seems to be very minimal. Most of my overloaded operators are not inlined by dmd at all.</li>
<li>Array literals. They always allocate, even if they don&#8217;t have to. For example when asiging to a fixed size array, or when passing to a function with a scope parameter.</li>
<li>D-Style variadic functions. Same as array literals, because internaly they are rewrote to one. Especially for these kind of functions I don&#8217;t see any reason why they should allocate on the heap.</li>
</ul>
<p>Currently only my modifications to druntime and phobos are aviable on github. But the full sourcecode for my small standard library and the game wil follow soon. All this has been done with dmd 2.058 and the druntime and phobos state of 2.058. But now that I&#8217;m done I will update to 2.060 soon.</p>
<p><a href="https://github.com/Ingrater/druntime">druntime</a> (build with make -f win32nogc.mak, currently only works on windows)<br />
<a href="https://github.com/Ingrater/phobos">phobos</a> (build with make -f win32nogc.mak, currently only works on windows)<br />
<a href="https://github.com/Ingrater/thBase">thBase</a> (my standard library)</p>
<p><strong>Update:</strong><br />
I found a piece of code that did manually slow down the simulation in case it got to fast. This code never kicked in with the GC version, because it never reached the margin. The manual memory managed version however did reach the margin and was slowed down. With this piece of code removed the manual memory managed version runs at 5 ms which is 200 FPS and thus nearly 3 times as fast as the GC collected version.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=20</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alienfx winamp plugin update</title>
		<link>http://3d.benjamin-thaut.de/?p=19</link>
		<comments>http://3d.benjamin-thaut.de/?p=19#comments</comments>
		<pubDate>Tue, 20 Sep 2011 18:50:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=19</guid>
		<description><![CDATA[As no one picked up the developement on the winamp plugin after I released the sourcecode and new alienware laptops keep coming out every year, so I decided to put a litte bit more work into the winamp alienfx plugin. &#8230; <a href="http://3d.benjamin-thaut.de/?p=19">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As no one picked up the developement on the winamp plugin after I released the sourcecode and new alienware laptops keep coming out every year, so I decided to put a litte bit more work into the winamp alienfx plugin. With this update users are able to add support for new laptops themselfs by editing a xml file. I will explain here how to create the xml file.<br />
To download the plugin go to the original post: <a href="http://3d.benjamin-thaut.de/?p=14">AlienFX Winamp plugin</a><br />
<span id="more-19"></span><br />
To follow this guide you need a Alienware laptop or PC with a AlienFX device and some xml editing skills.<br />
First you need to find out the product id of your alienfx device. To do that open the windows hardware manager. Go to start -> control panel -> system -> (top left) device manager.<br />
In the device manager open the &#8220;input devices (Humand Interface Devices)&#8221; group and right click onto the first &#8220;USB-input device&#8221; in the list. Go to properties. </p>
<p><img src="http://3d.benjamin-thaut.de/Bilder/HardwareManager.jpg" alt="windows hardware manager" /></p>
<p>In the properties window go to details and select &#8220;Hardware-IDs&#8221; from the dropdown list.</p>
<p><img src="http://3d.benjamin-thaut.de/Bilder/properties.jpg" alt="usb device properties" /><br />
The shown lines should start with &#8220;USB\VID_187C&#8221;.</p>
<p>If they do thats the AlienFX device. If not you have to try the other usb input devices. After the VID_187C you can see the product id &#8220;PID_0511&#8243;. You can ignore the PID_ and the zero, that gives us the product id 511 in this case. Because this is hex notation you need to add 0x to the start of the product id, that gives you in this case the final product id <strong>0&#215;511</strong>.<br />
Write down the product id you will need again.<br />
Now download the AlienFX leds tester from here: <a href="http://3d.benjamin-thaut.de/Files/file.php?id=10">AlienFX leds tester</a><br />
Start the program and follow the instructions until it asks you if you want to test a custom device.<br />
Press Y and enter to answer with yes. Now type in the product id you just wrote down.<br />
Next it is going to ask you if it is a new alienfx device. If the winamp plugin does not support your device by default, it is most likely a new device, so press y and enter. Now follow the instructions until the program ends. If none of the alienfx leds on your laptop changed while the program ran, it did not work. If everything worked fine you should end up with a results.log file in the same directory that contains the leds tester. It should look something like this:</p><pre class="crayon-plain-tag">Old Alienfx Device
Model description: Area-51 m15x
Leds still on: power led
Led 0x1: touchpad
Led 0x20: light pipe
Led 0x80: alienware logo
Led 0x100: alienhead
Led 0x10000: touchbar</pre><p>Keep this file open you are going to need it.<br />
No go to your &#8220;appData/Winamp/plugins&#8221; directory (&#8220;C:\Users\Your Username\appdata\Roaming\Winamp\Plugins&#8221; for Vista and 7)<br />
Create an empty textfile and name it &#8220;alienfx_vis_devices.xml&#8221; (make shure you have &#8220;hide known file endings&#8221; disabled in the windows folder options). Edit this xml file and paste the following template into it:</p><pre class="crayon-plain-tag">&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;devices&gt;
  &lt;device name=&quot;device name&quot; protocolVersion=&quot;protocol version&quot; productId=&quot;product id&quot;&gt;
  &lt;/device&gt;
&lt;/devices&gt;</pre><p>Enter the name of your laptop into the name attribute. If you have a new alienfx device (anything newer then the Area-51 series) enter 2 for the protocol version, otherwise enter 1. Usually you want to enter 2 for the protocol version as all laptops with the old protocol version are supported by default.<br />
for the productId enter the product id you just found out.<br />
Now you need to add the following line inside the devices node for each led you have on your laptop:</p><pre class="crayon-plain-tag">&lt;led name=&quot;Led Name&quot; code=&quot;led code&quot; /&gt;</pre><p>For name enter the name of your led, and for code enter the code for that led. You can find the code in the results.log file you should still have open. The format in the results.log is: &#8220;Led (led code): (led name)&#8221;.<br />
When you are done editing the xml file it should look like this:</p><pre class="crayon-plain-tag">&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;devices&gt;
  &lt;device name=&quot;Area-51 mx 15&quot; protocolVersion=&quot;1&quot; productId=&quot;0x511&quot;&gt;
    &lt;led name=&quot;Touchpad&quot;        code=&quot;0x000001&quot; /&gt;
    &lt;led name=&quot;Lightpipe&quot;       code=&quot;0x000020&quot; /&gt;
    &lt;led name=&quot;Alienware Logo&quot;  code=&quot;0x000080&quot; /&gt;
    &lt;led name=&quot;Keyboard&quot;        code=&quot;0x000400&quot; /&gt;
    &lt;led name=&quot;Power Button&quot;    code=&quot;0x008000&quot; /&gt;
    &lt;led name=&quot;Touchpanel&quot;      code=&quot;0x010000&quot; /&gt;
  &lt;/device&gt;
&lt;/devices&gt;</pre><p>Fire up winamp, start the plugin. If you made any mistakes there should be error messages telling you what you did wrong. Fix the erros and try again. If everything started without errors you can go to the config dialog and configure the leds to respond to certain beats, and test the plugin. If you have a working xml for your laptop be nice and upload it to notebookrecords.com and/or send me a e-mail with the xml attachted to it. It is also possible to enter multiple devices into this xml file. Just add additional &#8220;device&#8221; nodes to the xml file. The plugin will try all devices in the xml file upon start, and use the first one it is able to find.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=19</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suggestions for the D 2.0 Programming Language</title>
		<link>http://3d.benjamin-thaut.de/?p=18</link>
		<comments>http://3d.benjamin-thaut.de/?p=18#comments</comments>
		<pubDate>Sat, 27 Aug 2011 17:09:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>
		<category><![CDATA[D 2.0]]></category>
		<category><![CDATA[suggestions]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=18</guid>
		<description><![CDATA[First of all don&#8217;t take this article to negative. I really like the D programming language and often when I have to go back to C++ coding im sitting in front the code thinking &#8220;Oh this would be so much &#8230; <a href="http://3d.benjamin-thaut.de/?p=18">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>First of all don&#8217;t take this article to negative. I really like the D programming language and often when I have to go back to C++ coding im sitting in front the code thinking &#8220;Oh this would be so much easier in D&#8221; or &#8220;This could be solved much cleaner in D&#8221;.<br />
I recently completed 3 Projects using the D 2.0 programming language:<br />
- A implementation of the Light Propagation Volumes algorithm<br />
- A 3d multiplayer cross platfrom (windows / linux) space shooter<br />
- A lisp interpreter (with almost all Scheme features)</p>
<p>The two 3D projects have been done using OpenGL and are very performance critical. You only get to spend 16ms every frame until it has to be completely rendered otherwise you won&#8217;t reach fluent framerates. The lisp interpreter was performance critical too, but more of a test how good D is usable as a systems programming language.</p>
<p><span id="more-18"></span></p>
<p><strong>1. Assert</strong><br />
Assert throwing a exception is very unhandy for debugging a application, especially when some of the stacktracing and stack unwinding happend before the debugger actually gets the signal. This often lead to not beeing able to see where the assert actually triggered. Usually I had to look it up in the console output, set a breakpoint at the perticular assert and rerun the application which added quite some turnaround time. Using a custom assert is also not possible because the compiler will complain about certain &#8220;not reachable&#8221; problems. Only the builtin assert is recognized by the compiler and there is no way of flagging another function as assert. Either the builtin assert should be configureable so that it triggers a breakpoint before throwing the exception, or there sould be a way to built a custom assert because something like this feels wrong:</p>
<p></p><pre class="crayon-plain-tag">bool bar(){
  switch(foo){
    case 1:
      ...
    default:
      ... 
  }
  myAssert(0,&quot;not reachable&quot;);
  assert(0,&quot;not reachable&quot;);
}</pre><p></p>
<p><strong>2. Emplace requiring the exact constructor argument types</strong><br />
Using D with manual memory management is a very nice thing, besides not beeing able to use phobos then and having to be very carefull when handeling arrays. But as the new and delete operator are deprecated one problem within phobos should be adressed:<br />
When using emplace to create a struct or class emplace is not aware of the consturctor overloading rules and unless given the exact same types as the constructor it is not able to construct the object:</p>
<p></p><pre class="crayon-plain-tag">class foo {
  this(int* addr){ ... }
}

void[__traits(classInstanceSize,foo)] mem;
emplace!bar(mem,null); //this will not compile</pre><p></p>
<p><strong>3. Structs not having identity</strong><br />
Structs in D don&#8217;t have identity, meaning they can be copied around by the compiler whenever he wants. This was especially a problem when implementing a custom GC for the Lisp interpreter. Because I wanted to implement a Baker GC which requires to know the addresses of all references on the stack I wanted to do something like this:</p>
<p></p><pre class="crayon-plain-tag">struct Ref(T) if(is(T == class)){
  T m_Ref;
  this(T pRef){
    m_Ref = pRef;
    myGC.addRoot(&amp;m_Ref);
  }

  ~this(){
    myGC.removeRoot(&amp;m_Ref);
  }
}</pre><p></p>
<p>Unfortunaltey when the destructor gets called m_Ref can have a completely differend address and therefore can not be deregistred at the garbagecollector. I ended up adding a assert into the desturctor telling me when the address changed and not using any exception handling because I figured that the struct copying then will not happen. But that is not a acceptable solution for the problem. Adding one level of indirection to every reference is also not acceptable for performance reasons. Now I&#8217;m not saying that structs should have identity, there should just be just a way to get notified when a struct gets moved. Maybe a move constructor, something like</p>
<p></p><pre class="crayon-plain-tag">struct Ref(T){
  ...
  this(this,void* oldAddr){
    myGC.removeRoot(oldAddr);
    myGC.addRoot(&amp;m_Ref);
  }
}</pre><p></p>
<p>This feature coupeled with the discussed -nogc flag that would replace every reference in the sourcecode with a Ref template inside _object.d would actually allow implementing GCs for the D language that are not based on the mark &#038; sweep approach, because they could track references. (There needs to be a different solution for references inside classes and structures of course)</p>
<p><strong>4. Implicit constructors</strong><br />
A feature I actually like sometimes about C++ is implicit constructors. They often cause a lot of problems but when used correctly they can be very usefull. Again given the &#8220;lets implement a different GC&#8221; task:</p>
<p></p><pre class="crayon-plain-tag">void foo(Object bar){
  ...
}

foo(new Object());</pre><p></p>
<p>If you now want to replace all refrences with a template it would look something like this:</p>
<p></p><pre class="crayon-plain-tag">void foo(Ref!Object bar){
  ...
}</pre><p></p>
<p>As new does return a Object and not a Ref!Object this will not compile. If there would be a way to define implicit constructors<br />
this problem could be solved:</p>
<p></p><pre class="crayon-plain-tag">struct Ref(T){
  implicit this(T pRef){
    ..
  }
}</pre><p></p>
<p>This would introduce a new keyword to the D programming language doing the exact opposide of C++ explicit. You have to delcare implicit constructors not explicit ones. This would be the same &#8220;I know what I am doing&#8221; approach D usually uses.</p>
<p><strong>5. Shared</strong><br />
Maybe I&#8217;m not getting this keyword, but I consider shared not beeing usable. I would highly appreciate a offical document about how shared sould be used, and not only in some small mini example using message passing, but in a realworld performance critical example.<br />
Say for example I have a Stack container:</p>
<p></p><pre class="crayon-plain-tag">class Stack(T){
  ...
  void push(T el){ ... }
  T pop(){ ... }
  bool empty(){ ... }
}</pre><p></p>
<p>And now I need a threadsafe version of it. Should be quite easy, especially because D supports synchronized classes:</p>
<p></p><pre class="crayon-plain-tag">synchronized class ThreadsafeStack(T){
  Stack!T m_Stack;
  void push(T el){ m_Stack.push(el); }
  T pop() { return m_Stack.pop(); }
  bool empty(){ return m_Stack.empty(); }
}</pre><p></p>
<p>This will not compile! Because synchronized classes are implicitly shared and shared is transitive, m_Stack will be shared and thus calling the methods of Stack!T is not possible because they are not shared. This transitivy basically kills you everywhere. If you have a shared class basically everything in the hirarchy it accesses has to be shared too. The only way out of this is casting shared away and that just looks and feels plain ugly in the code.</p>
<p></p><pre class="crayon-plain-tag">synchronized class ThreadsafeStack(T){
  Stack!T m_Stack;
  void push(el T){ 
    Stack!T stack = cast(Stack!T) m_Stack;
    stack.push(el);
  }
  ...
}</pre><p></p>
<p>Also the future plan that inside shared methods memory barries will be inserted by the compiler automatically gets me concerened. Especially for performance cirtical applications this will be a performance killer and ist not even needed in most cases. (At least in my experience). As it currently stands I just try to avoid shared completely.</p>
<p>Here is another example. I wanted to create a shared inteface to provide cross thread debug drawing for my application:</p>
<p></p><pre class="crayon-plain-tag">shared interface IDebugDraw {
  void DrawBox(vec3 min, vec3 max);
}</pre><p></p>
<p>The renderer already implemented a non threadsafe version of this method:</p>
<p></p><pre class="crayon-plain-tag">class Renderer {
  void DrawBox(vec3 min, vec3 max){ ... }
}</pre><p></p>
<p>So I just wanted to implement the interface by doing some synchronization and then calling the non threadsafe version:</p>
<p></p><pre class="crayon-plain-tag">class Renderer : IDebugDraw {
  void DrawBox(vec3 min, vec3 max) { ... }
  void DrawBox(vec3 min, vec3 max) shared {
    synchronized(m_DebugDrawMutex){
    	Renderer self = cast(Renderer)this;
    	self.DrawBox(min,max);
    }
  }
}</pre><p></p>
<p>This will not compile because you cant overload using shared. Choosing a different name for the function just to differ between the threadsafe and non threadsafe version seems strange to me especially when you have a feature in the type system that should exactly do that.</p>
<p>Another problem is that you are not able to define shared delegates. The type the compiler puts out can actually not be used in sourcecode.</p>
<p></p><pre class="crayon-plain-tag">class Foo {
  void bar() shared {}
}

void main(string[] args){
  Foo foo;
  static assert(0,typeof(&amp;foo.bar).stringof);
}</pre><p></p>
<p>If you do this the compiler will put out: &#8220;void delegate() shared&#8221; as type for bar.<br />
If you now try to use this:</p>
<p></p><pre class="crayon-plain-tag">void main(string[] args){
  Foo foo;
  void delegate() shared del = &amp;foo.bar;
}</pre><p></p>
<p>It will not compile. Also tried all kinds of variations:</p>
<p></p><pre class="crayon-plain-tag">(void delegate() shared) del = &amp;foo.bar;
shared(void delegate()) del = &amp;foo.bar;
void shared delegate() del = &amp;foo.bar;</pre><p></p>
<p>None of them will work.</p>
<p><strong>6.Thread Local Storage</strong><br />
There has been a particulary ugly bug in one of my projects connected to TLS. In total TLS was one of the most frequent causes for bugs. Most likely because I was not used to it, but still I want to mention this here:</p>
<p></p><pre class="crayon-plain-tag">class Foo {
  static Manager m_Manager; //unamanged class will not be scanned by GC, there is 1 manager for each thread

  this(){
    m_Manager.register(this);
  }

  ~this(){
   m_Manager.unregister(this);
  }
}</pre><p></p>
<p>As you don&#8217;t know in which thread the destructor will be executed as the GC may run in any thread, you can not tell if the class wil actually unregister itself on the same Manager it registered itself. The next thing I tried is creating a lambda inside the destructor and send it to the correct thread to perform the deregistering, unfortunatley this is not possible because no allocations can happen inside the constructor because the GC is currently collecting.<br />
The same problem was also a major issue when freeing OpenGL resources. As the resources have to be freed in the thread that holds the OpenGL context it would crash everytime the GC ran in a different thread than that one. I think there should be at least a warning by the compiler if TLS variables are used inside a destructor because you never know if the TLS variables actually contain what you expect.</p>
<p><strong>7. Associative array invariance</strong><br />
This was actually the second most frequent cause for bugs in my projects. Especially because you don&#8217;t get any warnings or asserts in the debug build about it. It just goes into undefined behaviour. If possible the associative array should track all its ranges and see if one of them is still iterating. If so there should be a exception or an assert when trying to change the associative array.</p>
<p><strong>8. std.concurreny TID does not support shared</strong><br />
This is really a pitty. The message passing mechanic prised in the TDPL book does not support shared TID types. Usually you would assume that you can share the TID structure and work on it as the message passing should be threadsafe. Casting away the shared everytime is a pain.</p>
<p><strong>8. No function overloading with template parameters</strong><br />
This one got me especially disappointed after reading Andreis &#8220;Modern C++ Design&#8221; Book. In there he describes a trick in C++ to overload Functions with template parameters which looks in D basically like this:</p>
<p></p><pre class="crayon-plain-tag">struct Type2Type(T){
}

class Foo1 {
  void funcHelper(Type2Type!int p){
    writefln(&quot;a&quot;);
  }
}

class Foo2 : Foo1 {
  alias Foo1.funcHelper funcHelper;
  void funcHelper(Type2Type!float p){
    writefln(&quot;b&quot;);
  }
  
  void func(T)(){
    funcHelper(Type2Type!(T)());
  }
}

void main(string[] args){
	Foo2 foo;
	foo.func!float();
	foo.func!int();
}</pre><p></p>
<p>Now I thought that in D it would be possible to do this without this trick as you are able to restrict tempaltes:</p>
<p></p><pre class="crayon-plain-tag">class Foo1 {
  void func(T)() if(is(T == int)){
    writefln(&quot;a&quot;);
  }	
}

class Foo2 : Foo1 {
  alias Foo1.func func;
  void func(T)() if(is(T == float)){
    writefln(&quot;b&quot;);
  }
}</pre><p></p>
<p>Unfortunately this will not compile:</p><pre class="crayon-plain-tag">Error: alias test.Foo2.func conflicts with template test.Foo2.func(T) if (is(T == float))</pre><p></p>
<p>Other then that the biggest problem with the D programming language for me is that the tools are not really major yet. But hopefully this will improve over time.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=18</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AlienFX Winamp plugin update &amp; source</title>
		<link>http://3d.benjamin-thaut.de/?p=17</link>
		<comments>http://3d.benjamin-thaut.de/?p=17#comments</comments>
		<pubDate>Sat, 14 May 2011 14:42:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[alienfx]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=17</guid>
		<description><![CDATA[With some help of Nils Reichert I was able to modifiy my AlienFX Winamp plugin so that it now supports the M17X R3. It should also support the M15X R3 now as the used AlienFX devices should be the same. &#8230; <a href="http://3d.benjamin-thaut.de/?p=17">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>With some help of Nils Reichert I was able to modifiy my AlienFX Winamp plugin so that it now supports the M17X R3. It should also support the M15X R3 now as the used AlienFX devices should be the same. You can find the download locations in my old post:</p>
<h3 class="storytitle"><a rel="bookmark" href="../?p=14">&gt;&gt;&gt; Winamp AlienFX Plugin &lt;&lt;&lt;</a></h3>
<p>I also decided to release the source code for both the plugin itself and the led tester I&#8217;ve written, so that someone else can continue the developement as I don&#8217;t have time for it anymore. You can freely modifiy the programm under the following conditions:</p>
<ul>
<li>you have to name me as original author</li>
<li>you may not use it for anything commercial</li>
<li>you have to distribute it under the same conditions then I do</li>
</ul>
<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/de/"><img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/de/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">AlienFX Winamp Plugin</span> von <a xmlns:cc="http://creativecommons.org/ns#" href="http://3d.benjamin-thaut.de/" property="cc:attributionName" rel="cc:attributionURL">Benjamin Thaut</a> steht unter einer <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/de/">Creative Commons Namensnennung-Nicht-kommerziell-Weitergabe unter gleichen Bedingungen 3.0 Deutschland Lizenz</a>.</p>
<p><br/><br />
Sourcecode: <a href="http://3d.benjamin-thaut.de/Files/file.php?id=9">AlienFX-Winamp-plugin-source.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=17</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Light Propagation Volumes Implementation</title>
		<link>http://3d.benjamin-thaut.de/?p=16</link>
		<comments>http://3d.benjamin-thaut.de/?p=16#comments</comments>
		<pubDate>Mon, 07 Mar 2011 18:39:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>
		<category><![CDATA[OpenGL Demos]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=16</guid>
		<description><![CDATA[For a university project I implemented the Light Propagation Volumes technique implemented in CryEngine 3 to simulate indirect illumination. I wrote this demo from scratch using OpenGL and the D programming language. The paper about the alogrithm can be found &#8230; <a href="http://3d.benjamin-thaut.de/?p=16">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.youtube.com/watch?v=S1gzb2tXipc"><img src="http://3d.benjamin-thaut.de/Bilder/lpv_screenshot.jpg" alt="screenshot of the light propagation volumes demo" /></a></p>
<p>For a university project I implemented the Light Propagation Volumes technique implemented in CryEngine 3 to simulate indirect illumination. I wrote this demo from scratch using OpenGL and the D programming language. </p>
<p>The paper about the alogrithm can be found here:<br />
<a href="http://www.vis.uni-stuttgart.de/~dachsbcn/download/lpv.pdf">http://www.vis.uni-stuttgart.de/~dachsbcn/download/lpv.pdf</a></p>
<p>The model and textures have been taken from the crytek site: <a href="http://www.crytek.com/cryengine/cryengine3/downloads">http://www.crytek.com/cryengine/cryengine3/downloads</a></p>
<p>You can download the application for windows including the full sourcecode and documentation here:<br />
<a href="http://3d.benjamin-thaut.de/Files/file.php?id=8">lpv-release.zip</a><br />
To fly around in the scene klick into the 3d window and press M to activate the mouse, then you can fly around using the WASD keys and the mouse. To deactivate the mouse looking press M again.<br />
For everything else you can use the GUI.<br />
<br/><br />
<a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">Implementation of Light Propagation Volumes</span> von <a xmlns:cc="http://creativecommons.org/ns#" href="http://3d.benjamin-thaut.de" property="cc:attributionName" rel="cc:attributionURL">Benjamin Thaut</a> steht unter einer <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Namensnennung 3.0 Unported Lizenz</a>.<br />Beruht auf einem Inhalt unter <a xmlns:dct="http://purl.org/dc/terms/" href="http://www.vis.uni-stuttgart.de/~dachsbcn/download/lpv.pdf" rel="dct:source">www.vis.uni-stuttgart.de</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=16</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>D 2.0 Stacktrace</title>
		<link>http://3d.benjamin-thaut.de/?p=15</link>
		<comments>http://3d.benjamin-thaut.de/?p=15#comments</comments>
		<pubDate>Wed, 06 Oct 2010 11:48:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[D programming]]></category>
		<category><![CDATA[D 2.0]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=15</guid>
		<description><![CDATA[I wrote a small piece of sourcecode that generates stacktraces in D 2.0 under windows. It works both with the pdb and cv debug symbol format. For Exceptions that are derived from the Error or Exception class the trace information &#8230; <a href="http://3d.benjamin-thaut.de/?p=15">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I wrote a small piece of sourcecode that generates stacktraces in D 2.0  under windows. It works both with the pdb and cv debug symbol format.  For Exceptions that are derived from the Error or Exception class the trace  information is automatically appended, this causes all builtin D errors  to get a stacktrace information. The only point where this does not work is the Access Vioaltion error, as it does not call the stacktrace callback function for some reason.</p>
<p><img class="alignright" src="http://3d.benjamin-thaut.de/Bilder/stack-example.jpg" alt="stack trace example" width="537" height="178" /></p>
<p><span id="more-15"></span></p>
<p>It is very easy to use, just copy the two files from the zip archive to your root source directory and import the stacktrace module inside your main file.</p>
<p><code>import stacktrace;</code><br />
<code> </code><br />
<code>void main(string[] argv){</code><br />
<code> ...</code><br />
<code>}</code></p>
<p>Now all Errors will get trace information.<br />
If you need a backtrace at a certain point in your code just do the following:</p>
<p><code>module foo;</code></p>
<p><code>import stacktrace;</code></p>
<p><code>void blup(){</code><br />
<code> ...</code><br />
<code> StackTrace trace = new StackTrace();</code><br />
<code> auto stack = trace.GetCallstack();</code><br />
<code> foreach(char[] s;stack)</code><br />
<code> writefln("%s",s);</code><br />
<code> ...</code><br />
<code>}</code></p>
<p>Download: <a href="http://3d.benjamin-thaut.de/Files/file.php?id=7">d2stacktrace.zip (12 kb)</a></p>
<p>It is released under the &#8220;Creative Commons by&#8221; license. If this licence causes any problems for you, feel free to contact me and we will fix the problem.</p>
<p>XP Users:<br />
If you get a stacktrace with numbers only download a new version of dbghelp.dll (it comes with the windows platform SDK) and put it into your project root directory. That should fix it.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">D2 Stacktrace</span> von <a xmlns:cc="http://creativecommons.org/ns#" href="http://3d.benjamin-thaut.de/?p=15#more-15" property="cc:attributionName" rel="cc:attributionURL">Benjamin Thaut</a> steht unter einer <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Namensnennung 3.0 Unported Lizenz</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=15</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Winamp AlienFX Plugin</title>
		<link>http://3d.benjamin-thaut.de/?p=14</link>
		<comments>http://3d.benjamin-thaut.de/?p=14#comments</comments>
		<pubDate>Sat, 03 Apr 2010 12:28:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[alienfx]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[winamp]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=14</guid>
		<description><![CDATA[I made plugin for Alienwares AlienFX Device that comes with every Alienware laptop and computer. Currently the following models are supported: Area51 m15x All Powerfull m15x All Powerfull m17x All Powerfull m11x A demonstration of the plugin by Lord_Zath form &#8230; <a href="http://3d.benjamin-thaut.de/?p=14">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I made plugin for <a href="http://www.alienware.com">Alienwares</a> AlienFX Device that comes with every <a href="http://www.alienware.com">Alienware</a> laptop and computer. Currently the following models are supported:</p>
<ul>
<li>Area51 m15x</li>
<li>All Powerfull m15x</li>
<li>All Powerfull m17x</li>
<li>All Powerfull m11x</li>
</ul>
<p>A demonstration of the plugin by Lord_Zath form NBR (<a href="http://www.notebookreview.com">www.notebookreview.com</a>) can be found at:<br />
<a href="http://www.youtube.com/watch?v=dLymX4fLVtc">www.youtube.com/watch?v=dLymX4fLVtc</a></p>
<p><strong>Download:</strong> <a href="http://3d.benjamin-thaut.de/Files/file.php?id=6">vis_alienfx.zip (257 kb)</a></p>
<p>Please be shure to read the README file. It contains important instructions howto setup and configure the plugin! Also I want to thank Lord_Zath for helping me test the plugin and writing the README file. A thank you also goes to all the people on NBR which are taking part in the developement of this plugin.</p>
<p>If you have a Alienware laptop / computer that is not yet supported and you are willing to help me developing the support for it, please contact me, and I will built in the support for your model.</p>
<p><strong>Update 31.10.2010:</strong> Fixed that the plugin is crashing winamp when closing winamp or stopping the plugin. The plugin now also automatically detects on which alienware laptop it is running.</p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=14</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Easyhook tipps and tricks</title>
		<link>http://3d.benjamin-thaut.de/?p=13</link>
		<comments>http://3d.benjamin-thaut.de/?p=13#comments</comments>
		<pubDate>Sat, 26 Sep 2009 15:58:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[easyhook]]></category>

		<guid isPermaLink="false">http://3d.benjamin-thaut.de/?p=13</guid>
		<description><![CDATA[I wanted to hook the WinApi funktion CreateFile, CloseHandle, ReadFile and WriteFile to decode a device protocol. So I searched for a hooking library in the internet. Unfortunately the only good one for c++ was detour from Mircrosoft which was &#8230; <a href="http://3d.benjamin-thaut.de/?p=13">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I wanted to hook the WinApi funktion CreateFile, CloseHandle, ReadFile and WriteFile to decode a device protocol. So I searched for a hooking library in the internet. Unfortunately the only good one for c++ was detour from Mircrosoft which was free only for x86 non comercial use. As my laptop runs with a x64 Windows Vista this was no option for me. So I found easyhook, a c# hooking library. It was quite easy to achive the first success with it, but then I had a few small problems for which I want to describe the solutions here.<br />
<span id="more-13"></span></p>
<p>Lets asume you want to hook a function which easy hook which executes some hooking code before and after the original call:</p>
<p></p><pre class="crayon-plain-tag">[UnmanagedFunctionPointer(...)]
delegate bool DSomeFunc(...);

[DllImport(&quot;somedll.dll&quot;)]
static bool SomeFunc(...);

static bool SomeFunc_Hooked(...){
  some code before original call

  bool ret = SomeFunc(...);

  some code after original call
  return ret;
}</pre><p></p>
<p>You will notice that the code after the original call never gets executed. This is because the DllImport gives you the already hooked function. So you are calling the hooked function from the hooked function. This is prevented by the easyhook lib, by returning the flow to the calling program. (which is a very good thing, because it would lead to a infinite loop)<br />
To avoid this behaviour you have to get the unhooked function from the easyhook library.</p>
<p></p><pre class="crayon-plain-tag">[UnmanagedFunctionPointer(...)]
delegate bool DSomeFunc(...);

private DSomeFunc SomeFuncPtr;

static bool SomeFunc_Hooked(...){
  some code before original call

  bool ret = SomeFuncPtr(...);

  some code after original call
  return ret;
}</pre><p></p>
<p>And in the run method of your injected dll right after installing the hooks.</p>
<p></p><pre class="crayon-plain-tag">...
SomeFuncPtr = LocalHook.GetProcDelegate&lt;DSomeFunc&gt;(&quot;somedll.dll&quot;, &quot;SomeFunc&quot;);
...</pre><p></p>
<p>Now your code after the original api call gets executed!</p>
<p>The second problem I encounterd was on hooking WriteFile:</p>
<p></p><pre class="crayon-plain-tag">[UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Auto,
            SetLastError = true)]
        delegate bool DWriteFile(
            IntPtr hFile,
            byte[] lpBuffer,
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            [In] IntPtr lpOverlapped);

        [DllImport(&quot;kernel32.dll&quot;,
            CharSet = CharSet.Auto,
            SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern bool WriteFile(
            IntPtr hFile,
            byte[] lpBuffer, 
            uint nNumberOfBytesToWrite, 
            out uint lpNumberOfBytesWritten, 
            [In] IntPtr lpOverlapped);

        static bool WriteFile_Hooked(
            IntPtr hFile,
            byte[] lpBuffer,
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            [In] IntPtr lpOverlapped)
        {
            for(uint i=0;i&lt;nNumberOfBytesToWrite;i++){
	      do_something_with(lpBuffer[i]);
	    }
            return WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, lpOverlapped);
        }</pre><p></p>
<p>On every WriteFile call I got a exception in the loop for i=1, because if the call comes from a unmanaged app the byte array has no size and therefore the size 1 is assumed.<br />
To fix the problem one has to use the marshal class and change all the byte arrays to pointers.</p>
<p></p><pre class="crayon-plain-tag">[UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Auto,
            SetLastError = true)]
        delegate bool DWriteFile(
            IntPtr hFile,
            IntPtr lpBuffer, //changed
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            [In] IntPtr lpOverlapped);

        [DllImport(&quot;kernel32.dll&quot;,
            CharSet = CharSet.Auto,
            SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern bool WriteFile(
            IntPtr hFile,
            byte[] lpBuffer, //no need to change here because we are calling that
            uint nNumberOfBytesToWrite, 
            out uint lpNumberOfBytesWritten, 
            [In] IntPtr lpOverlapped);

        static bool WriteFile_Hooked(
            IntPtr hFile,
            IntPtr lpBuffer, //changed
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            [In] IntPtr lpOverlapped)
        {
            byte[] bytes = new byte[nNumberOfBytesToWrite];
            for (uint i = 0; i &lt; nNumberOfBytesToWrite; i++)
                bytes[i] = Marshal.ReadByte(lpBuffer, (int)i);

            for(uint i=0;i&lt;nNumberOfBytesToWrite;i++){
	      do_something_with(bytes[i]);
	    }
            return WriteFile(hFile, bytes, nNumberOfBytesToWrite, out lpNumberOfBytesWritten, lpOverlapped);
        }</pre><p></p>
<p>Now the hook works. The same works for hooking ReadFile but after calling the original function (also use tipp 1!)</p>
<p>For hooking I simply changed the FileMonInject example the source can be downloaded here:<br />
<a href="http://3d.benjamin-thaut.de/Files/FileMonInject.zip">C# Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://3d.benjamin-thaut.de/?feed=rss2&#038;p=13</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
