<!-- iframe showing the search results (closed by default) -->
<divid="MSearchResultsWindow">
<iframesrc="javascript:void(0)"frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
</div><!-- top -->
<divclass="header">
<divclass="headertitle">
<divclass="title">Tutorial </div></div>
</div><!--header-->
<divclass="contents">
<divclass="toc"><h3>Table of Contents</h3>
<ul><liclass="level1"><ahref="#esignal_declare">Declare a Signal: </a></li>
<liclass="level1"><ahref="#esignal_connection">Connecting on a signal </a><ul><liclass="level2"><ahref="#esignal_connection_base">Connection and basic emition </a></li>
<liclass="level2"><ahref="#esignal_connection_class">Connection on class member function </a></li>
<liclass="level2"><ahref="#esignal_connection_shared">Connection on ememory::SharedPtr<class> member function </a></li>
</ul>
</li>
<liclass="level1"><ahref="#esignal_create">Create new Signal </a></li>
<p>Declaring a signal is really simple, just include the esignal file:</p>
<divclass="fragment"><divclass="line"><spanclass="preprocessor">#include <esignal/Signal.hpp></span></div></div><!-- fragment --><p> You can now declare your signals. We have basicly declare some basic signal type:</p><ul>
<li>void</li>
<li>bool</li>
<li>std::string / std::u32string</li>
<li>int8_t / int16_t / int32_t / int64_t</li>
<li>uint8_t / uint16_t / uint32_t / uint64_t</li>
<li>float / double</li>
<li>vec2 / bvec2 / ivec2 / uivec2</li>
<li>vec3 / bvec3 / ivec3 / uivec3</li>
<li>etk::Color<unsigned char,4></li>
<li>etk::Color<unsigned char,3></li>
<li>etk::Color<float,4></li>
<li>etk::Color<float,3></li>
</ul>
<p>To declare a signal with 'void' type: </p><divclass="fragment"><divclass="line"> esignal::Signal<> signalVoid;</div></div><!-- fragment --><p> To declare a signal with 'int32_t' type: </p><divclass="fragment"><divclass="line"> esignal::Signal<int32_t> signalInt;</div></div><!-- fragment --><p> To declare a signal with 'string' type: </p><divclass="fragment"><divclass="line"> esignal::Signal<std::string> signalString;</div></div><!-- fragment --><h1><aclass="anchor"id="esignal_connection"></a>
Connecting on a signal </h1>
<p>We have some way to connect on a signals depending on where we do the connection.</p>
<p>Declare the signal: </p><divclass="fragment"><divclass="line"> esignal::Signal<int32_t> signalValue;</div></div><!-- fragment --><p> Declare a generic fuction: </p><divclass="fragment"><divclass="line"><spanclass="keywordtype">void</span> localCallBack(int32_t _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback Local the value is : "</span><< _val);</div><divclass="line">}</div></div><!-- fragment --><p> Connect a generic function: </p><divclass="fragment"><divclass="line"> esignal::Connection con1 = signalValue.connect(&localCallBack);</div></div><!-- fragment --><p> Or simply connect a lambda function: </p><divclass="fragment"><divclass="line"> esignal::Connection con2 = signalValue.connect(</div><divclass="line"> [](int32_t _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback 1 the value is : "</span><< _val);</div><divclass="line"> });</div></div><!-- fragment --><p> And now, we can emit a simple signal: </p><divclass="fragment"><divclass="line"> signalValue.emit(1001001);</div></div><!-- fragment --><p> You can see that all connection return a esignal::Connection value. This is an handle that can not be copiable, but only movable, While this handle is alive, the connection is allive too. The to remove a connection, we only need to remive the handle or call the esignal::Connection::disconnect fucntion.</p>
<p>To disconnect a signal, it is very simple: </p><divclass="fragment"><divclass="line"> con1.disconnect();</div></div><!-- fragment --><p>This Will generate this simple sample code: </p><divclass="fragment"><divclass="line"><spanclass="keywordtype">void</span> localCallBack(int32_t _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback Local the value is : "</span><< _val);</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> basicConnection() {</div><divclass="line"><spanclass="comment">// Create the signal</span></div><divclass="line"><spanclass="comment"></span> esignal::Signal<int32_t> signalValue;</div><divclass="line"><spanclass="comment">// Connect the signal function</span></div><divclass="line"><spanclass="comment"></span> esignal::Connection con1 = signalValue.connect(&localCallBack);</div><divclass="line"><spanclass="comment">// Connect the signal Lambda</span></div><divclass="line"><spanclass="comment"></span> esignal::Connection con2 = signalValue.connect(</div><divclass="line"> [](int32_t _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback 1 the value is : "</span><< _val);</div><divclass="line"> });</div><divclass="line"><spanclass="comment">// Emit the signal</span></div><divclass="line"><spanclass="comment"></span> signalValue.emit(1001001);</div><divclass="line"><spanclass="comment">// Disconnect the connection n°1</span></div><divclass="line"><spanclass="comment"></span> con1.disconnect();</div><divclass="line"><spanclass="comment">// Second emit to check disconnection</span></div><divclass="line"> signalValue.emit(2002002);</div><divclass="line">}</div></div><!-- fragment --><h2><aclass="anchor"id="esignal_connection_class"></a>
Connection on class member function </h2>
<p>Declare class fuction: </p><divclass="fragment"><divclass="line"><spanclass="keyword">class </span>TmpClass {</div><divclass="line"><spanclass="keyword">public</span>:</div><divclass="line"><spanclass="keywordtype">void</span> localCallBack(<spanclass="keyword">const</span> int32_t& _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback Local the value is : "</span><< _val);</div><divclass="line"> }</div><divclass="line"><spanclass="keywordtype">void</span> localCallBackSecond(<spanclass="keyword">const</span> int32_t& _val, <spanclass="keyword">const</span> std::string& _otherValue) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback 2 Local the value is : "</span><< _val <<<spanclass="stringliteral">" with perso: '"</span><< _otherValue <<<spanclass="stringliteral">"'"</span>);</div><divclass="line"> }</div><divclass="line">};</div></div><!-- fragment --><p> For direct connection, you need to have a 'const ref' on the parameter (internal helper design) to bind on the signal</p>
<p>Now you can nonnect the functions: </p><divclass="fragment"><divclass="line"> esignal::Connection con1 = signalValue.connect(&myClass, &TmpClass::localCallBack);</div><divclass="line"> esignal::Connection con2 = signalValue.connect(&myClass, &TmpClass::localCallBackSecond, <spanclass="stringliteral">"Hello, HowAreYou"</span>);</div></div><!-- fragment --><p> This Will generate this simple sample code: </p><divclass="fragment"><divclass="line"><spanclass="keyword">class </span>TmpClass {</div><divclass="line"><spanclass="keyword">public</span>:</div><divclass="line"><spanclass="keywordtype">void</span> localCallBack(<spanclass="keyword">const</span> int32_t& _val) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback Local the value is : "</span><< _val);</div><divclass="line"> }</div><divclass="line"><spanclass="keywordtype">void</span> localCallBackSecond(<spanclass="keyword">const</span> int32_t& _val, <spanclass="keyword">const</span> std::string& _otherValue) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"Callback 2 Local the value is : "</span><< _val <<<spanclass="stringliteral">" with perso: '"</span><< _otherValue <<<spanclass="stringliteral">"'"</span>);</div><divclass="line"> }</div><divclass="line">};</div><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> classConnection() {</div><divclass="line"><spanclass="comment">// Create the signal</span></div><divclass="line"> esignal::Signal<int32_t> signalValue;</div><divclass="line"><spanclass="comment">// Declare the class</span></div><divclass="line"> TmpClass myClass;</div><divclass="line"><spanclass="comment">// Connect signals</span></div><divclass="line"><spanclass="comment"></span> esignal::Connection con1 = signalValue.connect(&myClass, &TmpClass::localCallBack);</div><divclass="line"> esignal::Connection con2 = signalValue.connect(&myClass, &TmpClass::localCallBackSecond, <spanclass="stringliteral">"Hello, HowAreYou"</span>);</div><divclass="line"><spanclass="comment">// Emit sample signals</span></div><divclass="line"> signalValue.emit(4004004);</div><divclass="line">}</div><divclass="line"></div></div><!-- fragment --><h2><aclass="anchor"id="esignal_connection_shared"></a>
Connection on ememory::SharedPtr<class> member function </h2>
<p><aclass="elRef"doxygen="/home/heero/dev/perso/out/doc/release/ememory.tag:http://atria-soft.github.io/ememory/"href="http://atria-soft.github.io/ememory/classememory_1_1_shared_ptr.html">ememory::SharedPtr</a> have intrinsec knowledge of alive pointer, then, if you do not need to remove connection while the <aclass="elRef"doxygen="/home/heero/dev/perso/out/doc/release/ememory.tag:http://atria-soft.github.io/ememory/"href="http://atria-soft.github.io/ememory/classememory_1_1_shared_ptr.html">ememory::SharedPtr</a> is alive, just connect it like: </p><divclass="fragment"><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> sharedConnection() {</div><divclass="line"><spanclass="comment">// Create the signal</span></div><divclass="line"> esignal::Signal<int32_t> signalValue;</div><divclass="line"><spanclass="comment">// Declare the class</span></div><divclass="line"><aclass="codeRef"doxygen="/home/heero/dev/perso/out/doc/release/ememory.tag:http://atria-soft.github.io/ememory/"href="http://atria-soft.github.io/ememory/classememory_1_1_shared_ptr.html">ememory::SharedPtr<TmpClass></a> myClassShared = ememory::makeShared<TmpClass>();</div><divclass="line"><spanclass="comment">// Connect signals</span></div><divclass="line"> signalValue.connect(myClassShared, &TmpClass::localCallBack);</div><divclass="line"><spanclass="comment">// Emit sample signals</span></div><divclass="line"> signalValue.emit(7007007);</div><divclass="line">}</div></div><!-- fragment --><h1><aclass="anchor"id="esignal_create"></a>
Create new Signal </h1>
<p>If the signal is not in the list: <aclass="el"href="esignal_tutorial.html#esignal_declare">Declare a Signal: </a>, you need to declare it yourself. This is due to optimise the compilation time, in C++ when we inserte many template with all the implementation, the compilation time increase, the we decide to optimise the build time.</p>
<p>Create a new custum signal: </p><divclass="fragment"><divclass="line"> esignal::Signal<int32_t, std::string> signalCustum;</div></div><!-- fragment --><p> Connect on the Signal: </p><divclass="fragment"><divclass="line"> esignal::Connection con2 = signalCustum.connect(</div><divclass="line"> [](int32_t _val, std::string _val2) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"lambda callback: "</span><< _val <<<spanclass="stringliteral">" vel2="</span><< _val2);</div><divclass="line"> });</div></div><!-- fragment --><p> Emit a Signal: </p><divclass="fragment"><divclass="line"> signalCustum.emit(1001001, <spanclass="stringliteral">"plop"</span>);</div></div><!-- fragment --><p> This might work good, but at this point the compilation is OK, but not the linking ==> we need to declare the implementation of the signal: </p><divclass="fragment"><divclass="line"><spanclass="preprocessor">#include <esignal/details/Signal.hxx></span></div><divclass="line">ESIGNAL_DECLARE_SIGNAL(int32_t, std::string);</div></div><!-- fragment --><p>This Will generate this simple sample code: </p><divclass="fragment"><divclass="line"></div><divclass="line"><spanclass="keywordtype">void</span> newSignal() {</div><divclass="line"><spanclass="comment">// Declare new signal</span></div><divclass="line"><spanclass="comment"></span> esignal::Signal<int32_t, std::string> signalCustum;</div><divclass="line"><spanclass="comment">// Connect a lambda</span></div><divclass="line"><spanclass="comment"></span> esignal::Connection con2 = signalCustum.connect(</div><divclass="line"> [](int32_t _val, std::string _val2) {</div><divclass="line"> TEST_PRINT(<spanclass="stringliteral">"lambda callback: "</span><< _val <<<spanclass="stringliteral">" vel2="</span><< _val2);</div><divclass="line"> });</div><divclass="line"><spanclass="comment">// Example emit</span></div><divclass="line"><spanclass="comment"></span> signalCustum.emit(1001001, <spanclass="stringliteral">"plop"</span>);</div><divclass="line">}</div><divclass="line"></div><divclass="line"><spanclass="comment">// do it in a single C++: Implementation of signal</span></div><divclass="line"><spanclass="comment"></span><spanclass="preprocessor">#include <esignal/details/Signal.hxx></span></div><divclass="line">ESIGNAL_DECLARE_SIGNAL(int32_t, std::string);</div><divclass="line"></div></div><!-- fragment --></div></div><!-- contents -->