<?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>Coder-Studio &#187; C &amp; C++</title>
	<atom:link href="http://www.coder-studio.com/blog/category/c-cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 31 Mar 2010 00:00:53 +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>Tutoriel Boost Graph Library</title>
		<link>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/</link>
		<comments>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 01:06:58 +0000</pubDate>
		<dc:creator>Calvin1602</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[graphes]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=429</guid>
		<description><![CDATA[Boost, c'est le bien, et la BGL ne fait pas exception à la règle. BGL permet d'utiliser des algorithmes de graphes précodés en l'adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.
C'est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble [...]
Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable.]]></description>
			<content:encoded><![CDATA[<p>Boost, c&#8217;est le bien, et la BGL ne fait pas exception à la règle. BGL permet d&#8217;utiliser des algorithmes de graphes précodés en l&#8217;adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.<br />
C&#8217;est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble :<br />
<span id="more-429"></span></p>
<ul>
<li>Elle est très peu connexe. Par exemple, il y a un unique lien vers la table des matières.</li>
<li>Elle est peu explicite. Par exemple, dans l&#8217;interface de l&#8217;algorithme de dijkstra, on peut trouver un bgl_named_parameters. Il faut se lever de bonne heure pour trouver ce que c&#8217;est.</li>
<li>Les exemples sont rares et peu explicites. Le seul exemple de l&#8217;algorithme A* est peu commenté (et encore moins aux parties les plus dures), démontre deux autres features qui n&#8217;ont rien à voir, utilise l&#8217;interface obsolète et non recommandée de la lib, et complique le tout avec une autre couche de templates totalement inutile pour un tuto qui se veut simple.</li>
</ul>
<p>Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable. Tous les membres du namespace boost seront préfixés par boost:: afin de savoir qu&#8217;est-ce qui est à nous et qu&#8217;est-ce qui est à Boost.</p>
<p>Il est basé sur le cas suivant : on a un graphe de waypoints, et on veut utiliser l&#8217;algorithme A* (qui utilise une bonne partie des concepts importants de la lib). Dans un premier temps, dans un souci de simplicité, on va utiliser une heuristique par défaut, qui rend toujours zéro. On verra par la suite comment l&#8217;adapter.</p>
<p>On va avoir besoin de deux headers boost:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code1'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4291"><td class="code" id="p429code1"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;boost/graph/adjacency_list.hpp&gt;</span>
<span style="color: #339900;">#include &lt;boost/graph/astar_search.hpp&gt;</span></pre></td></tr></table></div>

<p>On va maintenant définir les structures nécessaires à définir notre graphe :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code2'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4292"><td class="code" id="p429code2"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Un waypoint</span>
<span style="color: #0000ff;">struct</span> WayPoint<span style="color: #008000;">&#123;</span>
    Vector3f pos<span style="color: #008080;">;</span>
    <span style="color: #666666;">// et éventuellement d'autres informations (crouch, hide, camp, ...)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Une liaison entre deux waypoints</span>
<span style="color: #0000ff;">struct</span> WayPointConnection<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">float</span> dist<span style="color: #008080;">;</span>
    <span style="color: #666666;">// idem</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va maintenant déclarer le type de notre graphe. On va utiliser une adjacency_list, qui est un peu un graphe à tout faire. Ce n&#8217;est pas le plus optimisé dans tous les cas, mais il est très versatile et convient très bien ici.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code3'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4293"><td class="code" id="p429code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">adjacency_list</span><span style="color: #000080;">&lt;</span>  <span style="color: #666666;">// adjacency_list est un template qui dépend de :</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">listS</span>,               <span style="color: #666666;">//  le conteneur utilisé pour les arcs partant d'un sommet. Ici, std::list.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">vecS</span>,                <span style="color: #666666;">//  le conteneur utilisé pour contenir tous les sommets du graphe. Ici, std::vector.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">undirectedS</span>,         <span style="color: #666666;">//  le type des arcs. Pourrait être boost::directedS.</span>
    WayPoint,                   <span style="color: #666666;">//  le type qui décrit un sommet.</span>
    WayPointConnection          <span style="color: #666666;">//  le type qui décrit un arc.</span>
<span style="color: #000080;">&gt;</span> WayPointGraph<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Les deux premiers paramètres influent grandement sur l&#8217;organisation mémoire et les performances de graphe. Selon les applications, une liste, un vecteur, un set, une map, &#8230; sera plus approprié. Pour plus d&#8217;information, voir <a href="http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/using_adjacency_list.html#sec:choosing-graph-type">la doc</a>.</p>
<p>On déclare aussi des raccourcis pour les IDs de sommets et d&#8217;arcs (en fait, ce sont des unsigned int)</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code4'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4294"><td class="code" id="p429code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">vertex_descriptor</span> WayPointID<span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">edge_descriptor</span>   WayPointConnectionID<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va pouvoir instancier notre graphe.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code5'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4295"><td class="code" id="p429code5"><pre class="cpp" style="font-family:monospace;">WayPointGraph graphe<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On commence par rajouter tous les sommets :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code6'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4296"><td class="code" id="p429code6"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets S<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    WayPointID wpID <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_vertex</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// wp est l'indice d'un nouveau sommet qui a été ajouté dans graphe</span>
    graphe<span style="color: #008000;">&#91;</span>wpID<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span> <span style="color: #000080;">=</span> la position du sommet S    <span style="color: #666666;">// graphe[ un WayPointID ] est un WayPoint. On peut donc régler sa position de cette manière.</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Maintenant, on peut les relier par des arcs. Là, c&#8217;est à vous de savoir où vont les arcs, boost ne va pas le deviner tout seul&#8230;</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code7'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4297"><td class="code" id="p429code7"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// petit changement de notation, dans boost un arc est souvent décrit entre deux sommets u et v.</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous les voisins V de U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// C'est à vous de savoir quels sont les voisins de U.</span>
&nbsp;
        WayPointID u <span style="color: #000080;">=</span> indice de U<span style="color: #008080;">;</span> <span style="color: #666666;">// soit c'est le int du for(), soit il faut y accéder via un autre vector. Cf les notes plus bas.</span>
        WayPointID v <span style="color: #000080;">=</span> indice de V<span style="color: #008080;">;</span>
&nbsp;
        WayPointConnectionID edge<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">bool</span> ok<span style="color: #008080;">;</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">tie</span><span style="color: #008000;">&#40;</span>edge, ok<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_edge</span><span style="color: #008000;">&#40;</span>u,v, graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// boost::add_edge renvoie une std::pai&gt;WayPointConnectionID,bool&gt;. C'est compliqué à écrire, alors on laisse boost::tie le faire pour nous.</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>ok<span style="color: #008000;">&#41;</span>  <span style="color: #666666;">// Si le graphe a bel et bien été ajouté ( pas de doublon, par exemple, sauf si spécifié dans le typedef de WayPointGraph )</span>
        graphe<span style="color: #008000;">&#91;</span>edge<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">dist</span> <span style="color: #000080;">=</span> Distance<span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span>, graphe<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Longueur d'un arc = distance euclidienne entre les deux sommets u et v.</span>
&nbsp;
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Plusieurs choses sont à remarquer :</p>
<ul>
<li>Personnellement, j&#8217;ai utilisé le fait que WayPointID est en fait un int et que dans mon double for(), j&#8217;utilise un int pour accéder au waypoint. C&#8217;est pas très propre, mais ça évite l&#8217;utilisation d&#8217;un vector en plus.</li>
<li>graphe[edge] ( edge étant un WayPointConnectionID ) est un WayPointConnection, alors que graphe[u] (u étant un WaypointID) est un WayPoint. On peut donc accéder directement à leurs membres.</li>
<li>Cette dernière remarque est très importante. Cette syntaxe est très appréciable, elle évite d&#8217;utiliser les incompréhensibles boost::property_map, elle oblige seulement à avoir un compilateur récent. GCC et Visual s&#8217;en sortent très bien.</li>
</ul>
<p>Pour information, mon code à moi ressemble à ça :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code8'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4298"><td class="code" id="p429code8"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>indices.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">/</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    ConnectiviteTriangle connectivity<span style="color: #008080;">;</span>
    fillconnectivityinfo<span style="color: #008000;">&#40;</span>i, connectivity, indices<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> c<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> c<span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> c<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        TriangleDescriptor u <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span>
        TriangleDescriptor v <span style="color: #000080;">=</span> connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>La syntaxe est moyennement cool, mais j&#8217;espère que ça vous aidera à mieux comprendre.</p>
<p>Ok, donc maintenant notre graphe a des sommets et des arcs. On va pouvoir faire du pathfinding !</p>
<p>Pour ça, on va avoir besoin de quelques structures :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code9'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4299"><td class="code" id="p429code9"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Une instance de cette structure sera lancée en exception quand on aura trouvé un chemin</span>
<span style="color: #0000ff;">struct</span> found_goal <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Le visiteur, dont le but est de définir une fonction examine_vertex qui dit si on est arrivé au but.</span>
<span style="color: #666666;">// Le but est spécifié via le constructeur.</span>
<span style="color: #0000ff;">class</span> astar_goal_visitor <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">default_astar_visitor</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    astar_goal_visitor<span style="color: #008000;">&#40;</span>WayPointID goal<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">void</span> examine_vertex<span style="color: #008000;">&#40;</span>WayPointID u, <span style="color: #0000ff;">const</span> Graph <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> g<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Le const est important.</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>u <span style="color: #000080;">==</span> m_goal<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">throw</span> found_goal<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// On sort en lancant une exception. C'est moche mais c'est comme ça.</span>
        <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    WayPointID m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Il faut maintenant trouver notre point de départ et notre point d&#8217;arrivée. C&#8217;est votre problème, mais il faut arriver à quelque chose du style :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code10'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42910"><td class="code" id="p429code10"><pre class="cpp" style="font-family:monospace;">TriangleDescriptor goal <span style="color: #000080;">=</span> ...
<span style="color: #007788;">TriangleDescriptor</span> start <span style="color: #000080;">=</span> ...</pre></td></tr></table></div>

<p>Ok, on y va :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code11'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42911"><td class="code" id="p429code11"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Deux vecteurs qui vont servir à sauvegarder le résultat de la recherche</span>
vector<span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> p<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les prédécesseurs</span>
vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span>      d<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les distances</span>
&nbsp;
<span style="color: #0000ff;">try</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Encore une fois, la découverte d'un chemin est signalée par une exception, donc il faut un try/catch.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_search</span>
    <span style="color: #008000;">&#40;</span>
        graphe, <span style="color: #666666;">// notre graphe</span>
        start,  <span style="color: #666666;">// notre point de départ</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span><span style="color: #000080;">&lt;</span>NavMeshGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #666666;">// Une heuristique bidon qui renvoie toujours 0</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">predecessor_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">distance_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>d<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">visitor</span><span style="color: #008000;">&#40;</span>astar_goal_visitor<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">weight_map</span><span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">get</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>WayPointConnection<span style="color: #008080;">::</span><span style="color: #007788;">dist</span>, graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #666666;">// Voir plus bas</span>
    <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>found_goal fg<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// On a trouvé un chemin</span>
    <span style="color: #666666;">// On suit le chemin trouvé dans le sens inverse</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> shortest_path<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>WayPointID v <span style="color: #000080;">=</span> goal<span style="color: #008080;">;;</span> v <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        shortest_path.<span style="color: #007788;">push_front</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> v<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">// et on l'affiche.</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> spi <span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">++</span>spi<span style="color: #008080;">;</span> spi <span style="color: #000040;">!</span><span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>spi<span style="color: #008000;">&#41;</span>
        Log<span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>spi<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    Log<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Total travel time: &quot;</span> , d<span style="color: #008000;">&#91;</span>goal<span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Remarque sur la ligne bizarre:</p>
<ul>
- Ce ne sont pas des virgules, ce sont des points ! Il s&#8217;agit d&#8217;un seul objet auquel on rajoute plein de propriétés. Cette syntaxe est par exemple utilisée dans la création d&#8217;interfaces graphiques : monmenu.addoption(&laquo;&nbsp;option1&#8243;).addoption(&laquo;&nbsp;option2&#8243;) etc<br />
- A* a besoin de ces quatre propriétés : une map de prédécesseurs, une map de distances, une map de poids, et un visiteur.<br />
- La map de poids est intrisèque au graphe : elle est stockée dans le champ dist des arcs. Mais Boost ne peut pas deviner tout seul que c&#8217;est cette variable qu&#8217;il faut lire, donc on le lui dit avec boost::get(&amp;WayPointConnection::dist, graphe)</p>
<li>Le visiteur est initialisé avec le goal pour pouvoir lancer son exception si il y a réussite.</li>
</ul>
<p>Vous avez économisé 4 heures de prise de tête avec la doc de BGL, autant d&#8217;implémentation de l&#8217;A* si vous l&#8217;aviez codé vous même, et autant de débug que vous n&#8217;aurez jamais à faire : un des grands intérêts des templates, c&#8217;est que comme en OCaml, quand ça compile, ça marche (souvent) ^^.</p>
<p>Voyons maintenant comment améliorer un peu notre heuristique : pour l&#8217;instant, on n&#8217;a fait qu&#8217;un parcours brutal de l&#8217;arbre, ça ne valait pas trop le coup.<br />
Cela va bien sûr passer par une nouvelle structure :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code12'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42912"><td class="code" id="p429code12"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> distance_heuristic <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span> <span style="color: #000080;">&lt;</span>WayPointGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// De la même manière que tout à l'heure, on passe les données dont il aura besoin dans son foncteur à la construction.</span>
    distance_heuristic<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> l, WayPointID goal<span style="color: #008000;">&#41;</span>
    <span style="color: #008080;">:</span> m_graph<span style="color: #008000;">&#40;</span>l<span style="color: #008000;">&#41;</span>, m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">float</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>WayPointID u<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> U <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> V <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>m_goal<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dx <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dy <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">sqrt</span><span style="color: #008000;">&#40;</span>dx <span style="color: #000040;">*</span> dx <span style="color: #000040;">+</span> dy <span style="color: #000040;">*</span> dy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> m_graph<span style="color: #008080;">;</span>
    TriangleDescriptor m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>m_graph peut être remplacé ( en changeant le constructeur et l&#8217;opérateur ) par n&#8217;importe quoi qui vous permette d&#8217;obtenir la position d&#8217;un vertex à partir de son identifiant. Cela peut être comme ici le graphe lui-même, mais aussi les données à partir duquel il a été construit, etc.</p>
<p>Il suffit maintenant de remplacer boost::astar_heuristic<WayPointGraph, float>() par distance_heuristic(graphe, goal) dans l&#8217;appel au A*.</p>
<p>Oh, et au fait : les waypoints ça pue, utilisez des navmeshes.</p>
<p><a href="http://www.coder-studio.com/forum2/viewtopic.php?id=1392">Discussion sur le forum</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Préprocesseur et énumérations : la suite.</title>
		<link>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/</link>
		<comments>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 20:34:09 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=393</guid>
		<description><![CDATA[Cet article fait suite à mon premier article intitulé &#171;&#160;Faire un peu joujou avec le préprocesseur&#160;&#187;
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).
Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création
d&#8217;un opérateur &#171;&#160;]]></description>
			<content:encoded><![CDATA[<p>Cet article fait suite à mon premier article intitulé &laquo;&nbsp;Faire un peu joujou avec le préprocesseur&nbsp;&raquo;<br />
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).</p>
<p>Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création<br />
d&#8217;un opérateur &laquo;&nbsp;<<" pour iostream, capable d'afficher le nom d'une énumération.</p>
<p><span id="more-393"></span></p>
<p>Voici le code :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code24'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39324"><td class="code" id="p393code24"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_N(nb_vals, __VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(nb_vals, enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code25'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39325"><td class="code" id="p393code25"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Le plus gros problème de ce système est le fait que l&#8217;on soit obligés de donner le nombre de valeurs de l&#8217;énumération<br />
lors de l&#8217;utilisation de la macro ENUMERATE.</p>
<p>Ce qui nous oblige à spécifier ce numéro, c&#8217;est la nécessiter de &laquo;&nbsp;choisir&nbsp;&raquo; la bonne macro parmi ENUM_CASE_1, ENUM_CASE_2, &#8230;, ENUM_CASE_10.</p>
<p>Se passer de ce nombre, c&#8217;est effectuer l&#8217; &laquo;&nbsp;appel récursif&nbsp;&raquo; jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument à traiter dans la<br />
&laquo;&nbsp;liste&nbsp;&raquo; __VA_ARGS__.</p>
<p>Que se passe-t-il si l&#8217;on supprime ce nombre et que l&#8217;on remplace l&#8217;appel à ENUM_CASE_N par la version qui gère le plus d&#8217;arguments<br />
(ici ENUM_CASE_10, donc) ?</p>
<p>Version remaniée :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code26'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39326"><td class="code" id="p393code26"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_10(__VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code27'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39327"><td class="code" id="p393code27"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// test.cpp</span>
&nbsp;
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Après un appel au préprocesseur par &laquo;&nbsp;cpp test.cpp&nbsp;&raquo;, voici ce qu&#8217;il nous affiche (remis en forme pour être lisible et<br />
en enlevant les lignes commençant par un #, sans importance) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code28'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39328"><td class="code" id="p393code28"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">enum</span> MonEnumeration <span style="color: #008000;">&#123;</span> E_VAL_1, E_VAL_2, E_VAL_3 <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_3<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_3&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Vous voyez le problème : on a des &laquo;&nbsp;case :&nbsp;&raquo; à partir du stade où il n&#8217;y a plus d&#8217;argument. Il faut donc remplacer<br />
chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; (correspondant à ce que génère ENUM_CASE_1) par quelque chose qui puisse faire un test d&#8217;égalité<br />
entre &laquo;&nbsp;e&nbsp;&raquo; et &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc, mais qui puisse aussi compiler et ne rien faire lorsqu&#8217;en lieu et place<br />
de &laquo;&nbsp;E_VAL_XXX&nbsp;&raquo;, il n&#8217;y a rien.</p>
<p>Là, on pense à la surcharge de fonction ! En effet, si l&#8217;on a une fonction surchargée ainsi :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code29'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39329"><td class="code" id="p393code29"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blabla</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blublu</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>on peut obtenir un comportement différent selon que l&#8217;on passe ou pas quelque chose en argument à la fonction !<br />
Il suffirait de remplacer chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; par un test d&#8217;égalité qui aurait cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code30'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39330"><td class="code" id="p393code30"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #008000;">&#40;</span>e, E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>et le tour est joué !</p>
<p>Mais attendez, vous ne voyez pas un problème ? Si, si : contrairement à la fonction f() de l&#8217;exemple, ce &laquo;&nbsp;TestEgalite&nbsp;&raquo;<br />
a 2 arguments. Si l&#8217;on remplace &laquo;&nbsp;E_VAL_1&#8243; par du vide, on obtient un &laquo;&nbsp;if(TestEgalite(e, )) {blabla;}&nbsp;&raquo; : ça ne marche pas !</p>
<p>Le problème reste donc entier&#8230;<br />
Oui, pour ceux qui se demandent, cette partie de l&#8217;article n&#8217;apporte rien à la solution, c&#8217;est juste la démarche que j&#8217;ai<br />
eue : vous pouvez vous dire que ça ne sert à rien, je ne vous le reprocherai pas, mais maintenant c&#8217;est trop tard, vous<br />
l&#8217;avez lu :p</p>
<p>On pourrait se poser le problème ainsi : comment, à partir d&#8217;une fonction à 2 arguments, en faire 2 fonctions à 1 argument ?<br />
En effet, si l&#8217;on arrive à en faire 2 fonctions à 1 argument, alors le problème serait réglé <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Si je ne m&#8217;abuse, il<br />
s&#8217;agit de la &laquo;&nbsp;curryfication&nbsp;&raquo;, que l&#8217;on trouve en programmation fonctionnelle et en lambda-calcul <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Peut-être est-ce possible, je n&#8217;ai pas exploré cette possibilité. Il ne m&#8217;étonnerait pas que cela soit possible grâce à des<br />
foncteurs, i.e. une classe dont un surcharge l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;. On peut ainsi se retrouver avec une construction de la forme<br />
&laquo;&nbsp;MaClasse(arg1)(arg2)&nbsp;&raquo;, i.e. un appel au constructeur suivi d&#8217;un appel à l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;.</p>
<p>En fait, à mon avis, c&#8217;est une solution possible, je garderai peut-être pour la suite, dans un hypothétique futur article <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Quoi qu&#8217;il en soit, pour en revenir au problème : on peut aussi se le poser ainsi : est-on obligés de traiter les cas où<br />
le préprocesseur ne met rien, en lieu et place de nos &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc ? Dit encore autrement, ne peut-on pas mettre<br />
quelque chose d&#8217;autre à la place ? Qu&#8217;est-ce qui nous arrangerait alors ?</p>
<p>Hmm, voyons voir, remplacer le vide par quelque chose que l&#8217;on pourrait tester lors de la compilation&#8230;<br />
Il s&#8217;agit bien de méta-programmation. Or, en méta-programmation : les 2 outils principaux que le C++ met à notre disposition<br />
sont les macros et les templates.</p>
<p>Eurêka !</p>
<p>On peut &laquo;&nbsp;surcharger&nbsp;&raquo; une fonction template qui s&#8217;occupera de faire le test d&#8217;égalité !<br />
On écrit alors les tests d&#8217;égalité comme ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code31'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39331"><td class="code" id="p393code31"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_1<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_2<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
...
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>On déclare alors TestEgalite sous cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code32'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39332"><td class="code" id="p393code32"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span>MonEnumeration val<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> e <span style="color: #000080;">==</span> val<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Et le tour est joué !</p>
<p>Bon, maintenant, pour faire plus pro, en renommant ça en anglais et en préfixant par le nom de l&#8217;énumération<br />
(histoire que l&#8217;on n&#8217;ait pas de conflit s&#8217;il y a 2 énumérations différentes, au cas où), et en remettant tout<br />
ensemble, cela donne ceci :</p>
<p>Version finale :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code33'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39333"><td class="code" id="p393code33"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(EnumType, ...)	\
	enum EnumType { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(EnumType, val, ...)	\
	if(EnumType ## _EnumIsEqual&lt;val&gt;(e)) {os &lt;&lt; #val; break;}</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_1(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_3(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_2(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_4(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_3(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_5(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_4(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_6(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_5(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_7(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_6(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_8(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_7(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_9(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_8(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_10(EnumType, val, ...)	ENUM_CASE_1(EnumType, val) ENUM_CASE_9(EnumType, __VA_ARGS__, void)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(EnumType, ...)	\
	template &lt;EnumType val&gt;				\
	inline bool EnumType ## _EnumIsEqual(const EnumType&amp; e) {	\
		return e == val;										\
	}															\
																\
	template &lt;class T&gt;											\
	inline bool EnumType ## _EnumIsEqual(const EnumType&amp; e) {	\
		return false;											\
	}															\
																\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const EnumType&amp; e) {	\
		do {																\
			ENUM_CASE_10(EnumType, __VA_ARGS__, void)								\
		} while(0);											\
		return os;											\
	}</span>
&nbsp;
<span style="color: #339900;">#define ENUMERATE(EnumType, ...)		\
	MAKE_ENUM(EnumType, __VA_ARGS__)	\
	MAKE_OPERATOR(EnumType, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code34'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39334"><td class="code" id="p393code34"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Voilà pour cette partie <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ceci dit, un problème est résolu, mais il en reste d&#8217;autres, notamment :<br />
- ça doit toujours aussi mal passer auprès des systèmes d&#8217;auto-complétion (enfin, j&#8217;ai pas testé sur Visual Assist<br />
  ou Eclipse à vrai dire&#8230;)<br />
- on ne peut toujours pas attribuer de valeur numérique manuellement à un symbole de l&#8217;énumération</p>
<p>Il pourrait aussi être intéressant d&#8217;associer une autre chaîne de caractères, voire toute autre valeur, à un symbole de<br />
l&#8217;énumération&#8230;<br />
Tout comme il serait intéressant d&#8217;explorer une solution à base de pseudo-curryfication plutôt que de templates, voire, qui<br />
sait, une solution entièrement à base de templates. A ce sujet, un article très intéressant est disponible ici pour les<br />
curieux : http://www.codeguru.com/cpp/cpp/cpp_mfc/templates/article.php/c4137</p>
<p>Ce sera tout pour cette fois !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Faire un peu joujou avec le préprocesseur&#8230;</title>
		<link>http://www.coder-studio.com/blog/preproc/</link>
		<comments>http://www.coder-studio.com/blog/preproc/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 18:53:54 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=371</guid>
		<description><![CDATA[Ça faisait un bail que je n'écrivais pas sur Coder-Studio...
Chose réparée :)

Du 17 au 19 avril 2009, a eu lieu la finale de Cod'INSA, un concours de programmation inter-INSA,
qui s'est déroulée à l'INSA de Toulouse (plus d'infos sur http://codinsa.insa-lyon.fr pour les intéressés).
Faisant partie des organisateurs, j'ai eu à faire l'interfaçage C++/Java (oui parce qu'il y en a qui veulent
participer en Java...allez comprendre :p [/troll]). J'y ai découvert les joies de GCJ et de CNI, ce qui
pourra peut-être être l'objet d'un autre article, selon ma motivation...

Bref, tout ça pour dire qu'il m'a fallu interfacer une librairie écrite en C avec du Java, et qu'il a fallu
automatiser un peu le boulot pour la partie concernant les énumérations.

Dans cet article, je vais illustrer une méthode pour faciliter l'affichage des valeurs des énumérations.
En gros, le but, c'est que si l'on a :
<pre lang="cpp">
MonEnumeration e = E_VAL_1;
std::cout << e << std::endl;
</pre>

il s'affiche alors à l'écran "E_VAL_1".]]></description>
			<content:encoded><![CDATA[<p>Ça faisait un bail que je n&#8217;écrivais pas sur Coder-Studio&#8230;<br />
Chose réparée <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Du 17 au 19 avril 2009, a eu lieu la finale de Cod&#8217;INSA, un concours de programmation inter-INSA,<br />
qui s&#8217;est déroulée à l&#8217;INSA de Toulouse (plus d&#8217;infos sur http://codinsa.insa-lyon.fr pour les intéressés).<br />
Faisant partie des organisateurs, j&#8217;ai eu à faire l&#8217;interfaçage C++/Java (oui parce qu&#8217;il y en a qui veulent<br />
participer en Java&#8230;allez comprendre :p [/troll]). J&#8217;y ai découvert les joies de GCJ et de CNI, ce qui<br />
pourra peut-être être l&#8217;objet d&#8217;un autre article, selon ma motivation&#8230;</p>
<p>Bref, tout ça pour dire qu&#8217;il m&#8217;a fallu interfacer une librairie écrite en C avec du Java, et qu&#8217;il a fallu<br />
automatiser un peu le boulot pour la partie concernant les énumérations.</p>
<p>Dans cet article, je vais illustrer une méthode pour faciliter l&#8217;affichage des valeurs des énumérations.<br />
En gros, le but, c&#8217;est que si l&#8217;on a :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code35'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37135"><td class="code" id="p371code35"><pre class="cpp" style="font-family:monospace;">MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>il s&#8217;affiche alors à l&#8217;écran &laquo;&nbsp;E_VAL_1&#8243;.</p>
<p><span id="more-371"></span></p>
<p>La version non automatisée consiste en l&#8217;écriture d&#8217;une surcharge de l&#8217;opérateur &laquo;&nbsp;<<". Programme de démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code36'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37136"><td class="code" id="p371code36"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">enum</span> MonEnumeration
<span style="color: #008000;">&#123;</span>
	E_VAL_1,
	E_VAL_2
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Ce programme affiche bien &laquo;&nbsp;E_VAL_1&#8243; à l&#8217;écran.</p>
<p>Mais c&#8217;est tout de même bien contraignant : la duplication des informations est évidente : entre la<br />
déclaration de l&#8217;énumération et l&#8217;opérateur &laquo;&nbsp;<<", "E_VAL_1" est écrit 3 fois ! C'est évidemment source<br />
d'erreurs (le copier-coller n'est pas le meilleur ami du programmeur, loin s'en faut...), particulièrement<br />
lorsque l'on veut rajouter de nouvelles valeurs à l'énumération. Et puis c'est tout simplement pénible<br />
de devoir maintenir l'énumération et l'opérateur.<br />
Bref, c'est moche, peut mieux faire.</p>
<p>C'est là qu'arrive le préprocesseur.</p>
<p>A partir de là, je suppose que vous utilisez GCC (ou MinGW/Cygwin sous Windows).</p>
<p>Nous allons en particulier nous baser sur 2 opérateurs spéciaux du préprocesseur, qui ne sont pas très<br />
connus : # et ##.</p>
<p>Commençons par # : il permet de rajouter des guillemets autour de l'argument d'une macro.</p>
<p>Démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code37'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37137"><td class="code" id="p371code37"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define STRINGIFY(val) #val</span>
&nbsp;
STRINGIFY<span style="color: #008000;">&#40;</span>pouet<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>Supposons que vous ayez enregistré cela dans &laquo;&nbsp;pouet.h&nbsp;&raquo; : passez un coup de préprocesseur : &laquo;&nbsp;cpp pouet.h&nbsp;&raquo;<br />
(ou bien &laquo;&nbsp;g++ -E pouet.h&nbsp;&raquo;, ça revient au même).</p>
<p>Résultat affiché :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code38'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37138"><td class="code" id="p371code38"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
&nbsp;
&quot;pouet&quot;</pre></td></tr></table></div>

<p>Bon, déjà, ça c&#8217;est intéressant <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  On remarque que cpp écrit des lignes commençant par un #, que le compilateur<br />
qui passe derrière doit probablement interpréter pour les messages d&#8217;erreurs afin d&#8217;indiquer la ligne de l&#8217;erreur.</p>
<p>Passons à la suite : on voudrait une macro qui permette d&#8217;automatiser la création de l&#8217;opérateur &laquo;&nbsp;<<" pour<br />
l'affichage de la valeur de notre énumération.<br />
Essayons d'abord en supposant que notre énumération ne puisse contenir qu'une seule valeur :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code39'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37139"><td class="code" id="p371code39"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, val)	\
	enum enum_name {	\
		val			\
	};</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, val)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			case val:	\
				os &lt;&lt; #val;	\
				break;	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, val)	\
	MAKE_ENUM(enum_name, val)	\
	MAKE_OPERATOR(enum_name, val)</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On a donc une macro MAKE_ENUM qui s&#8217;occupe de déclarer l&#8217;énumération et une macro MAKE_OPERATOR qui s&#8217;occupe<br />
de définir l&#8217;operateur &laquo;&nbsp;<<". Notez le "inline" qui sert à éviter tout problème de linkage (si le même fichier .h,<br />
qui décrit l'énumération et l'opérateur, est inclus dans 2 .cpp différents, on se retrouve avec l'opérateur défini 2<br />
fois, et couic !).</p>
<p>Cool, ça marche ! (en même temps c'est un tuto...)</p>
<p>Maintenant, on peut arrêter de contourner la difficulté et s'attaquer au vrai problème : comment gérer le fait<br />
qu'une énumération n'ai pas 1, 2, ou 3 valeurs, mais un nombre variable ??</p>
<p>C'est là qu'arrive une autre astuce du préprocesseur : la macro __VA_ARGS__.</p>
<p>Démonstration, dans notre pouet.h :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code40'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37140"><td class="code" id="p371code40"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MA_MACRO(...) __VA_ARGS__</span>
MA_MACRO<span style="color: #008000;">&#40;</span>a, b, c<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>cpp pouet.h donne :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code41'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37141"><td class="code" id="p371code41"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
a, b, c</pre></td></tr></table></div>

<p>Pratique, quand on veut des macros avec un nombre variable d&#8217;arguments&#8230;</p>
<p>On peut dores et déjà remplacer MAKE_ENUM par une version capable de gérer un nombre variable d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code42'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37142"><td class="code" id="p371code42"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span></pre></td></tr></table></div>

<p>Ça, c&#8217;est fait. Maintenant, reste le problème de MAKE_OPERATOR&#8230;</p>
<p>Si l&#8217;on analyse le problème, on voit que l&#8217;on a 3 parties :</p>
<p>- une introduction :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code43'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37143"><td class="code" id="p371code43"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span></pre></td></tr></table></div>

<p>- une partie qui se répète :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code44'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37144"><td class="code" id="p371code44"><pre class="cpp" style="font-family:monospace;">		<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>
			os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;</span>
			<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>- une conclusion :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code45'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37145"><td class="code" id="p371code45"><pre class="cpp" style="font-family:monospace;">		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Il s&#8217;agit donc, à partir d&#8217;une liste variable d&#8217;arguments, de répéter plusieurs fois la partie centrale pour<br />
chaque argument &laquo;&nbsp;val&nbsp;&raquo;. C&#8217;est là que j&#8217;ai pensé à ces vieux cours de Caml, où pour traiter une liste, on écrivait<br />
une fonction récursive, qui décomposait la liste en t::q (pour tête et queue), la tête étant le 1er élément, et la<br />
queue tout le reste. Désolé pour ceux qui n&#8217;ont pas fait de Caml :p</p>
<p>Pour revenir à notre préprocesseur, cela se traduirait par une macro qui prend en argument quelque chose de la forme :<br />
#define MACRO(a, &#8230;) et qui ensuite s&#8217;appellerait récursivement jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument.</p>
<p>Malheureusement, la récursivité, en préprocesseur ça n&#8217;existe pas, ou alors j&#8217;ai pas trouvé comment&#8230;</p>
<p>Il va donc falloir trouver une parade : il s&#8217;agira d&#8217;écrire une version de la macro pour chaque appel récursif, i.e.<br />
pour chaque nombre d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code46'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37146"><td class="code" id="p371code46"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le problème n&#8217;est toujours pas totalement résolu : encore faut-il choisir la bonne macro à utiliser&#8230;</p>
<p>C&#8217;est là qu&#8217;arrive l&#8217;opérateur ## du préprocesseur <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Celui-ci permet de concaténer des symboles.</p>
<p>Exemple (dans pouet.h) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code47'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37147"><td class="code" id="p371code47"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define CONCAT(a, b) a ## b</span>
CONCAT<span style="color: #008000;">&#40;</span>foo, bar<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>&laquo;&nbsp;cpp pouet.h&nbsp;&raquo; affiche cette fois :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code48'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37148"><td class="code" id="p371code48"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
foobar</pre></td></tr></table></div>

<p>Cela va nous servir à choisir la bonne macro à utiliser :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code49'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37149"><td class="code" id="p371code49"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le gros inconvénient est bien sûr qu&#8217;il nous faut préciser le nombre de valeurs de l&#8217;énumération :/</p>
<p>Il semble que l&#8217;on ait fait le tour. Voici donc la version finale de tout ça, séparée dans un .h générique<br />
et un .cpp d&#8217;exemple :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code50'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37150"><td class="code" id="p371code50"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_N(nb_vals, __VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(nb_vals, enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code51'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37151"><td class="code" id="p371code51"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p><strong>Conclusion</strong></p>
<p>Au final, cette méthode présente l&#8217;avantage d&#8217;éviter la duplication de code, et tous les ennuis qui vont avec.<br />
Il reste cependant plusieurs inconvénients non négligeables :<br />
- On est obligés de préciser le nombre de valeurs de l&#8217;énumération<br />
- On est limités dans le nombre de valeurs que l&#8217;on peut définir par le nombre de macros que l&#8217;on a définis dans Enumerate.h<br />
  A la limite, si l&#8217;on a besoin de plus de valeurs, il suffit de les rajouter, c&#8217;est pas bien grave ^^<br />
- Pour la plupart des IDE, je pense qu&#8217;un tel système aboutit à un type &laquo;&nbsp;MonEnumeration&nbsp;&raquo;, ainsi que les valeurs définies,<br />
  qui sont inconnus. Ça peut être un problème&#8230;<br />
- En déclarant ses énumérations de la sorte, on ne peut pas préciser de valeur numérique pour chaque valeur possible de<br />
  l&#8217;énumération.</p>
<p>La méthode a ses limites, et je me demande s&#8217;il n&#8217;y aurait pas moyen d&#8217;aller au-delà en utilisant des templates&#8230;<br />
Par ailleurs, ce petit article sur le préprocesseur ne fait aucune mention de Boost::Preprocessor, qui, selon Arnaud,<br />
est incroyable à voir&#8230;<br />
Je serais curieux de voir s&#8217;il pourrait apporter un élément de réponse au problème ^^</p>
<p>Ce sera tout !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preproc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Interface GSM sur système Linux embarqué</title>
		<link>http://www.coder-studio.com/blog/interface-gsm-sur-systeme-linux-embarque/</link>
		<comments>http://www.coder-studio.com/blog/interface-gsm-sur-systeme-linux-embarque/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:38:38 +0000</pubDate>
		<dc:creator>Aquanum</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[Embarqué]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[AT]]></category>
		<category><![CDATA[Fox Board]]></category>
		<category><![CDATA[GSM]]></category>
		<category><![CDATA[SMS]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=25</guid>
		<description><![CDATA[J&#8217;ai été amené à travailler dans le cadre de mes études sur un petit projet de développement d&#8217;une Interface GSM sur un système Linux embarqué. Ayant découvert la puissance du système, j&#8217;ai pensé vous faire part de mes découvertes sur l&#8217;utilisation de cette carte.
Dans mon cas le principe était de créer un système autonome d&#8217;envoi [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_24" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-24" title="carte_fox" src="http://r19649.ovh.net/cs/blog/wp-content/uploads/2009/02/acme_fox-300x197.jpg" alt="Carte Fox" width="300" height="197" /><p class="wp-caption-text">Carte Fox</p></div>
<p style="text-align: justify;">J&#8217;ai été amené à travailler dans le cadre de mes études sur un petit projet de développement d&#8217;une Interface GSM sur un système Linux embarqué. Ayant découvert la puissance du système, j&#8217;ai pensé vous faire part de mes découvertes sur l&#8217;utilisation de cette carte.</p>
<p style="text-align: justify;">Dans mon cas le principe était de créer un système autonome d&#8217;envoi de SMS aux étudiants de mon école. L&#8217;idée étant de pouvoir envoyer les résultats des examens directement par SMS aux étudiants, ce qui est ma foi fort sympatique <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2 style="text-align: justify;">Le Matériel</h2>
<p style="text-align: justify;">Alors, tout d&#8217;abord : Carte FOX Késako !? Il s&#8217;agit d&#8217;un système embarqué à bas coût utilisant le système d’exploitation Linux. La carte est dotée d’un processeur AXIS à 100MHz et de 32 MB de RAM, de connectiques USB, Ethernet, d’un port série console ainsi que 40 pins pouvant être reliées à plusieurs BUS de données. Elle permet de développer en bon nombre de langages : C, C++, PHP, PYTHON, Shell, … et permet des connections HTTP, FTP, SSH et TELNET. De petite taille et faible consommation électrique (1 W) est idéale pour mettre en place rapidement des projets de type embarqué.</p>
<p style="text-align: justify;">
<div id="attachment_36" class="wp-caption alignright" style="width: 210px"><img class="size-full wp-image-36" title="gm862-quad" src="http://r19649.ovh.net/cs/blog/wp-content/uploads/2009/02/gm862-quad.jpg" alt="Modem GSM" width="200" height="200" /><p class="wp-caption-text">Modem GSM</p></div>
<p>Le modem GSM utilisé ici est un modem de la marque Telit. Il est relié à la carte FOX par l’intermédiaire d’une carte d’extension. La carte FOX peut communiquer avec le modem par l’intermédiaire du port série /dev/ttyS2. Une simple utilisation de carte SIM classique permet de se connecter au réseau GSM. Il est possible de trouver cette carte seule sur le site d&#8217;<a href="http://foxlx.acmesystems.it/?id=4">ACME SYSTEMS</a> à 176 € frais de port tout compris. Si l&#8217;on ajoute le kit GPRS cela monte jusqu&#8217;à 626 €, ce qui commence déjà à faire beaucoup. Je pense qu&#8217;une solution plus abordable serait de relier la carte basique à un téléphone portable pour communiquer en série étant donné que dans notre cas nous n&#8217;avons pas besoin de tous les éléments de la carte d&#8217;extension.</p>
<p style="text-align: justify;">Les modems GSM utilisent un protocole de commandes appelées &laquo;&nbsp;commandes AT&nbsp;&raquo;. Chaque constructeur fait un peu ce qu&#8217;il veut avec ses normes, ce qui fait que chaque modem est plus ou moins différent et qu&#8217;il faut se référer à la <a href="http://www.telit.com/module/infopool/download.php?id=542">doc du constructeur</a>. Ces commandes AT sont donc envoyées via le port série pour soumettre différentes commandes au modem. On peut notamment dans notre cas manipuler et envoyer des SMS par l’intermédiaire de celles-ci.</p>
<p><span id="more-25"></span></p>
<h2 style="text-align: justify;">Environnement de développement</h2>
<p style="text-align: justify;">La compilation d’un programme en C sur la carte fox nécessite un compilateur croisé permettant de compiler le code C pour les processeurs AXIS. La compilation directe sur la carte n’étant pas possible, il faut par conséquent utiliser un SDK  pour compiler le programme. J&#8217;ai travaillé avec le <a href="http://foxlx.acmesystems.it/?id=5">SDK Axis</a> fourni pour la carte fox.</p>
<p style="text-align: justify;">Avant toute chose il faut se rendre dans le dossier du SDK (~/devboard-R2_01 pour ma part) et y taper la commande suivante afin d’initialiser l’environnement de développement.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code60'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2560"><td class="code" id="p25code60"><pre class="shell" style="font-family:monospace;">. init_env</pre></td></tr></table></div>

<p>Ensuite, il faut choisir le compilateur AXIS</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code61'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2561"><td class="code" id="p25code61"><pre class="shell" style="font-family:monospace;">make cris-axis-linux-gnu</pre></td></tr></table></div>

<p>On doit alors créer un Makefile pour notre programme. Voici celui que j&#8217;ai créé :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code62'); return false;">View Code</a> MAKEFILE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2562"><td class="code" id="p25code62"><pre class="makefile" style="font-family:monospace;">AXIS_USABLE_LIBS=UCLIBC GLIBC
include $(AXIS_TOP_DIR)/tools/build/Rules.axis
PROGS = sms
INSTDIR= $(prefix)/mnt/flash
INSTMODE= 0755
INSTOWNER= root
INSTGROUP= root
OBJS = main.o atcommand.o modem.o
all: $(PROGS)
$(PROGS): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
scp sms root@fox01:/mnt/flash/tx
clean:
rm -f *.o
rm -f sms</pre></td></tr></table></div>

<p style="text-align: justify;">Il n’y a alors plus qu’à faire un make pour compiler le programme et à l’envoyer sur la carte en FTP ou SCP. Ayant dû compiler à de très nombreuses reprises mon programme, j’ai rajouté l’envoi du fichier dans le makefile via la commande scp. Les fichiers utilisateurs sont déposés sur la carte Flash dans le répertoire /mnt/flash. Attention toutefois, car la mémoire flash EPROM est limitée en nombre d&#8217;écritures. Il vaut mieux tant que possible éviter d&#8217;écrire dans cette mémoire régulièrement. Privilégier la RAM (dossier /var par exemple) plutôt que sur la carte flash. Seul soucis, la carte se réinitialise à chaque redémarrage, par conséquent les tests peuvent être faits en RAM et une fois que l&#8217;application compilée est stable il est préférable de la déposer sur la carte flash afin de ne pas perdre le programme à chaque reboot.</p>
<p style="text-align: justify;">La connexion à la carte fox se fait en telnet (ou ssh) simplement à l’aide de la commande suivante grâce à un simple telnet</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code63'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2563"><td class="code" id="p25code63"><pre class="shell" style="font-family:monospace;">telnet adresse_ip_de_la_fox</pre></td></tr></table></div>

<h2 style="text-align: justify;">Développement du programme</h2>
<h3>Utilisation des commandes AT</h3>
<p style="text-align: justify;">Le modem se commande directement grâce aux commandes AT.  Ces commandes AT suivent une certaine syntaxe et nécessitent une mise en forme particulière pour leur envoi sur le modem. Ce dernier reconnaît plusieurs caractères de contrôle :</p>
<p style="text-align: justify;"><strong>&lt;CR&gt;</strong> : Caractère de retour chariot : Sa valeur ASCII en décimal est fixée à 13 par défaut. (et peut être changée grâce au paramètre AT S3) Sa valeur hexadécimale quant à elle est 0&#215;0D.</p>
<p style="text-align: justify;"><strong>&lt;LF&gt;</strong> : Caractère d’interligne : Sa valeur ASCII en décimal est fixée à 10 par défaut</p>
<p style="text-align: justify;"><strong>&lt;CTRL+Z&gt;</strong> : Combinaison des touches CTRL et Z. Sa valeur hexa est 0&#215;1A</p>
<p style="text-align: justify;">Ces caractères sont demandés et utilisés par le modem pour identifier les commandes AT. Chacune d’entre-elles utilise ces caractères de contrôle plus ou moins différemment. Voici un aperçu des différentes commandes que j’ai utilisées avec leurs caractères de contrôle.</p>
<p style="text-align: justify;"><strong>ATE0&lt;CR&gt;</strong><br />
Cette commande permet de désactiver la commande écho (ATE1 la réactive). Cela demande donc au modem de ne pas répéter systématiquement les commandes qui lui sont envoyées.</p>
<p style="text-align: justify;"><strong>AT+CMGF=1&lt;CR&gt;</strong></p>
<p style="text-align: justify;">Cette commande permet de régler le format de message pour l’envoi de SMS. Par défaut, le modem est en mode PDU (AT+CMGF=0). C&#8217;est-à-dire que l’envoi de message se fait en hexadécimal. AT+CMGF=1 permet de passer en mode texte, ce qui simplifie les manipulations de SMS.</p>
<p style="text-align: justify;"><strong>AT+CMGS=&nbsp;&raquo;06XXXXXXXX&nbsp;&raquo;&lt;CR&gt;</strong></p>
<p style="text-align: justify;">Cette commande permet de commencer la rédaction d’un SMS. On précise en argument le numéro de téléphone choisi. En retour on obtient le caractère d’invite de commande « &gt; » qui nous invite à rentrer le texte du SMS.</p>
<p style="text-align: justify;"><strong>Texte du SMS&lt;CTRL+Z&gt;&lt;CR&gt;</strong><br />
Cette fin de commande permet alors de préciser le texte et de valider l’envoi du SMS par un CTRL+Z et un retour chariot.</p>
<p style="text-align: justify;">Il est important de noter que l&#8217;envoi de la commande AT d&#8217;envoi de SMS se fait en 2 parties et pas en un coup. (j&#8217;ai testé pendant plusieurs semaines&#8230; ça ne marche pas ^^)</p>
<p style="text-align: justify;">Le modem répond à ces commandes par des messages de retour. Ces derniers indiquent si celles-ci ont été exécutées avec succès ou non. La plupart de ces réponses sont entourées des caractères <strong>&lt;CR&gt;&lt;LF&gt;</strong> Il y a toutefois des exceptions, notamment pour <strong>AT+CMGS</strong> qui renvoie <strong>+CMGS: &lt;mr&gt;</strong> ou <strong>+CMS ERROR: &lt;err&gt;</strong> Mais dans la plupart des cas les retours sont rapportés de la manière suivante :<br />
<strong>&lt;CR&gt;&lt;LF&gt;OK&lt;CR&gt;&lt;LF&gt;<br />
&lt;CR&gt;&lt;LF&gt;ERROR&lt;CR&gt;&lt;LF&gt;<br />
&lt;CR&gt;&lt;LF&gt;&#8230;&lt;CR&gt;&lt;LF&gt;</strong></p>
<p style="text-align: justify;">Ces commandes AT doivent être transmises au modem par le port série /dev/ttyS2. Il existe plusieurs façons de communiquer sur le port série :</p>
<p style="text-align: justify;"><strong>Termnetd</strong> (<a href="http://foxlx.acmesystems.it/?id=69">http://foxlx.acmesystems.it/?id=69</a>)</p>
<p style="text-align: justify;">Il s’agit d’un processus permettant de relier un port TCP/IP à un port série de manière transparente. Une fois que le deamon est lancé sur la carte fox, il est possible de se connecter depuis l’extérieur grâce à la commande telnet adress_ip_fox 7000. Le port 7000 (choisi dans la config de termnetd) redirige directement sur le port série et il est alors possible de rentrer manuellement des commandes AT et de voir leur comportement direct sur le modem. Ce programme est utile pour comprendre le fonctionnement des commandes AT.</p>
<p style="text-align: justify;"><strong>Script Chat</strong> (<a href="http://linux.about.com/od/commands/l/blcmdl8_chat.htm">http://linux.about.com/od/commands/l/blcmdl8_chat.htm</a>)<br />
Il est possible d’utiliser la commande UNIX chat permettant de dialoguer de manière automatisée avec le modem.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code64'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2564"><td class="code" id="p25code64"><pre class="shell" style="font-family:monospace;">/usr/sbin/chat -V -s -f &lt;fichier_script&gt; &gt; /dev/ttyS2 &lt; /dev/ttyS2 2&gt;&lt;fichier_resultat&gt;</pre></td></tr></table></div>

<p style="text-align: justify;">La réponse du modem est alors enregistrée dans le fichier de résultat choisi.</p>
<p style="text-align: justify;"><strong>Programme en C</strong><br />
Il est également possible de dialoguer avec le modem via un programme C. Le dialogue se fait alors en écrivant et en lisant sur /dev/ttyS2. La prise en main est beaucoup plus complexe que les 2 précédentes méthodes, mais permet une totale maitrise du modem.</p>
<h3 style="text-align: justify;">Développement en C</h3>
<p style="text-align: justify;">Le code pour envoyer un SMS n&#8217;est pas bien compliqué, mon but n&#8217;est pas là de copier/coller intégralement mon code, mais plutôt d&#8217;expliquer les grandes lignes son fonctionnement et de vous donner envie de bidouiller une carte fox ^^</p>
<p style="text-align: justify;">L&#8217;idée est donc d&#8217;initialiser tout d&#8217;abord la connexion série à l&#8217;aide de Termios. La documentation sur le site du constructeur regorge d&#8217;informations et propose du <a href="http://foxlx.acmesystems.it/foxlx_acmesystems_it/00035/serial_test.c">code tout fait</a> pour gérer la connexion série. Une fois la configuration réalisée (c&#8217;est très rapide à réaliser), il n&#8217;y a plus qu&#8217;à faire un write sur /dev/ttyS2</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code65'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2565"><td class="code" id="p25code65"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span> command1<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> command2<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">50</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
sprintf<span style="color: #009900;">&#40;</span>command1<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;AT+CMGS=&quot;</span><span style="color: #339933;">%</span>s<span style="color: #ff0000;">&quot;x0D&quot;</span><span style="color: #339933;">,</span> number<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sprintf<span style="color: #009900;">&#40;</span>command2<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;%sx1Ax0D&quot;</span><span style="color: #339933;">,</span> text<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
write <span style="color: #009900;">&#40;</span>tty_fd<span style="color: #339933;">,</span> command1<span style="color: #339933;">,</span> strlen<span style="color: #009900;">&#40;</span>command1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sleep<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// attend la réponse du modem afin d'envoyer la seconde partie</span>
write<span style="color: #009900;">&#40;</span>tty_fd<span style="color: #339933;">,</span>command2<span style="color: #339933;">,</span>strlen<span style="color: #009900;">&#40;</span>command2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Et le SMS est envoyé ! Après libre à vous de rajouter à la suite une lecture de la réponse du modem (gentil petit read). Dès lors il est possible de se faire une petite fonction d&#8217;envoi de SMS à partir d&#8217;arguments tels que le numéro de téléphone et le texte du message. J&#8217;en ai profité pour me rajouter un système de logs et de manipulation du modem (redémarrage, arrêt). Je me suis créé une interface web en bash (scripts cgi) et par simples appels de notre programme C il est alors possible de se construire une application métier complexe. On a plus qu&#8217;à brancher notre carte fox sur le réseau et celle-ci peut envoyer des SMS à distance de manière assistée grâce à des formulaires web !</p>
<h2 style="text-align: justify;">Préparation de la carte FOX</h2>
<p style="text-align: justify;">Dernier point de précision: au démarrage, le modem n’est pas allumé ni configuré. Il faut par conséquent créer un script de démarrage à déposer dans /etc/init.d/boottime . Voici le script que j&#8217;ai utilisé:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code66'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2566"><td class="code" id="p25code66"><pre class="shell" style="font-family:monospace;">#!/bin/sh
# démarrage du modem
setbits -p b -b 7 -s 1
# Lancement de termnetd (pour les tests)
/mnt/flash/termnetd
# Initialisation série du modem (mon petit programme d’initialisation de la connexion série)
/mnt/flash/tx/sms -init
sleep 20
# Initialisation AT du modem
/usr/sbin/chat -V -s -f /mnt/flash/tx/scripts/scriptAT.chat &gt;
/dev/ttyS2 &lt; /dev/ttyS2 2&gt; /mnt/flash/tx/scripts/scriptAT_result.txt
# Ecriture des logs (pour le fun ^^)
echo “`date` : MODEM start” &gt;&gt; /mnt/flash/tx/log/fox.log</pre></td></tr></table></div>

<p style="text-align: justify;">On commence par allumer le modem, on initialise la connexion série avec le programme en C puis attend 20 secondes que le modem soit identifié sur le réseau. Le temps choisi est totalement arbitraire. Cela semble fonctionner correctement avec cette période, mais idéalement il serait intéressant d’interroger le modem pour déterminer s’il est bien connecté au réseau. Ensuite on exécute un script chat que voici :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p25code67'); return false;">View Code</a> SCRIPT_CHAT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2567"><td class="code" id="p25code67"><pre class="script_chat" style="font-family:monospace;">ABORT BUSY
ABORT 'NO CARRIER'
ABORT ERROR
'' AT
OK ATZ
OK 'ATE0'
OK 'AT+CMGF=1'
OK ''</pre></td></tr></table></div>

<p style="text-align: justify;">Ce dernier permet de désactiver l’écho afin de ne pas recevoir mes commandes en double, et permet d’activer le mode texte pour l’envoi de SMS. Par défaut l’envoi de SMS se fait en mode PDU (sous forme hexadécimale), ce qui est bien plus compliqué à utiliser. Une fois ce script exécuté, le modem est prêt à être utilisé. On peut rajouter un log à la fin pour identifier le démarrage du modem.</p>
<p style="text-align: justify;">La carte fox est une carte embarqué assez simple à prendre en main, les utilisations sont assez illimités. Le rêve de tout bidouilleur !<br />
Je songe à m&#8217;en commander une très bientôt, je ne peux pas résister à tant de potentiel de bidouille.</p>
<p style="text-align: justify;">A suivre : Comment connecter la carte fox au réseau GPRS pour pouvoir aller sur le net et envoyer des mail <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/interface-gsm-sur-systeme-linux-embarque/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Introduction à wxWidgets</title>
		<link>http://www.coder-studio.com/blog/introduction-a-wxwidgets/</link>
		<comments>http://www.coder-studio.com/blog/introduction-a-wxwidgets/#comments</comments>
		<pubDate>Mon, 08 Aug 2005 16:47:29 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[wxWidgets]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=123</guid>
		<description><![CDATA[I) Présentation
wxWidgets est une librairie open source dont le but 1er est de permettre de créer des interfaces graphiques pour ses programmes (fenêtres, boutons&#8230;etc). Elle est portable mais les applications crées avec ont la particularité d&#8217;adopter le &#171;&#160;look and feel&#160;&#187; (apparence) de la plate-forme sur laquelle elles ont été compilées. Cela est dû au fait [...]]]></description>
			<content:encoded><![CDATA[<h2>I) Présentation</h2>
<p style="text-align: justify;">wxWidgets est une librairie open source dont le but 1er est de permettre de créer des interfaces graphiques pour ses programmes (fenêtres, boutons&#8230;etc). Elle est portable mais les applications crées avec ont la particularité d&#8217;adopter le &laquo;&nbsp;look and feel&nbsp;&raquo; (apparence) de la plate-forme sur laquelle elles ont été compilées. Cela est dû au fait qu&#8217;en interne, wxWidgets utilise l&#8217;API propre à chaque plate-forme (API Win32 ou juste GDI sous Windows, GTK+, Motif ou directement X11 sous Linux et autres UNIXs, Carbon ou Cocoa sous Mac&#8230;). Cependant, l&#8217;équipe de wxWidgets a également mis sur pied une version spéciale de wxWidgets, wxUniversal, qui compile sous Windows, Linux et certains périphériques embarqués, et qui s&#8217;occupe entièrement de l&#8217;affichage (le &laquo;&nbsp;look and feel&nbsp;&raquo; natif de la plate-forme n&#8217;est pas forcément respecté).</p>
<p style="text-align: justify;">Cependant, wxWidgets ne se limite pas à permettre la création d&#8217;interfaces graphiques, elle est capable de faire beaucoup d&#8217;autres choses; elle possède ses propres classes de tableau, tables de haschage, liste chaînée, elle permet de créer des applications utilisant les sockets (connections réseau), d&#8217;intégrer une zone dédiée à OpenGL dans une fenêtre pour pouvoir faire du dessin en 3D, de faire des manipulations de chaînes grâce à la classe wxString, contient une sous-librairie, wxHTML, qui permet de visualiser une page HTML, possède son propre système d&#8217;aide semblable aux CHM de Windows, peut utiliser des ressources au format XML, peut utiliser des bases de données&#8230;etc.</p>
<p style="text-align: justify;">Et tout cela est gratuit et portable, pourquoi s&#8217;en priver ? <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span id="more-123"></span></p>
<h2>II) Installation</h2>
<p>Quelle que soit la plate-forme choisie, wxWidgets n&#8217;est pas livrée pré-compilée; c&#8217;est à vous de la compiler à partir des sources.</p>
<p>Mais avant de compiler, cherchez le fichier setup.h et modifiez-le si besoin. Ce fichier contient des #defines qui définissent comment la librairie doit être compilée. Personnellement, j&#8217;ai l&#8217;habitude de changer le :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code74'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12374"><td class="code" id="p123code74"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Recommended setting: 1 if you intend to use OpenGL, 0 otherwise</span>
<span style="color: #339900;">#define wxUSE_GLCANVAS</span></pre></td></tr></table></div>

<p>en :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code75'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12375"><td class="code" id="p123code75"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Recommended setting: 1 if you intend to use OpenGL, 0 otherwise</span>
<span style="color: #339900;">#define wxUSE_GLCANVAS</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ce qui permet d&#8217;utiliser la classe wxGLCanvas si l&#8217;on veut pouvoir créer une zone OpenGL dans une fenêtre d&#8217;un programme wxWidgets.</p>
<p style="text-align: justify;">Ensuite, si vous êtes sous Visual C++, il lancez la compilation du projet situé dans le répertoire src. Vous avez le temps d&#8217;aller boire un café en attendant, vu que le compilateur met un certain temps à &laquo;&nbsp;digérer&nbsp;&raquo; la librairie <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Après, il faut aller dans le menu Tools-&gt;Options-&gt;onglet Directories, rajouter le répertoire lib lorsque &laquo;&nbsp;Librairies files&nbsp;&raquo; est sélectionné et rajouter le répertoire include lorsque &laquo;&nbsp;Include files&nbsp;&raquo; est sélectionné.</p>
<p style="text-align: justify;">Enfin, pour créer un projet, je vous recommande de reprendre un des projets du répertoire samples qui contient de nombreux exemples et de le réutiliser.</p>
<p style="text-align: justify;">Si vous utilisez Dev-C++, vous pouvez trouver <a href="http://michel.weinachter.free.fr/indexfr.html">des DevPacks ici</a> ou compiler vous-mêmes; si vous optez pour cette solution, regardez du côté des makefiles, du fichier configure ou essayez d&#8217;importer le projet Visual C++.</p>
<p style="text-align: justify;">[UPDATE du 23/09/04 : vous pouvez également télécharger un DevPack <a href="http://cfred.free.fr/DevPack/">ICI</a> pour wxWidgets 2.5.2, merci à fredcl <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  D'ailleurs il me fait remarquer qu'il faut impérativement désinstaller toute version précédente du DevPack avant d'installer celle-ci ^^]</p>
<p>Si vous êtes sous Linux, il faut faire le triplet habituel</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code76'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12376"><td class="code" id="p123code76"><pre class="shell" style="font-family:monospace;">./configure
&nbsp;
make
make install</pre></td></tr></table></div>

<p>Mais renseignez-vous avant sur les options que vous pouvez passer au ./configure (notamment &#8211;with-opengl et &#8211;use-gtk2 il me semble, mailez-moi si je me trompe).</p>
<p>Ensuite, pour la compilation en ligne de commande on fait:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code77'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12377"><td class="code" id="p123code77"><pre class="shell" style="font-family:monospace;">g++ mon_code.cpp -o mon_executable `wx-config --libs --cflags`</pre></td></tr></table></div>

<h2>III) Premier programme</h2>
<p>Allez c&#8217;est parti, maintenant on code !</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code78'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12378"><td class="code" id="p123code78"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// App.h</span>
<span style="color: #339900;">#ifndef APP_H</span>
<span style="color: #339900;">#define APP_H</span>
&nbsp;
<span style="color: #666666;">// Le header principal de wxWidgets</span>
<span style="color: #339900;">#include </span>
&nbsp;
<span style="color: #666666;">// La classe App représente l'application</span>
<span style="color: #0000ff;">class</span> App <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> wxApp
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
&nbsp;
   <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> OnInit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  <span style="color: #666666;">// OnInit() est l'équivalent du main() classique :</span>
                           <span style="color: #666666;">// c'est là que débute le programme.</span>
&nbsp;
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif // APP_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code79'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12379"><td class="code" id="p123code79"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// App.cpp</span>
<span style="color: #339900;">#include &quot;App.h&quot;</span>
&nbsp;
<span style="color: #666666;">// Cette macro crée l'objet global de type App qui représente l'application.</span>
IMPLEMENT_APP<span style="color: #008000;">&#40;</span>App<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #666666;">// Equivalent de main()</span>
<span style="color: #0000ff;">bool</span> App<span style="color: #008080;">::</span><span style="color: #007788;">OnInit</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// On crée une nouvelle wxFrame (une fenêtre), avec new.</span>
   <span style="color: #666666;">// Notez qu'il est inutile d'appeler delete, wxWidgets le fera</span>
   <span style="color: #666666;">// automatiquement :)</span>
   wxFrame<span style="color: #000040;">*</span> frame <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> wxFrame<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, <span style="color: #FF0000;">&quot;Hello World !&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On centre la fenêtre</span>
   frame<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>Center<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On l'affiche</span>
   frame<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>Show<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On précise à wxWidgets que ce sera la fenêtre principale;</span>
   <span style="color: #666666;">// grâce à cela il pourra détruire (delete) la fenêtre en fin d'application</span>
   <span style="color: #666666;">// et c'est aussi grâce à cela qu'un clic sur la croix ferme le programme</span>
   <span style="color: #666666;">// (et pas seulement la fenêtre).</span>
   this<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>SetTopWindow<span style="color: #008000;">&#40;</span>frame<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// Pour finir on renvoie TRUE, ce qui signifie que l'application doit continuer</span>
   <span style="color: #666666;">// (et rentrer dans la boucle d'évènements).</span>
&nbsp;
   <span style="color: #0000ff;">return</span> TRUE<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h2>IV) Conclusion</h2>
<p style="text-align: justify;">Voilà, ce tutorial n&#8217;est qu&#8217;une première approche à wxWidgets, normalement devraient suivre d&#8217;autres tuts sur les menus, les boutons, les listes&#8230;</p>
<p style="text-align: justify;">Comme d&#8217;habitude, pour toute remarque/critique/suggestion, laissez un message ci-dessous ou mailez-moi à funto66 at gmail.com.</p>
<blockquote>
<p style="text-align: justify;">Cet article provient du tutorial publié par Funto le 08/08/2005 sur l&#8217;ancien site de Coder-Studio.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/introduction-a-wxwidgets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Les Bases du langage C</title>
		<link>http://www.coder-studio.com/blog/les-bases-du-langage-c/</link>
		<comments>http://www.coder-studio.com/blog/les-bases-du-langage-c/#comments</comments>
		<pubDate>Sat, 30 Jul 2005 16:29:13 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[débutant]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=15</guid>
		<description><![CDATA[Introduction
Je suppose que si vous êtes arrivé jusqu&#8217;à cette page web, soit vous vous êtes perdu soit vous voulez vraiment apprendre à programmer en langage C ^^. Si vous êtes dans ce cas, bienvenue chez les programmeurs ! Alors, qu&#8217;est-ce que le C ? Le C est un langage de programmation; on écrit un programme [...]]]></description>
			<content:encoded><![CDATA[<h2 style="text-align: justify;">Introduction</h2>
<p style="text-align: justify;">Je suppose que si vous êtes arrivé jusqu&#8217;à cette page web, soit vous vous êtes perdu soit vous voulez vraiment apprendre à programmer en langage C ^^. Si vous êtes dans ce cas, bienvenue chez les programmeurs ! Alors, qu&#8217;est-ce que le C ? Le C est un langage de programmation; on écrit un programme dans ce langage, et ensuite le texte que vous avez tapé est converti par un &laquo;&nbsp;compilateur&nbsp;&raquo; en langage binaire 0 et 1 compréhensible par le processeur de votre ordinateur (un fichier .exe). Donc, pour commencer, il vous faut un compilateur et un éditeur (le bloc-notes peut suffire comme éditeur mais il y a beaucoup mieux <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ). Un environnement qui intègre et compilateur et éditeur est appelé IDE (Integrated Development Environment). La plupart de ceux que je vais vous proposer sont des compilateurs C++. Qu&#8217;est-ce que le C++? C&#8217;est un autre langage, mais qui en réalité est compatible avec le C (un programme écrit en C peut se compiler avec un compilateur C++ mais pas l&#8217;inverse). Le C++, c&#8217;est donc tout le C, mais avec des notions supplémentaires (templates, objets, surcharge de fonctions&#8230;). Le C et le C++ sont définis par les normes ANSI/ISO (ce sont des organismes de normalisation, en gros ils donnent les règles que doit respecter un compilateur pour pouvoir être présenté comme un compilateur C ANSI ou C++ ANSI).</p>
<p style="text-align: justify;"><span id="more-15"></span>Voici donc les IDEs majeurs (sous Windows) :</p>
<p style="text-align: justify;"><strong>Visual C++ de Microsoft</strong> : il est payant, très utilisé, et est compatible avec la plupart des librairies (j&#8217;expliquerai plus tard). Il est spécialement pratique à utilisé accompagné de Visual Assist (payant). La version 6.0 est &laquo;&nbsp;indépendante&nbsp;&raquo; alors que la version 7.0 est intégrée à Visual Studio.NET (il vous faudra un PC bien puissant pour utiliser celle-ci&#8230;)</p>
<p style="text-align: justify;"><strong>Dev-C++ de Bloodshed Software</strong> : il est gratuit et sous licence GPL open source, vous pouvez le trouver sur <a href="http://www.bloodshed.net">http://www.bloodshed.net</a>. Cet IDE s&#8217;appuie sur le compilateur MinGW, qui est une version Windows du compilateur pour Linux GCC. Cet environnement est très bien aussi et est aussi compatible avec la plupart des librairies (notamment celles que nous utiliserons plus tard). Prenez la bêta 5.</p>
<p style="text-align: justify;"><strong>Borland C++Builder</strong> : il est payant (trop d&#8217;ailleurs ?) mais est fourni avec la librairie VCL, ce qui lui donne un avantage non négligeable sur les autres (en gros il permet de créer des interfaces graphiques (fenêtres, boutons&#8230; de Windows) très facilement). Cependant, Borland met à disposition de tous le compilateur de la version 5.5 de C++Builder, sans l&#8217;environnement de développement. Qu niveau des librairies, il me semble qu&#8217;il est possible d&#8217;importer celles de Visual C++.</p>
<p style="text-align: justify;">Cf <a title="http://www.borland.com/products/downloads/download_cbuilder.html" href="http://www.borland.com/products/downloads/download_cbuilder.html">http://www.borland.com/products/downloads/download_cbuilder.html</a></p>
<p style="text-align: justify;"><strong>Borland C++BuilderX </strong> : c&#8217;est le tout nouvel IDE de Borland, qui semble très prometteur. Vous pouvez l&#8217;associer à n&#8217;importe quel compilateur (MinGW, le compilateur de Borland, celui de Visual C++&#8230;)</p>
<p style="text-align: justify;"><strong>LCC-Win32</strong> : c&#8217;est un vieil IDE reposant sur le compilateur LCC; il est gratuit mais n&#8217;est plus développé et ne compile que le C (pas le C++). Pour les librairies, c&#8217;est comme pour Borland, on peut importer celles de Visual C++.</p>
<p style="text-align: justify;">Il existe encore d&#8217;autres IDEs/compilateurs C++ (Digital Mars C++, Symantec C++, Watcom C++, CodeWarrior&#8230;), mais je vous ai cité les principaux compilateurs pour Windows (Win32). Cependant, il y a aussi des compilateurs pour MS-DOS (Turbo C++, DJGPP) mais ceux-ci ne seront pas compatibles dès lors que nous voudrons utiliser des librairies pour Win32. Cependant, vous pouvez très bien les utiliser pour ce tutorial sur le langage C, vu qu&#8217;ils respectent les normes ANSI/ISO.</p>
<p style="text-align: justify;">Dans la suite de ce tutorial, je considérerai que vous utilisez Visual C++ 6.0 ou Dev-C++ 5 bêta. Pour les autres, les explications doivent être à peu près semblables.</p>
<h2 style="text-align: justify;">II) Premier programme</h2>
<p style="text-align: justify;">Bon, c&#8217;est pas tout ça, mais faudrait commencer ! <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Ouvrez votre IDE, et créez un nouveau &laquo;&nbsp;projet&nbsp;&raquo; (un projet rassemble tout ce qui concerne la création d&#8217;un programme) (Fichier -&gt;Nouveau -&gt; Projet ou File -&gt;New -&gt;Onglet Project, enfin vous connaissez <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ). Le projet sera de type Win32 Console Application sous Visual C++ 6.0 et Console Application (langage C) sous Dev-C++. Donnez-lui un nom (&laquo;&nbsp;Hello&nbsp;&raquo;) et cliquez sur OK. Sous Visual C++ 6.0, choisissez &laquo;&nbsp;An empty Project&nbsp;&raquo;.</p>
<p style="text-align: justify;">Maintenant que votre projet est créé et ouvert, vous devez y ajouter un fichier &laquo;&nbsp;hello.c&nbsp;&raquo; (sous Dev-C++ vous avez déjà un fichier main.c, faites un clic droit sur l&#8217;onglet et choisissez Fermer; n&#8217;enregistrez pas). Pour cela, sous Visual C++ 6.0 ouvrez l&#8217;onglet File View et faites File -&gt;New -&gt; Onglet Files -&gt;C++ Source File. Appelez-le hello.c. Si vous regardez dans l&#8217;arborescence de l&#8217;onglet File View vous verrez que le fichier hello.c est bien ajouté dans les Source Files. Les dossiers que vous voyez n&#8217;existent pas réellement, ils permettent de séparer les fichiers pour pouvoir mieux les repérer. Pour les utilisateurs de Dev-C++ : faites Fichier -&gt; Nouveau -&gt; Fichier Source -&gt; Ajouter au projet? Yes -&gt; enregistrez-le sous hello.c.</p>
<p>Bon, si vous avez suivi jusque là, on peut enfin commencer à coder ! Recopiez dans hello.c ceci (en respectant majuscules/minuscules !) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p15code82'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1582"><td class="code" id="p15code82"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// hello.c</span>
<span style="color: #339933;">#include &quot;stdio.h&quot;;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hello World !&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   getchar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Bon, ne vous effrayez pas, vous comprendrez tout ça ?. Maintenant, sous Dev-C++ faites Exécuter -&gt;Compiler et exécuter. Sous Visual C++, vous devez voir dans une barre d&#8217;outils &laquo;&nbsp;Win32 Debug&nbsp;&raquo; : changez ça en &laquo;&nbsp;Win32 Release&nbsp;&raquo;; ça permettra au compilateur de ne pas inclure d&#8217;informations de débogage dans l&#8217;exécutable final : votre .exe sera moins gros. Faites Build -&gt; Build Hello.exe, puis cliquez sur le point d&#8217;exclamation rouge pour commencer l&#8217;exécution de votre programme.</p>
<p style="text-align: justify;">Que fait votre programme? Il affiche dans une console MS-DOS (bien que le programme soit un programme Win32, je le rappelle) &laquo;&nbsp;Hello World !&nbsp;&raquo; puis attend que vous appuyez sur Entrée pour quitter. Aux utilisateurs de Visual C++ : Vous verrez écrit &laquo;&nbsp;Press any key to continue&nbsp;&raquo;, ceci est dû à l&#8217;environnement, si vous exécutez votre .exe depuis l&#8217;explorateur Windows ce message ne s&#8217;affiche pas.</p>
<p style="text-align: justify;">Bon, maintenant on passe à l&#8217;explication. Avant tout, il faut savoir que l&#8217;exécution du programme est séquentielle : les lignes que vous tapez sont des instructions, et celles-ci sont exécutées les unes après les autres, dans l&#8217;ordre dans lequel vous les avez écrit.</p>
<p style="text-align: justify;">Commençons par la 1ère ligne : &laquo;&nbsp;//Hello.c&nbsp;&raquo;. Vous pouvez très bien l&#8217;enlever, le programme se compilera de la même façon : c&#8217;est un commentaire. Vous pouvez marquer ce que vous voulez à la place de &laquo;&nbsp;Hello.c&nbsp;&raquo;, je marque cela juste pour connaître le nom du fichier. En C et en C++, tout ce qui suit &laquo;&nbsp;//&nbsp;&raquo; jusqu&#8217;à la fin de la ligne est un commentaire, de même que tout ce qui est placé entre &laquo;&nbsp;/*&nbsp;&raquo; et &laquo;&nbsp;*/&nbsp;&raquo; (sans les guillemets).</p>
<p style="text-align: justify;">Voyons la 2ème ligne: &laquo;&nbsp;#include&lt;stdio.h&gt;&nbsp;&raquo;. Cette ligne n&#8217;est pas vraiment une instruction : c&#8217;est une directive du préprocesseur comme toutes celles débutant par un #. Ne vous effrayez pas ! Bon, pour simplifier, on dira que c&#8217;est elle qui vous permet d&#8217;écrire printf et getchar par la suite sans provoquer d&#8217;erreur à la compilation. Je rentrerai dans les détails plus tard, pour l&#8217;instant sachez qu&#8217;il faut la placer en début de fichier.</p>
<p style="text-align: justify;">Maintenant, la 3ème ligne : &laquo;&nbsp;int main()&nbsp;&raquo;. Celle-ci dénote le début du bloc principal : c&#8217;est là que commencera l&#8217;exécution de votre programme, tout ce qui suit main() est exécuté en 1er. Un bloc d&#8217;instructions est délimité par { et }. Notre programme ne comporte qu&#8217;un seul bloc d&#8217;instructions.</p>
<p style="text-align: justify;">&laquo;&nbsp;printf(&laquo;&nbsp;Hello World !&nbsp;&raquo;);&nbsp;&raquo; : ceci est notre 1ère instruction. printf commande l&#8217;écriture à l&#8217;écran de texte. On dit que printf est une fonction, et que la ligne &laquo;&nbsp;printf(&laquo;&nbsp;Hello World !&nbsp;&raquo;);&nbsp;&raquo; est un appel à la fonction printf. Un appel de fonction est toujours composé du nom de la fonction (printf), d&#8217;une parenthèse ouvrante, d &#8216; &laquo;&nbsp;argument(s)&nbsp;&raquo; (le &laquo;&nbsp;Hello World !&nbsp;&raquo;) et d&#8217;une parenthèse fermante. Et le point-virgule? Il délimite la fin d&#8217;une instruction. L&#8217;oubli d&#8217;un point-virgule est une erreur très fréquente en programmation en C, et elle est dure à repérer pour les débutants : faites attention !</p>
<p style="text-align: justify;">&nbsp;&raquo; getchar();&nbsp;&raquo; : ceci est un autre appel à une fonction, la fonction &laquo;&nbsp;getchar&nbsp;&raquo;. Vous remarquerez qu&#8217;on ne lui passe pas d&#8217;arguments, car elle n&#8217;en a pas besoin; c&#8217;est elle qui attend l&#8217;appui sur la touche Entrée. En effet, recompilez votre programme sans cette ligne (mettez-la en commentaire) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p15code83'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1583"><td class="code" id="p15code83"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// hello.c</span>
<span style="color: #339933;">#include &quot;stdio.h&quot;;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span>
<span style="color: #009900;">&#123;</span>
   <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hello World !&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">//  getchar();    // La ligne est mise en commentaire, elle n'est pas compilée.</span>
   <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">A l&#8217;exécution du programme (hors IDE, je veux dire pour les utilisateurs de VC++, ouvrez votre exécutable depuis l&#8217;explorateur Windows), le programme quitte avant que vous ayez pu lire quoi que ce soit ! Voilà pourquoi il vous faut rajouter l&#8217;appel à la fonction getchar().</p>
<p style="text-align: justify;">Enfin, le &laquo;&nbsp;return 0;&nbsp;&raquo;, placé dans le bloc main(), indique la sortie du programme (il quitte). Si vous le placez avant getchar() par exemple, getchar() ne sera pas exécuté car le programme aura quitté avant. Le } délimite la fin du bloc main (principal).</p>
<p style="text-align: justify;">Ouf ! Voilà, vous avez terminé le 1er tutorial sur la programmation en C, maintenant essayez de changer l&#8217;ordre des lignes, de rajouter des appels à printf avec un texte différent (à oui, au fait, j&#8217;ai oublié pour les guillemets dans printf : ils montrent que l&#8217;argument passé à printf est une chaîne de caractères, un texte quoi, vous verrez ça plus en détail + tard, encore une fois <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</p>
<p style="text-align: justify;">Pour toute remarque, conseil, correction : funto66 at gmail.com <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<blockquote>
<p style="text-align: justify;">Cet article provient du tutorial publié par Funto le 30/07/2005 sur l&#8217;ancien site de Coder-Studio.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/les-bases-du-langage-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La factory</title>
		<link>http://www.coder-studio.com/blog/la-factory/</link>
		<comments>http://www.coder-studio.com/blog/la-factory/#comments</comments>
		<pubDate>Tue, 21 Dec 2004 17:41:22 +0000</pubDate>
		<dc:creator>twxs</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[factory]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=164</guid>
		<description><![CDATA[La Factory, brrr
Dans ce tutorial, je vais tenter d&#8217;aborder le design pattern factory (fabrique pour les anglophobes).
A mon habitude, nous allons retrouver la même ligne directrice que pour les précédents tutoriaux.
Je vais commencer par expliquer brièvement le principe de la factory, ensuite en découlera une première implémentation en C++ et enfin on essayera de rendre [...]]]></description>
			<content:encoded><![CDATA[<p><strong>La Factory, brrr</strong></p>
<p style="text-align: justify;">Dans ce tutorial, je vais tenter d&#8217;aborder le design pattern factory (fabrique pour les anglophobes).<br />
A mon habitude, nous allons retrouver la même ligne directrice que pour les précédents tutoriaux.<br />
Je vais commencer par expliquer brièvement le principe de la factory, ensuite en découlera une première implémentation en C++ et enfin on essayera de rendre ça le plus générique possible.</p>
<p style="text-align: justify;"><span id="more-164"></span></p>
<h2>Definition</h2>
<p style="text-align: justify;">La factory est en fait un objet dont le rôle est de créer des instances d&#8217;autres objets.<br />
Dans un modeleur par exemple, on pourrait avoir une factory d&#8217;objets géométriques qui servirait à créer des sphères, cônes, etc&#8230;</p>
<h2>Première Implémentation :</h2>
<p style="text-align: justify;">Nous allons prendre le cas d&#8217;une factory d&#8217;objets géométriques dont le but est de fournir des objets héritant de l&#8217;interface Shape.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code97'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16497"><td class="code" id="p164code97"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">De plus, nous avons dans l&#8217;application des objets implémentant l&#8217;interface shape comme Sphere, Cone, &#8230;.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code98'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16498"><td class="code" id="p164code98"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Sphere <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> Cone   <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Une premiere implémentation de la factory pourrait donner ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code99'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16499"><td class="code" id="p164code99"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> ShapeFactory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  Shape <span style="color: #000040;">*</span> createSphere<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  Shape <span style="color: #000040;">*</span> createCone<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Cone<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ce qui donne à l&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code100'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164100"><td class="code" id="p164code100"><pre class="cpp" style="font-family:monospace;">ShapeFactory factory<span style="color: #008080;">;</span>
&nbsp;
Shape <span style="color: #000040;">*</span> sphere <span style="color: #000080;">=</span> factory.<span style="color: #007788;">createSphere</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sphere<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>display<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Cette première approche fonctionne, mais a le désavantage de rendre le code de la factory dépendant de l&#8217;application.<br />
Nous allons tenter de définir la factory de manière générique (template <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) afin de pouvoir la réutiliser dans d&#8217;autres cas.</p>
<h2>On templatise un peu ?</h2>
<p style="text-align: justify;">On peut voir la factory comme une map : à une clef donnée, on associe un type d&#8217;objet a créer.</p>
<p style="text-align: justify;">On devrait donc avoir au niveau des paramètres de la factory générique, le type de la clef et le type d&#8217;objet que la factory retourne. Ceci nous donne le prototype suivant :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code101'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164101"><td class="code" id="p164code101"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Et à  l&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code102'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164102"><td class="code" id="p164code102"><pre class="cpp" style="font-family:monospace;">Factory shapeFactory<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">De plus, on s&#8217;attend à pouvoir écrire quelque chose du genre :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code103'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164103"><td class="code" id="p164code103"><pre class="cpp" style="font-family:monospace;">Shape <span style="color: #000040;">*</span>sphere <span style="color: #000080;">=</span> shapeFactory.<span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">On enrichit donc notre esquisse de la classe  :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code104'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164104"><td class="code" id="p164code104"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  Object <span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Pour le corps de la méthode create, nous avons besoin de réellement créer une instance d&#8217;un objet que la factory ne connait pas. Comme ceci ne peut pas se faire par magie, il va falloir enregistrer dans la factory une fonction capable de créer chaque objet et les associer à une clef.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code105'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164105"><td class="code" id="p164code105"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
<span style="color: #666666;">// un pointeur de fonction qui retourne un Object*</span>
  <span style="color: #0000ff;">typedef</span> Object <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>Creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
  map _registeredCreator<span style="color: #008080;">;</span>
&nbsp;
  <span style="color: #0000ff;">bool</span> <span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span>Key key, Creator creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>_registeredCreator.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> _registeredCreator.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span> <span style="color: #666666;">// la clef est deja utilisé</span>
    _registeredCreator.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span>pair<span style="color: #008000;">&#40;</span>key, creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  Object <span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span>Key key<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    Object <span style="color: #000040;">*</span>object<span style="color: #008080;">;</span>
    Creator creator<span style="color: #008080;">;</span>
    map<span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// on cherche le pointeur de fonction associé a la clef</span>
    it <span style="color: #000080;">=</span> _registeredCreator.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>it <span style="color: #000080;">==</span> _registeredCreator.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// on ne l'a pas trouvé</span>
&nbsp;
    <span style="color: #666666;">// on récupère le pointeur de fonction</span>
    creator <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>it<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">second</span><span style="color: #008080;">;</span>
    <span style="color: #666666;">// on appelle la fonction pour créer un nouvel objet</span>
    object <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #666666;">// on retourne l'objet</span>
    <span style="color: #0000ff;">return</span> object<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Regardons maintenant comment utiliser tout ça :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code106'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164106"><td class="code" id="p164code106"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// des fonctions de création d'objets</span>
Shape <span style="color: #000040;">*</span>createSphere<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
Shape <span style="color: #000040;">*</span>createCone<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Cone<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
&nbsp;
Factory shapeFactory<span style="color: #008080;">;</span>
shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span>, createSphere<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Cone&quot;</span>, createCone<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
Shape <span style="color: #000040;">*</span>sphere <span style="color: #000080;">=</span> shapeFactory.<span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ici le problème reste la nécessité d&#8217;avoir des fonctions &laquo;&nbsp;C&nbsp;&raquo; à mettre dans le code, et de devoir enregistrer ces fonctions à la main. Donc à chaque ajout d&#8217;objet géométrique devoir aller remodifier ce code d&#8217;initialisation de la factory.</p>
<p style="text-align: justify;">Pour rendre ceci un peu plus propre, nous allons définir ces fonctions en statique dans chaque objet géométrique et se servir de l&#8217;initialisation des CRT pour enregistrer les fonctions automatiquement.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code107'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164107"><td class="code" id="p164code107"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// sphere.h</span>
<span style="color: #0000ff;">class</span> Sphere <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">static</span> Shape<span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> <span style="color: #0000ff;">register</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code108'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164108"><td class="code" id="p164code108"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// sphere.pp</span>
<span style="color: #339900;">#include &quot;ShapeFactory.h&quot; // on considère que la shapeFactory est une variable globale accessible par ce fichier</span>
&nbsp;
Shape <span style="color: #000040;">*</span> Shpere<span style="color: #008080;">::</span><span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #666666;">// auto enregistrement :</span>
<span style="color: #0000ff;">bool</span> Sphere<span style="color: #008080;">::</span><span style="color: #0000ff;">register</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span>, Sphere<span style="color: #008080;">::</span><span style="color: #007788;">create</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Il est possible d&#8217;utiliser des macros pour encore réduire la taille du code à produire.</p>
<p style="text-align: justify;">Petite explication : au lancement du programme, la variable statique register est initialisée. Cette initialisation passe par l&#8217;appel de la methode shapeFactory::register qui enregistre le &laquo;&nbsp;create&nbsp;&raquo;.</p>
<h2>Conlusion:</h2>
<p style="text-align: justify;">J&#8217;ai ici présenté l&#8217;implémentation &laquo;&nbsp;générique&nbsp;&raquo; d&#8217;une factory; pour pousser un peu plus l&#8217;exemple du modeleur, on peut imaginer que l&#8217;interface Shape permette de décrire des attributs (association nom / valeur). Une sphère par exemple aura un paramètre de type float nommé &laquo;&nbsp;radius&nbsp;&raquo;.<br />
Notre petite application graphique aura à parcourir les entrées de la factory pour y découvrir tous les objets &laquo;&nbsp;instanciables&nbsp;&raquo; et fournir à l&#8217;utilisateur un panel de boutons pour créer des Shapes.<br />
A partir de là, à chaque Shape créé, elle pourra construire une boîte de dialogue d&#8217;édition adaptée à l&#8217;objet (à la mode 3DS), SANS en connaitre le type réel.</p>
<h2>Pour aller plus loin :</h2>
<p style="text-align: justify;">Il est possible de s&#8217;abstraire de l&#8217;écriture de la fonction create statique dans les classes en utilisant les templates pour créer des objets dont le rôle est de remplacer la fonction statique.</p>
<p style="text-align: justify;">A l&#8217;utilisation cela donne quelque chose comme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code109'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p164109"><td class="code" id="p164code109"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Shape<span style="color: #008080;">::</span><span style="color: #0000ff;">register</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span> <span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Shape&quot;</span>, Creator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Il faut pour cela modifier un peu la classe factory, mais je vous le laisse en exercice <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  (j&#8217;ai toujours révé de dire ça un jour&#8230;)</p>
<p style="text-align: justify;">Dernier point, on peut utiliser les singleton pour ne pas avoir à stocker la factory dans une variable globale.</p>
<p><span style="color: #ff0000;"><strong>joyeuses fetes <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></span></p>
<p><strong>Twxs</strong></p>
<blockquote><p>Cet article provient du tutorial publié par Twxs le 24/12/2004 sur l&#8217;ancien site de Coder-Studio.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/la-factory/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Le design pattern Observer/Observable en C++</title>
		<link>http://www.coder-studio.com/blog/le-design-pattern-observer-observable-en-c/</link>
		<comments>http://www.coder-studio.com/blog/le-design-pattern-observer-observable-en-c/#comments</comments>
		<pubDate>Wed, 03 Nov 2004 17:32:25 +0000</pubDate>
		<dc:creator>twxs</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[design pattern]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=156</guid>
		<description><![CDATA[Ce tutorial a pour but de proposer une implementation en C++ du patron de conception Observer / Observable. Comme il s&#8217;agit a la base d&#8217;un patron de conception, il en existe par definition beaucoup d&#8217;implementations specifiques au domaine.
Ici nous allons proposer une implementation &#171;&#160;generique&#160;&#187; qui sera utilisable dans la majorite des cas.

Introduction
La relation Observer/Observable est [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ce tutorial a pour but de proposer une implementation en C++ du patron de conception Observer / Observable. Comme il s&#8217;agit a la base d&#8217;un patron de conception, il en existe par definition beaucoup d&#8217;implementations specifiques au domaine.<br />
Ici nous allons proposer une implementation &laquo;&nbsp;generique&nbsp;&raquo; qui sera utilisable dans la majorite des cas.</p>
<p><span id="more-156"></span></p>
<h2>Introduction</h2>
<p style="text-align: justify;">La relation Observer/Observable est un concept assez simple, le principe repose sur le fait de pouvoir informer automatiquement des objets (Observeurs) des modification d&#8217;un autre (l&#8217;Observable). Nous prendrons comme cas &laquo;&nbsp;d&#8217;école&nbsp;&raquo; l&#8217;exemple d&#8217;un VU mètre system. On supposera avoir une classe <span style="color: #ff0000;">CPU </span>permettant de connaitre la charge cpu, une classe <span style="color: #ff0000;">FileSystem</span> donnant accès aux informations concernant les disques et enfin, une classe charger d&#8217;afficher l&#8217;état de notre machine i.e. la charge CPU et l&#8217;occupation des disques.</p>
<p style="text-align: justify;"><strong>La classe Observer</strong><br />
L&#8217;observer est un objet &laquo;&nbsp;simple&nbsp;&raquo;, être observeur defini uniquement le fait de pouvoir être mis a jour par un objet extérieur. Ceci se traduit par avoir une méthode de type <span style="color: #ff0000;">update</span>.<br />
Ceci nous mène à une premiere définition de l&#8217;interface Observer :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code121'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156121"><td class="code" id="p156code121"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">struct</span> Observer <span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Rendre un objet observateur d&#8217;un sujet, se traduira alors par une implémentation de cette interface. ex :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code122'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156122"><td class="code" id="p156code122"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> VUMeter <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Observer <span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// mis a jour car un sujet a changé d'etat</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">La première limitation de cette proposition vient du fait que l&#8217;on ne prend pas en compte le type du sujet observe dans l&#8217;interface. Ceci a l&#8217;utilisation, obligera en plus d&#8217;hériter de l&#8217;interface, de stocker dans ses attributs une référence au sujet. ex :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code123'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156123"><td class="code" id="p156code123"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> VUMeter <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Observer<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">private</span> <span style="color: #008080;">:</span>
  Subject <span style="color: #000040;">*</span>subjet<span style="color: #008080;">;</span>
<span style="color: #0000ff;">public</span> <span style="color: #008080;">:</span>
  <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #666666;">// subject a change</span>
    subject<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getValues<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>...
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">une première solution, est de passer en paramètre la classe Observable dans la méthode update.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code124'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156124"><td class="code" id="p156code124"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>Observable <span style="color: #000040;">*</span>subject<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
  <span style="color: #666666;">//</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">cette solution est presque viable, mais va obliger :</p>
<ul>
<li> soit a implementer dans l&#8217;observable, une interface generique pour récuperer les information d&#8217;un sujet &laquo;&nbsp;abstrait&nbsp;&raquo;. Il nous faudra récuperer la charge CPU, l&#8217;occupation du disque&#8230;</li>
<li> soit a &laquo;&nbsp;dynamic_caster&nbsp;&raquo; le sujet de type Observable en son reel type</li>
</ul>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code125'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156125"><td class="code" id="p156code125"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>Observable <span style="color: #000040;">*</span>subjet<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>CPU <span style="color: #000040;">*</span>cpu <span style="color: #000080;">=</span> <span style="color: #0000ff;">dynamic_cast</span><span style="color: #008000;">&#40;</span>subject<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
     cpu<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getLoad<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>...
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>FileSystem<span style="color: #000040;">*</span> fs <span style="color: #000080;">=</span> <span style="color: #0000ff;">dynamic_cast</span><span style="color: #008000;">&#40;</span>subject<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    fs<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getFreeSpace<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Cette solution n&#8217;est pas des plus élegantes. Une derniere alternative plus &laquo;&nbsp;propre&nbsp;&raquo; serait de posseder une méthode update prenant en paremetre un CPU* et une autre prenant un FileSystem*</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code126'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156126"><td class="code" id="p156code126"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>FileSystem<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>CPU<span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Cette solution nous garantie une separation propre du code. Pour l&#8217;implementer, nous allons devoir passer par l&#8217;utilisation de template. Le principe : spécifier le type reel observé dans l&#8217;interface <span style="color: #ff0000;">Observer</span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code127'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156127"><td class="code" id="p156code127"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>
<span style="color: #0000ff;">struct</span>  Observer<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>Subject <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Et voici maintenant l&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code128'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156128"><td class="code" id="p156code128"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> VUMeter <span style="color: #008080;">:</span>
  <span style="color: #0000ff;">public</span> Observer,
  <span style="color: #0000ff;">public</span> Observer<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>FileSystem<span style="color: #000040;">*</span> fs<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    fs<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getFreeSpace<span style="color: #008000;">&#40;</span>...
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">void</span> update<span style="color: #008000;">&#40;</span>CPU<span style="color: #000040;">*</span> cpu<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    cpu<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>...
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Et voila le travail, nous avons un observeur capable d&#8217;observer plusieurs sujets. Ils nous reste a implémenter l&#8217;autre partie : l&#8217;<strong>Observable</strong></p>
<p style="text-align: justify;"><strong>La classe Observable</strong><br />
Nous devons ici definir la classe de laquelle vont deriver CPU et FileSystem pour être observable. Les besoins d&#8217;un Observable sont :</p>
<ul>
<li> lui attacher un observateur</li>
<li> le détacher</li>
<li> notifier tous les observateurs</li>
<li> stocker ses observateurs</li>
</ul>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code129'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156129"><td class="code" id="p156code129"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Observable<span style="color: #008000;">&#123;</span>
  std<span style="color: #008080;">::</span><span style="color: #007788;">set</span> _observers<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">void</span> attach<span style="color: #008000;">&#40;</span>Observer <span style="color: #000040;">*</span>o<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// insertion dans le set</span>
  <span style="color: #0000ff;">void</span> detach<span style="color: #008000;">&#40;</span>Observer <span style="color: #000040;">*</span>o<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// suppression du set</span>
  <span style="color: #0000ff;">void</span> notify<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// updater tous les observers dans le set</span>
    ...
      <span style="color: #007788;">obs</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>update<span style="color: #008000;">&#40;</span>...<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Cette implémentation ne fonctionne pas a cause de la &laquo;&nbsp;templatisation&nbsp;&raquo; de la class Observer qui prend, déjà, pour la méthode update le type réel du sujet (ex : FileSystem) mais aussi par le fait que les observeurs n&#8217;héritent pas de Observer, mais Observer.<br />
Dans la classe Obserable, nous devons donc connaitre le type reel du sujet.<br />
Encore une fois les template vont permettre de nous en sortir :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code130'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156130"><td class="code" id="p156code130"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Observable
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  ~Observable<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">void</span> attach<span style="color: #008000;">&#40;</span>Observer <span style="color: #000040;">*</span>o<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">void</span> detach<span style="color: #008000;">&#40;</span>Observer <span style="color: #000040;">*</span>o<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">void</span> notify<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
  std<span style="color: #008080;">::</span><span style="color: #007788;">set</span><span style="color: #000080;">&lt;</span>Observer <span style="color: #000040;">*</span><span style="color: #000080;">&gt;</span> _observers<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>A l&#8217;utilisation, ceci donne :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p156code131'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p156131"><td class="code" id="p156code131"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> FileSystem <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Observable<span style="color: #008000;">&#123;</span>
   ...
   <span style="color: #0000ff;">void</span> some_func<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
     ...
     <span style="color: #007788;">notify</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// on change d'etat, informer les observateurs</span>
   <span style="color: #008000;">&#125;</span>
   ...
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
VUMeter vum<span style="color: #008080;">;</span>
&nbsp;
FileSystem fs<span style="color: #008080;">;</span>
CPU cpu<span style="color: #008080;">;</span>
&nbsp;
cpu.<span style="color: #007788;">attach</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>vum<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
fs.<span style="color: #007788;">attach</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>vum<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Et Voilà, c&#8217;est fini!</p>
<blockquote><p>Cet article provient du tutorial publié par Twxs le 03/11/2004 sur l&#8217;ancien site de Coder-Studio.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/le-design-pattern-observer-observable-en-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introduction des RAII en OpenGL</title>
		<link>http://www.coder-studio.com/blog/introduction-des-raii-en-opengl/</link>
		<comments>http://www.coder-studio.com/blog/introduction-des-raii-en-opengl/#comments</comments>
		<pubDate>Sun, 03 Oct 2004 17:07:45 +0000</pubDate>
		<dc:creator>twxs</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[RAII]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=137</guid>
		<description><![CDATA[Ce tutoriel introduit l&#8217;utilisation des RAII (Ressource Aquisition Is Initialisation) en OpenGL. Un point clef en opengl est de conserver la &#171;&#160;machine à états&#160;&#187; propre. L&#8217;utilisation de RAII va permettre de faciliter cette gestion et également de clarifier le code.
Prenons un exemple:

?View Code CglEnable&#40;flag&#41;;
....
glDisable&#40;flag&#41;;

C&#8217;est ici l&#8217;utilisation normale d&#8217;opengl. Rien de compliqué mais c&#8217;est exactement ce [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Ce tutoriel introduit l&#8217;utilisation des RAII (Ressource Aquisition Is Initialisation) en OpenGL. Un point clef en opengl est de conserver la &laquo;&nbsp;machine à états&nbsp;&raquo; propre. L&#8217;utilisation de RAII va permettre de faciliter cette gestion et également de clarifier le code.</p>
<p><span id="more-137"></span>Prenons un exemple:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code143'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137143"><td class="code" id="p137code143"><pre class="c" style="font-family:monospace;">glEnable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
....
<span style="color: #202020;">glDisable</span><span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">C&#8217;est ici l&#8217;utilisation normale d&#8217;opengl. Rien de compliqué mais c&#8217;est exactement ce qu&#8217;on veut éviter pour ne pas alourdir le code&#8230;</p>
<h2>Un premier pas vers le RAII</h2>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code144'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137144"><td class="code" id="p137code144"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> Enable<span style="color: #009900;">&#123;</span>
   Enable<span style="color: #009900;">&#40;</span>GLenum flag<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      glEnable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   ~Enable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      glDisable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Puis on l&#8217;utilise dans un bloc, comme suit :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code145'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137145"><td class="code" id="p137code145"><pre class="c" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   Enable active<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   ...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Comme on peut le voir ici, Le principe est très simple : Lors de la création de l&#8217;instance de la structure Enable, on execute via le constructeur la commande opengl glEnable(). Lorsque l&#8217;on sort de la zone de portée de cette instance (ici, le bloc {}), elle est détruite. Il y a donc appel du destructeur dans lequel on a placé la commande glDisable().</p>
<h2>Conservation et propreté</h2>
<p style="text-align: justify;">Cette première version fonctionne, mais imaginons qu&#8217;avant le bloc le flag soit deja activé : à la sortie il sera desactivé. Pour s&#8217;assurer de la récuperation d&#8217;un contexte identique, nous devons modifier notre classe pour mémoriser l&#8217;etat courant avant sa modification.</p>
<p>On procède de cette manière :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code146'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137146"><td class="code" id="p137code146"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> Enable <span style="color: #009900;">&#123;</span>
&nbsp;
   GLboolean state<span style="color: #339933;">;</span>
   Enable<span style="color: #009900;">&#40;</span>GLenum flag<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      state <span style="color: #339933;">=</span> glIsEnable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// State contient l'état actuel du flag</span>
      <span style="color: #666666; font-style: italic;">// Si le flag est deja activé il n'est pas necessaire de le réactiver</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>state<span style="color: #009900;">&#41;</span>
         glEnable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   ~Enable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// Si le flag était désactivé à la création de la classe on le désactive à nouveau</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>state<span style="color: #009900;">&#41;</span>
         glDisable<span style="color: #009900;">&#40;</span>flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ici nous sommes : L&#8217;utilisation de l&#8217;objet conserve le contexte opengl.</p>
<h2>Cas d&#8217;usage : factorisation du code à l&#8217;aide des templates</h2>
<p>Prenons le cas suivant :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code147'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137147"><td class="code" id="p137code147"><pre class="c" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   Enable lighting<span style="color: #009900;">&#40;</span>GL_LIGHTING<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   Enable light0<span style="color: #009900;">&#40;</span>GL_LIGHT0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   Enable depth<span style="color: #009900;">&#40;</span>GL_DEPTH_TEST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">// ...code</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Supposons que ces trois appels reviennnent régulierement : l&#8217;héritage multiple devrait nous permettre de factoriser ce code en regroupant le tout en une seule et même classe. Mais le probleme ici, c&#8217;est que nous avons une unique classe pour tous les états. Comme nous ne pouvons pas heriter plusiseurs fois de la même classe, il va falloir trouver une autre solution.</p>
<p style="text-align: justify;">Et celle qui s&#8217;y prête le mieux reste l&#8217;utilisation de templates :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code148'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137148"><td class="code" id="p137code148"><pre class="c" style="font-family:monospace;">template <span style="color: #993333;">struct</span> Enable <span style="color: #009900;">&#123;</span>
   GLboolean state<span style="color: #339933;">;</span>
   Enable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">//plus de paramètre au constructeur</span>
      state <span style="color: #339933;">=</span> glIsEnable<span style="color: #009900;">&#40;</span>Flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// state contiend l'etat actuel du flag</span>
      <span style="color: #666666; font-style: italic;">// si le flag est deja active il 'est pas necessaire de le reactiver</span>
&nbsp;
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>state<span style="color: #009900;">&#41;</span>
          glEnable<span style="color: #009900;">&#40;</span>Flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   ~Enable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>state<span style="color: #009900;">&#41;</span>
      glDisable<span style="color: #009900;">&#40;</span>Flag<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">En &laquo;&nbsp;templetant&nbsp;&raquo; la classe Enable, nous obtenons une classe différente pour chaque paramètre du template, et donc pour chaque flag.</p>
<p style="text-align: justify;">Au niveau de l&#8217;utilisation,</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code149'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137149"><td class="code" id="p137code149"><pre class="c" style="font-family:monospace;">Enable depth<span style="color: #009900;">&#40;</span>GL_DEPTH_TEST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>deviendra :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code150'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137150"><td class="code" id="p137code150"><pre class="c" style="font-family:monospace;">Enable depth<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Mais surtout, ceci va nous permettre de factoriser des états.<br />
Reprenons les trois appels redondant de notre programme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code151'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137151"><td class="code" id="p137code151"><pre class="c" style="font-family:monospace;">Enable lighting<span style="color: #339933;">;</span>
Enable light0<span style="color: #339933;">;</span>
Enable depth<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>En templatant, on peut créer une structure héritant de chaque classe :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code152'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137152"><td class="code" id="p137code152"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> MonContext <span style="color: #339933;">:</span>
   Enable <span style="color: #339933;">,</span>
   Enable <span style="color: #339933;">,</span>
   Enable
<span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Nous obtenons une structure ayant les propriétés de 3 classes parents. Et surtout, à la creation de l&#8217;objet les 3 constructeurs des parents seront appelés, et réciproquement à la destruction.<br />
On peut donc se contenter de ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p137code153'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p137153"><td class="code" id="p137code153"><pre class="c" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   MonContext ctx_light<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Conclusion</h2>
<p>Voilà pour l&#8217;utilisation des RAII : Rien de très complexe dans la théorie ou dans la pratique. C&#8217;est par contre un puissant outil qui devrait rapidement devenir indispensable à la clarté de tout programme conséquent.<br />
<strong>Un grand merci à Twxs pour ce tuto !</strong></p>
<blockquote><p>Cet article provient du tutorial publié par Twxs le 03/10/2004 sur l&#8217;ancien site de Coder-Studio.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/introduction-des-raii-en-opengl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
