<?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>RasterGrid Blog &#187; callback</title>
	<atom:link href="http://rastergrid.com/blog/tag/callback/feed/" rel="self" type="application/rss+xml" />
	<link>http://rastergrid.com/blog</link>
	<description>A technical blog from Daniel Rákos (aka aqnuep)</description>
	<lastBuildDate>Tue, 07 Sep 2010 20:49:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>An introduction to OpenGL 4.1</title>
		<link>http://rastergrid.com/blog/2010/08/an-introduction-to-opengl-4-1/</link>
		<comments>http://rastergrid.com/blog/2010/08/an-introduction-to-opengl-4-1/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 19:32:51 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[binary shader]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[fragment shader]]></category>
		<category><![CDATA[geometry shader]]></category>
		<category><![CDATA[GLSL]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[OpenGL ES]]></category>
		<category><![CDATA[stencil]]></category>
		<category><![CDATA[vertex shader]]></category>
		<category><![CDATA[viewport]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=290</guid>
		<description><![CDATA[

The Khronos Group keeps the pace that they set themselves being able to deliver the latest specification of OpenGL less than half year after the revolutionary appearance of OpenGL 4. Abandoning the OpenGL 3.x line of the specification (at least for a while) the new update concentrates on Shader Model 5.0 class GPUs and extensions [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F08%252Fan-introduction-to-opengl-4-1%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F99sxN3%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22An%20introduction%20to%20OpenGL%204.1%22%20%7D);"></div>
<p>The Khronos Group keeps the pace that they set themselves being able to deliver the latest specification of OpenGL less than half year after the revolutionary appearance of OpenGL 4. Abandoning the OpenGL 3.x line of the specification (at least for a while) the new update concentrates on Shader Model 5.0 class GPUs and extensions heavily promoted by the community. Beside all this, the Khronos Group now confessedly opens towards convergence to OpenGL ES making the desktop version of the specification downward compatible with its embedded brother. In this article I would like to present the features introduced with the latest revision of the specification.</p>
<p><span id="more-290"></span>At the time of the release of the OpenGL 4 specification I was able to quickly deliver you a <a title="A brief preview of the new features introduced by OpenGL 3.3 and 4.0" href="http://rastergrid.com/blog/2010/03/a-brief-preview-of-the-new-features-introduced-by-opengl-3-3-and-4-0/">thorough presentation</a> of all the new features introduced by that revision of the specification. This time I am already quite late, however I hope that this article will still prove as value for lots of you, especially for those who haven&#8217;t had time in the recent past to dig into the details of the new API version.</p>
<p>OpenGL 4.1 is not as revolutionary and feature-rich as its predecessor, however the latest revision was well received by the community as it brought such core extensions to the API that the community was waiting for a long time now. The new revision of the specification was accompanied with the appearance of a couple of other ARB extensions that have not yet been included into core, however I will still talk about some of them as they indicate a slight shift in the force of influence of various vendors and representatives inside the <a title="About the OpenGL ARB &quot;Architecture Review Board&quot;" href="http://www.opengl.org/about/arb/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/about/arb/?referer=');">Architecture Review Board (ARB)</a>.</p>
<h2>New features of OpenGL 4.1</h2>
<p>Let&#8217;s start with the presentation of the new features arriving with the OpenGL 4.1 specification primarily targeting Shader Model 5.0 hardware. Here you will see a lot of harmonization features as well as community&#8217;s choice features that squarely intended to increase OpenGL development efficiency and feedom.</p>
<h3><a title="GL_ARB_ES2_compatibility" href="http://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/ES2_compatibility.txt?referer=');">ARB_ES2_compatibility</a></h3>
<p>There have been for a long time rumors about the Khronos Group preparing a convergence between desktop OpenGL and OpenGL ES. This extension of the core specification clearly makes the first step towards this goal by providing an all-in-one specification pack that makes the desktop version of the specification downward compatible with ES. The extension adds support for features of OpenGL ES 2.0 that are missing from OpenGL 3+. According to the extension specification, enabling these features will ease the process of porting applications from OpenGL ES 2.0 to OpenGL.</p>
<p>More precisely, <a title="GL_ARB_ES2_compatibility" href="http://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/ES2_compatibility.txt?referer=');">GL_ARB_ES2_compatibility</a> exposes not just all the functions and tokens that weren&#8217;t present in the desktop version of the specification but also completes it with all the semantics that were exclusively specified only in the embedded version. Just to mention few of these issues:</p>
<ul>
<li>Vertex data format is now extended with the possibility to use 16-bit fixed point values by exposing the GL_FIXED type identifier token.</li>
<li>Providing possibility to query the precision format used internally by shaders.</li>
<li>Enable the use of GLSL ES for writing shaders for desktop GL.</li>
</ul>
<p>While having this extension under the hood does not mean that we can simply pick our last game made for e.g. Symbian and just drop it on our PC, this extension may prove to be great value for GL ES developers migrating their software to desktop platforms.</p>
<h3><a title="GL_ARB_get_program_binary" href="http://www.opengl.org/registry/specs/ARB/get_program_binary.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/get_program_binary.txt?referer=');">ARB_get_program_binary</a></h3>
<p>This is one of the most waited additions to the core specification by the developer community. This extension introduces the possibility to acquire some sort of binary format of the compiled and linked shaders that can be later used to specify the program object directly with its binary code thus providing caching possibility to eliminate the need of compilation and linking next time the shader has to be used. This also makes it possible to create an offline GLSL compiler just using the OpenGL API itself.</p>
<p>Still, it has to be mentioned that having this feature in our hand does not necessarily mean that we can simply create our shader binaries offline and then distribute our software without the shader source itself as the binary formats supported by a particular implementation heavily depend on the hardware vendor as well as driver version. This is due to the fact that the shader binary most probably consists of instructions specially generated for the particular GPU-driver combo. The only way to relax this limitation would be to have some sort of cross-platform byte-code for shaders but that would in fact defeat most of the benefits of the extension on its own. Additionally, this extension does not provide any binary formats but leaves this to vendor specific extensions. It only exposes a common infrastructure for acquiring and loading program binaries.</p>
<p>While the usage of this extension does not completely eliminates the need for shader source compilation, it can limit the need for recompilation and relink to an installation time or first-run time compilation instead and use the stored binaries later. It also opens up room for SDK tools providing shader compilers with more aggressive optimization at their disposal being used offline. Such tools can truly be introduced as the specification explicitly mentions that run-time generated binaries by the GL should be interchangeable with those generated by offline SDK tools.</p>
<h3><a title="GL_ARB_separate_shader_objects" href="http://www.opengl.org/registry/specs/ARB/separate_shader_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/separate_shader_objects.txt?referer=');">ARB_separate_shader_objects</a></h3>
<p>This is one another extension requested over several forums by the community. This feature has a longer history as it is actually based on the already existing and widely supported extension <a title="GL_EXT_separate_shader_objects" href="http://www.opengl.org/registry/specs/EXT/separate_shader_objects.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/EXT/separate_shader_objects.txt?referer=');">GL_EXT_separate_shader_objects</a> by NVIDIA. For those who are already familiar with the predecessor of this extension won&#8217;t really find too much new stuff reading the specification of the ARB version of the extension, however it is still a must to read for them as well as even though there aren&#8217;t too much semantic differences between the functionality of the two, the usage of them still differs quite a lot as the ARB version solved the design issues of its predecessor by introducing a new type of GL object that I will talk about just in a moment.</p>
<p>In a nutshell, this extension provides a way to create program objects using any variation of shaders and bind them together to the current rendering context. Previously there was no way to bind multiple program objects to the context as the program object was designed to be a container for all the shaders forming the rendering pipeline of the context. This was a design decision during the development of GLSL that, before this extension, made the connection between the varyings of subsequent shader stages using a name based binding. As name information is available for shaders latest in the link stage, shaders were tightly coupled meaning that a change in any shader stage code required the relinking of the complete program object.</p>
<p>This proved to be very unpleasant for OpenGL developers as usually every rendering engine has its own set of vertex and fragment shaders (maybe accompanied with other shader types) that are used in various combinations. As an example, let&#8217;s take two vertex shaders: a simple MVP matrix based transformation shader and a more complex one that also supports skeletal animation. Also let&#8217;s take two fragment shaders: one for diffuse material and one for reflective material. We can have several types of objects: static with diffuse material, static with reflective material, animated with diffuse material and animated with reflective material.</p>
<p>In traditional GLSL the vertex and fragment shaders are bound together at link time rather than at the time they are bound to the context, like it was in case of legacy shaders (<a title="GL_ARB_vertex_program" href="http://www.opengl.org/registry/specs/ARB/vertex_program.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/vertex_program.txt?referer=');">GL_ARB_vertex_program</a>, <a title="GL_ARB_fragment_program" href="http://www.opengl.org/registry/specs/ARB/fragment_program.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/fragment_program.txt?referer=');">GL_ARB_fragment_program</a> and others). This means that in order to be able to use any of the combinations of vertex and fragment shaders (and maybe some geometry and tesselation shaders as well) we end up with two possible solutions, both having their severe drawbacks:</p>
<p><strong><em>Link every combination of the shader objects</em></strong></p>
<p>While this sounds as a viable solution and is still used by most of the developers, it has several problems. First of all, it wastes resources as we now have several copies of the same piece of code and the number of combinations can be pretty high, especially if not just vertex and fragment shaders are in use. While this is already quite a reasonable issue with the solution, the biggest problem arises for the application developer when he or she has to maintain an individual set of uniform locations as well as binding points for vertex attributes, draw buffers and possibly transform feedback buffers. While the <a title="GL_ARB_explicit_attrib_location" href="http://www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/explicit_attrib_location.txt?referer=');">GL_ARB_explicit_attrib_location</a> extension already eliminates the need for maintaining binding points for vertex attributes, this solution is still simply unacceptable.</p>
<p><strong><em>Link the program objects on an on-demand basis</em></strong></p>
<p>In case of this alternative we are said to link the shader objects only when they are actually needed. While this solution eliminates the need for a possibly huge number of program objects, it introduces a reasonable run-time performance hit due to the additional relink process needed. Additionally, this solution proves to be more inferior even compared to the previous one as the uniform locations are determined at link time so it makes no less headache to the application developer.</p>
<p>This is the rationale behind this extension and why it is included into the core specification. The extension relaxes the strict tightly coupled behavior of the GLSL and adopts a mix-and-match shader stage model allowing multiple different program objects to be bound at once each to an individual set of rendering pipeline stage independently of other stage bindings.</p>
<p>Due to the fact that from now program objects are not the top most containers for the code used currently by the rendering pipeline, the ARB decided to introduce a new container object called a &#8220;program pipeline object&#8221; that can contain a set of program objects bound to their very own set of shader stages. This is the main difference between the EXT and the ARB version of the extension. I think it was a good decision to introduce this new type of object and the associated semantics as I always thought that the EXT version of the extension doesn&#8217;t have a really good design as I&#8217;ve seen it kind of a hack to relax the limitations of GLSL. The program pipeline object idea is definitely superior and I hope that the GLSL does not have too much of such annoying design issues hidden within.</p>
<h3><a title="GL_ARB_shader_precision" href="http://www.opengl.org/registry/specs/ARB/shader_precision.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_precision.txt?referer=');">ARB_shader_precision</a></h3>
<p>This extension is much more a clarification to the existing specification rather than a new feature. It restricts more clearly the precision requirements of implementations of GLSL. According to the specification, the extension is meant to more precisely define the precision of arithmetic operations (addition, multiplication, etc.), transcendentals (log, exp, pow, etc.), when <a title="NaN - Wikipedia" href="http://en.wikipedia.org/wiki/NaN" target="_blank" onclick="pageTracker._trackPageview('/outgoing/en.wikipedia.org/wiki/NaN?referer=');">NaN</a>s (not-a-number) and INFs (infinites) will be accepted and generated and denorm flushing behavior. The precision of the rest of the operations, including trigonometric operations are not addressed by the extension. For further details, please refer to the extension specification.</p>
<h3><a title="GL_ARB_vertex_attrib_64bit" href="http://www.opengl.org/registry/specs/ARB/vertex_attrib_64bit.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/vertex_attrib_64bit.txt?referer=');">ARB_vertex_attrib_64bit</a></h3>
<p>This extension trivially introduces 64-bit floating-point types into the list of supported vertex attribute component types. Nominally OpenGL did support this already from the very early stages of its history, however in practice only the latest generation of hardware does really accept vertex attributes in double precision floating-point type. While OpenGL 4 already introduced support for 64-bit floating-point values in GLSL and most of the shaders&#8217; environment, vertex attributes gained the 64-bit precision only with this new extension.</p>
<p>This new feature makes it possible to use high precision for positioning data and other attributes of our geometries. While this sounds pretty awesome and it is actually, still for game developers and other real-time graphics users this shouldn&#8217;t mean that they should quickly switch to the new precision only in such cases when the precision requirements of the application really need it as using 64-bit floating-point values for vertex attributes does not just double the memory consumption but also involves a serious hit on performance due to bandwidth limitations and vertex attributes of this type may count double against the implementation-dependent limit on the number of vertex shader attribute vectors.</p>
<h3><a title="GL_ARB_viewport_array" href="http://www.opengl.org/registry/specs/ARB/viewport_array.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/viewport_array.txt?referer=');">ARB_viewport_array</a></h3>
<p>Previously, the configuration of the viewport, aka the transformation that generates the screen space coordinates based on the incoming view space coordinates of the vertices, was a global configuration that had effect on all draw commands meaning that in order to draw a primitive into multiple viewports the OpenGL viewport had to be changed between several draw calls. While previously this limitation wasn&#8217;t really an issue, due to the introduction of geometry shaders the possibility to amplify geometry and produce multiple output primitives for each primitive input justifies the need of several separately configurable viewports. Why? Because even though one was able to render the output primitives into separate render targets, they still shared the same global viewport.</p>
<p>This extension enhances OpenGL by providing a mechanism to specify multiple viewports and a new ability for the geometry shader being able to select the used viewport on a per-primitive basis. This does not just mean that separate viewports can be used for separate render targets but also enables to use multiple viewports to render to the same render target.</p>
<p>Additionally, the introduction of a viewport array means that we&#8217;re gonna have separate scissor rectangle for each viewport in the array as well. This can come handy for deferred shading based renderers that often use the scissor rectangle to limit the number of pixels to be accessed in case of rendering the effect of a light source. Having multiple scissors means that we have to change state less often, thus batching is much less an issue even in case of heavy scissor rectangle usage.</p>
<p>Finally, the new viewport specification commands accept floating point values thus providing additional flexibility to the application developer to define their very own pixel center conventions.</p>
<p>I&#8217;m pretty unsure whether this feature depends on any Shader Model 5.0 hardware, maybe others are more aware of this. Anyway, I wouldn&#8217;t be surprised if this extension will be supported by a much larger range of graphics cards than just pure SM5 GPUs. Actually this is true for many other extensions introduced by OpenGL 4.1 but let&#8217;s not guess but wait for the upcoming drivers to see whether I&#8217;m right or wrong.</p>
<h2>Some other interesting extensions</h2>
<p>So far I presented the new features of the latest revision of the OpenGL specification. While this was the main topic of this article, at about the same time the specification was published, a lot of other ARB extensions just appeared in the <a title="OpenGL Extension Registry" href="http://www.opengl.org/registry/" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/?referer=');">registry</a>. While these extensions are not yet included into core and I cannot know whether they will be ever included, I would like to talk about some of them as it made me get to an interesting conclusion.</p>
<h3><a title="GL_ARB_shader_stencil_export" href="http://www.opengl.org/registry/specs/ARB/shader_stencil_export.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/shader_stencil_export.txt?referer=');">ARB_shader_stencil_export</a></h3>
<p>The stencil test is a powerful mechanism of OpenGL to selectively discard fragments based on the content of the stencil buffer that is used in a wide variety of rendering techniques including shadow volumes and deferred shading. However, the whole configuration of the stencil test and stencil operations is completely fixed function that is limited to operations such as incrementing, decrementing the existing value, or replacing the existing value in the stencil buffer with a fixed reference value.</p>
<p>This extension provides some programmability to the fixed function stencil operations by enabling the fragment shader to output a stencil reference value on a per-fragment basis. When stencil testing is enabled, this allows the test to be performed against the value generated in the shader. Also, when the stencil operation is set to GL_REPLACE, this allows a value generated in the shader to be written to the stencil buffer directly.</p>
<p>This opens up a lot of possibilities, however, I need to think much more about it as the best use cases of this feature are pretty much not basic ones. Obviously, by using the stencil reference value export inside a fragment shader disables early stencil test in the same style as exporting an new depth value from within a fragment shader disables early depth test.</p>
<h3><a title="GL_ARB_debug_output" href="http://www.opengl.org/registry/specs/ARB/debug_output.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/ARB/debug_output.txt?referer=');">ARB_debug_output</a></h3>
<p>This extension allows OpenGL to notify the application when various events occur that can come handy during application development and debugging. These events include errors, usage of deprecated functionalities, using configuration that results in undefined behavior, portability or performance issues. The application is notified about these events using a callback function that is defined by passing a function pointer to the appropriate OpenGL command.</p>
<p>While this extension provides a callback mechanism only for debugging purposes, the most revolutionary thing by having such an ARB extension is that this is the first official appearance of a feature that supports callbacks to the application code. Most probably not I&#8217;m the only person who would like to see a lot of other callbacks in the future included in the OpenGL API as we can benefit from it by getting notification about e.g. the completion of various asynchronous commands issued previously. This does not just provide a lot of flexibility but may also help in optimizing the rendering code based on the additional information previously available only if we use polling.</p>
<h3>Why these extensions are so interesting?</h3>
<p>The two extensions presented above already great value on their own but this isn&#8217;t why I mentioned them. The reason why I found these extensions so interesting as they are both obviously based on some vendor specific extensions released in the recent past by AMD, namely <a title="GL_AMD_shader_stencil_export" href="http://www.opengl.org/registry/specs/AMD/shader_stencil_export.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/shader_stencil_export.txt?referer=');">GL_AMD_shader_stencil_export</a> and <a title="GL_AMD_debug_output" href="http://www.opengl.org/registry/specs/AMD/debug_output.txt" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.opengl.org/registry/specs/AMD/debug_output.txt?referer=');">GL_AMD_debug_output</a>. This conspicuously reveals that AMD has serious plans with their OpenGL support and this is something that a lot of those crazy folks waited for, who develop OpenGL stuff using ATI cards like me.</p>
<p>I think this also means that the NVIDIA monopoly in the ARB is over and this results in concurency and competition from what OpenGL and its community will definitely benefit in the long run.</p>
<h2>Conclusion</h2>
<p>The article ran out of control again, like the one I wrote about the previous release of the specification. Again, hope there are at least a few of you who kept up reading and finally got to this last chapter of the article. We can again quote the always recurring question of the community:</p>
<blockquote><p>Where is direct state access?</p>
</blockquote>
<p>Well, it is still not here, however, finally AMD has finished implementing it as well and published it finally. They have been working on it for quite some time but it became officially public only with Catalyst 10.7. Haven&#8217;t used it so far so maybe plenty of hidden bugs are still in it but at least they have it. This is one another thing that strengthens my prognostication that AMD committed itself for support OpenGL as previously they barely added support for any other extensions beside core features.</p>
<p>Back to the topic of the OpenGL 4.1 specification, while it is not as revolutionary as we got used to after reading the previous update, OpenGL is still on track and this is thanks to the Khronos Group and obviously to the great community. If OpenGL will get its iterative evolution in this pace like we&#8217;ve seen in the last two years, Microsoft will have a difficult time to keep up.</p>
<p>Thanks for reading this not-so-short article!</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/08/an-introduction-to-opengl-4-1/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>One more degree of freedom for C++</title>
		<link>http://rastergrid.com/blog/2010/02/one-more-degree-of-freedom-for-c/</link>
		<comments>http://rastergrid.com/blog/2010/02/one-more-degree-of-freedom-for-c/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 14:38:42 +0000</pubDate>
		<dc:creator>Daniel Rákos</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[delegation]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[event handling]]></category>
		<category><![CDATA[message]]></category>
		<category><![CDATA[signal]]></category>
		<category><![CDATA[signals and slots]]></category>

		<guid isPermaLink="false">http://rastergrid.com/blog/?p=176</guid>
		<description><![CDATA[

Those who worked enough with C or other procedure oriented languages know how much flexibility callbacks provide. The simplest example is the qsort function of the C standard library. It is also not unintentional that many libraries, windowing system APIs and operating system APIs also highly rely on callbacks to pass a particular task over [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frastergrid.com%252Fblog%252F2010%252F02%252Fone-more-degree-of-freedom-for-c%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fdrfdzt%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22One%20more%20degree%20of%20freedom%20for%20C%2B%2B%22%20%7D);"></div>
<p>Those who worked enough with C or other procedure oriented languages know how much flexibility callbacks provide. The simplest example is the qsort function of the C standard library. It is also not unintentional that many libraries, windowing system APIs and operating system APIs also highly rely on callbacks to pass a particular task over to another program module and it is one of the fundamental tools needed to implement an event-driven application. At the same time, object oriented languages does not directly support the concept of callbacks as they don&#8217;t really fit into the paradigms used by these languages. Fortunately, even if not as a language feature, all object oriented languages support a similar facility like callbacks in the form of delegates.</p>
<p><span id="more-176"></span>Delegation as a design pattern is used to describe the situation when one object passes on the implementation of a particular task to another object. This clearly reflects the purpose of callbacks used in procedure oriented languages. Many languages does natively support some form of delegation, some of the well known ones are C# and Delphi.</p>
<h2>Callbacks</h2>
<p>As mentioned before, the facility present in procedure oriented languages that enables the delegation of functionalities to other modules is done with callbacks. These callbacks are specified by passing function pointers to some registration functions provided by the library. Here is a very simple C example:</p>
<pre class="brush: c">/* server header */
void registerFooCallback(int (*fooCB)(int, float));
int doFoo(int a, float b);

/* client code */
int myFooCallback(int a, float b) {
    /* ... do something ... */
}

int main() {
    registerFooCallback(myFooCallback);
    cout &lt;&lt; doFoo(5, 3.2f);
    return 0;
}</pre>
<p>Here we can see how easily callbacks provide injection of user code for handling events happened in the server.</p>
<h2>Delegation as a design pattern</h2>
<p>The simplest way to create object oriented callbacks is by applying the design pattern of delegation. If we would like to construct the C++ equivalent of the example above using the mentioned pattern, we end up with something like the following:</p>
<pre class="brush: cpp">/* server header */
class IFooCallback {
public:
    virtual int operator() (int a, float b) = 0;
};

class Foo {
private:
    IFooCallback* _fooCB;
public:
    void registerCallback(IFooCallback* fooCB);
    int doFoo(int a, float b);
};

/* client code */
class MyFooCallback: public IFooCallback {
    int operator() (int a, float b) {
        /* ... do something ... */
    }
};

int main() {
    Foo foo;
    MyFooCallback fooCB;
    foo.registerCallback(fooCB);
    cout &lt;&lt; foo.doFoo(5, 3.2f);
    return 0;
}</pre>
<p>As you can see, it is quite straightforward to provide an object oriented alternative to callbacks. However, there is a very significant drawback when using the technique above, namely the type intrusion inherently coming from this definition of a callback. The client code needs to explicitly inherit it&#8217;s own code from a type defined in the server. This results in tight coupling and is likely to carry other disadvantages inside regarding to maintainability and migration issues.</p>
<h2>Delegate methods</h2>
<p>In our previous attempt to provide an easy to use C++ alternative for callbacks with OOP in mind we tried to replace function pointers with a pure virtual base class that acts like an interface definition for our callback. However, it somewhat violates the original goals of delegates which by definition should be some form of run-time inheritance (this varies from definition to definition, still, this is the one that I&#8217;m referring to in this article). We soon figure out that the most convenient way would be to be able to assign member functions of any class as a callback. Obviously, the parameters and return type should still match as previously to provide type safety, but we would like to remove any additional dependencies between the client and the server.</p>
<p>While C++ does have the term of pointers to member functions there is no easy and standard way to implement callbacks using them. Or is there? First of all, there is no particular problem with class static member functions as they are much like C functions, however, limiting delegates to static methods heavily affects the freedom of the developer. The problem with object member functions and especially with virtual member functions is that they have the implicit parameter <strong>this</strong> that enables them to access the object they correspond to.</p>
<p>The popular Boost library provides mechanisms that enables the use of object member functions as separate entities by using the <strong>bind</strong> functor adaptor which became part of the language standard as part of <a title="ISO/IEC TR 19768:2007" href="http://www.iso.org/iso/catalogue_detail.htm?csnumber=43289" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.iso.org/iso/catalogue_detail.htm?csnumber=43289&amp;referer=');">Technical Report 1</a>. This extension makes it possible to use member functions as delegates in a way that does not involve any type intrusion side effects.</p>
<p>Unfortunately, these facilities involve a noticeable performance hit when the callback is invoked compared to simple method invocations. Also, using functor adaptors for implementing delegates is not the most straightforward and makes the code quite ugly compared to an ideal situation when delegates are part of the language itself. Of course, this is only my opinion, others who used these libraries more often may have a different vision about the topic.</p>
<p>Anyway, as for me performance is always a concern, I started to look around for alternatives. It surprised me that I&#8217;ve found even two of them very soon:</p>
<ul>
<li><a title="Fastest Possible C++ Delegates" href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.codeproject.com/KB/cpp/FastDelegate.aspx?referer=');">Fastest Possible C++ Delegates</a> by Don Clugston &#8211; This is a library that provides delegates that are as fast as simple virtual method invocations. The implementation strongly relies on the behavior of different compilers, yet is very portable, at least as far as I can tell.</li>
<li><a title="The Impossibly Fast C++ Delegates" href="http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx?referer=');">The Impossibly Fast C++ Delegates</a> by Sergey Ryazanov &#8211; This library was introduced as an alternative to the previous one that strictly relies only on standard features of the languages. Surprisingly, this later is less supported by different compiler implementations and it is also somewhat slower than the previous one.</li>
</ul>
<p>Personally, I go with the first one as for me performance and portability is more important than conformance with the standard. And, of course, it is not that hard to change the back-end for the delegate support at some time if I change my mind. Finally, lets see how our foo callback looks like when using the fast delegates of Don Clugston:</p>
<pre class="brush: cpp">/* server header */
class Foo {
private:
    FastDelegate2&lt;int, float, int&gt; _fooCB;
public:
    void registerCallback(FastDelegate2&lt;int, float, int&gt; fooCB);
    int doFoo(int a, float b);
};

/* client code */
class MyClass {
    virtual int handleFoo(int a, float b) {
        /* ... do something ... */
    }
};

int main() {
    Foo foo;
    MyClass myObj;
    foo.registerCallback( MakeDelegate(&amp;myObj, &amp;MyClass::handleFoo) );
    cout &lt;&lt; foo.doFoo(5, 3.2f);
    return 0;
}</pre>
<h2>Multicast delegates</h2>
<p>The delegates presented previously can only be bound to a single method, as usually delegates behave this way, although a single method can be bound by many delegates. The signals and slots model extends this to a many-to-many relationship. Thus a signal is actually just a delegate that can bind to multiple methods at once. Such a primitive is sometimes also referred to as a multicast delegate.</p>
<p>Multicast delegates come handy especially in case of user interface programming and other situations where the event based programming model is used. The basic foundation behind this programming model is the idea of &#8220;subscribe and notify&#8221;. That means there are <em>publishers</em> who will do some logic and sometimes publish <em>events</em>. When such an <em>event</em> is published, it is actually sent out to the <em>subscribers</em> who have subscribed to receive the specific event. At implementation level this is nothing more than having a multicast delegate in the <em>publisher</em> object and providing an interface that will be used by the <em>subscriber</em> objects to register one of their methods that has to be called in case a particular <em>event</em> occurs.</p>
<p>There are plenty of signals and slots libraries out there including but not limited to the Boost Signals library. However, again, if performance is a concern one must look around carefully to find the appropriate library suitable for a particular purpose. One such library that extends the fast delegates of Clugston with a signals and slots framework is that of <a title="Simpler UI Code With Signals and Slots" href="http://www.gallantgames.com/2009/12/13/simpler-ui-code-with-signals-and-slots" target="_blank" onclick="pageTracker._trackPageview('/outgoing/www.gallantgames.com/2009/12/13/simpler-ui-code-with-signals-and-slots?referer=');">Patrick Hogan</a>&#8217;s.</p>
<h2>Asynchronous delegates</h2>
<p>If we do one more step forward, we arrive to asynchronous delegates that can provide us a flexible yet efficient messaging system for multi-threaded applications. The only additional thing we have to implement a message queue on the callee side and optionally some form of synchronization if we would like to also make it possible for the asynchronous delegates to return data to the caller.</p>
<p>As this topic deserves a thorough discussion on its own, I would recap on the subject in a future article and try to provide a sample implementation using OpenMP as usual.</p>
<h2>Conclusion</h2>
<p>We&#8217;ve just touched the surface of what possible use case scenarios of delegates one can met during software development, still, we&#8217;ve seen how many advantages such a programming primitive can give to C++ developers no matter if they are implementing a very simple library of sorting algorithms like the qsort C standard library function or a robust, fully event-driven multi-threaded application. We&#8217;ve also seen that there exist several efficient implementations of such a framework for those performance fanatics like me.</p>
<p>It is a perfect example how easily one can extend C++ with another facility that is usually available only in the most modern managed languages. By the way, I would be interested in your opinion what do you like the most in other languages like Java and C#, and you are disappointed that C++ does not directly provide the same thing. Maybe there exists a C++ alternative for those facilities as well, just we have to look around to find them&#8230;</p>

]]></content:encoded>
			<wfw:commentRss>http://rastergrid.com/blog/2010/02/one-more-degree-of-freedom-for-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
