<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Event Dispatcher &#x2F; Listener - Interface Stil ...]]></title><description><![CDATA[<p>Ich hatte grad eine Diskussion mit meinem Chef wie unser recht weit verbreitetes Event system überarbeitet werden sollte.<br />
Ausgangslage: Suboptimales System mit Dispatcher / Listener / Event Basisklasse, alle Event gehen als &quot;Event *&quot; raus und werden per dynamic_cast in den Listener in den &quot;richtigen&quot; Typ gecastet und verwendet wie gewünscht - oder verworfen. Unötiger overhead, bei entsprechender Eventvielfalt unübersichtlich ...</p>
<p>Nachdem wir nun überhaupt mal einig sind, dass das so Scheisse war will mein Chef jetzt ins andere extrem: Für jeden Furz ein eigener Event Typ, einen eigenen Event-callback( selbst wenn beim Event durch einen simplen enum kein Unterschied gemacht werden müsste ).<br />
Find ich beinahe genauso deppert wie die Variante davor. Wie seht ihr das? Code unten zur Illustration.</p>
<p>Ich glaub das &quot;Grundproblem&quot; ist das mein Chef einfache Regeln und klare Vorgaben so gern hat. Hauptsache niemand macht sich irgendwelche Gedanken wenn er ein Interface entwirft ....</p>
<pre><code class="language-cpp">class SomeOtherObject
{
	//... something
};

class EventA
{
public:
	enum EventTypeA
	{
		Type1,
		Type2,
		Type3,
		Type4,
		Type5,
		Type6,
	};
	SomeOtherObject o;
	EventTypeA t;
};

class EventB
{
public:
	SomeOtherObject o;
};

class ListenerInterfaceA
{
	virtual void processEventA( EventA * const _eventA ) = 0;
};

class ListenerInterfaceB
{
	virtual void processEventBType1( EventB * const _eventB ) = 0;
	virtual void processEventBType2( EventB * const _eventB ) = 0;
	virtual void processEventBType3( EventB * const _eventB ) = 0;
	virtual void processEventBType4( EventB * const _eventB ) = 0;
	virtual void processEventBType5( EventB * const _eventB ) = 0;
	virtual void processEventBType6( EventB * const _eventB ) = 0;
};

class SomeListenerImplementationA : public ListenerInterfaceA
{
	virtual void processEventA( EventA * const _eventA )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventA-&gt;o &lt;&lt; &quot; and type is &quot; &lt;&lt; _eventA-&gt;t &lt;&lt; std::endl; 

		switch( _eventA-&gt;t )
		{
		case EventA::Type1:
			// wake up
			break;
		case EventA::Type2:
			// eat something
			break;
		case EventA::Type3:
			// do nothing
			break;
		case EventA::Type4:
			// do nothing
			break;
		case EventA::Type5:
			// get drunk
			break;
		case EventA::Type6:
			// go sleeping
			break;
		}
	}
};

class SomeListenerImplementationB : public ListenerInterfaceB
{
	virtual void processEventBType1( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 1 &quot; &lt;&lt; std::endl; 
		// wake up
	}

	virtual void processEventBType2( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 2 &quot; &lt;&lt; std::endl;
		// eat something
	}

	virtual void processEventBType3( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 3 &quot; &lt;&lt; std::endl;
		// do nothing
	}

	virtual void processEventBType4( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 4 &quot; &lt;&lt; std::endl;
		// do nothing
	}

	virtual void processEventBType5( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 5 &quot; &lt;&lt; std::endl;
		// get drunk
	}

	virtual void processEventBType6( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 6 &quot; &lt;&lt; std::endl;
		// go sleeping
	}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/259150/event-dispatcher-listener-interface-stil</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 23:08:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/259150.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 19 Jan 2010 18:09:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Event Dispatcher &#x2F; Listener - Interface Stil ... on Tue, 19 Jan 2010 18:09:59 GMT]]></title><description><![CDATA[<p>Ich hatte grad eine Diskussion mit meinem Chef wie unser recht weit verbreitetes Event system überarbeitet werden sollte.<br />
Ausgangslage: Suboptimales System mit Dispatcher / Listener / Event Basisklasse, alle Event gehen als &quot;Event *&quot; raus und werden per dynamic_cast in den Listener in den &quot;richtigen&quot; Typ gecastet und verwendet wie gewünscht - oder verworfen. Unötiger overhead, bei entsprechender Eventvielfalt unübersichtlich ...</p>
<p>Nachdem wir nun überhaupt mal einig sind, dass das so Scheisse war will mein Chef jetzt ins andere extrem: Für jeden Furz ein eigener Event Typ, einen eigenen Event-callback( selbst wenn beim Event durch einen simplen enum kein Unterschied gemacht werden müsste ).<br />
Find ich beinahe genauso deppert wie die Variante davor. Wie seht ihr das? Code unten zur Illustration.</p>
<p>Ich glaub das &quot;Grundproblem&quot; ist das mein Chef einfache Regeln und klare Vorgaben so gern hat. Hauptsache niemand macht sich irgendwelche Gedanken wenn er ein Interface entwirft ....</p>
<pre><code class="language-cpp">class SomeOtherObject
{
	//... something
};

class EventA
{
public:
	enum EventTypeA
	{
		Type1,
		Type2,
		Type3,
		Type4,
		Type5,
		Type6,
	};
	SomeOtherObject o;
	EventTypeA t;
};

class EventB
{
public:
	SomeOtherObject o;
};

class ListenerInterfaceA
{
	virtual void processEventA( EventA * const _eventA ) = 0;
};

class ListenerInterfaceB
{
	virtual void processEventBType1( EventB * const _eventB ) = 0;
	virtual void processEventBType2( EventB * const _eventB ) = 0;
	virtual void processEventBType3( EventB * const _eventB ) = 0;
	virtual void processEventBType4( EventB * const _eventB ) = 0;
	virtual void processEventBType5( EventB * const _eventB ) = 0;
	virtual void processEventBType6( EventB * const _eventB ) = 0;
};

class SomeListenerImplementationA : public ListenerInterfaceA
{
	virtual void processEventA( EventA * const _eventA )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventA-&gt;o &lt;&lt; &quot; and type is &quot; &lt;&lt; _eventA-&gt;t &lt;&lt; std::endl; 

		switch( _eventA-&gt;t )
		{
		case EventA::Type1:
			// wake up
			break;
		case EventA::Type2:
			// eat something
			break;
		case EventA::Type3:
			// do nothing
			break;
		case EventA::Type4:
			// do nothing
			break;
		case EventA::Type5:
			// get drunk
			break;
		case EventA::Type6:
			// go sleeping
			break;
		}
	}
};

class SomeListenerImplementationB : public ListenerInterfaceB
{
	virtual void processEventBType1( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 1 &quot; &lt;&lt; std::endl; 
		// wake up
	}

	virtual void processEventBType2( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 2 &quot; &lt;&lt; std::endl;
		// eat something
	}

	virtual void processEventBType3( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 3 &quot; &lt;&lt; std::endl;
		// do nothing
	}

	virtual void processEventBType4( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 4 &quot; &lt;&lt; std::endl;
		// do nothing
	}

	virtual void processEventBType5( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 5 &quot; &lt;&lt; std::endl;
		// get drunk
	}

	virtual void processEventBType6( EventB * const _eventB )
	{
		std::cout &lt;&lt; &quot;hey, we got some event here! o is: &quot; &lt;&lt; _eventB-&gt;o &lt;&lt; &quot; and type is 6 &quot; &lt;&lt; std::endl;
		// go sleeping
	}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1841555</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1841555</guid><dc:creator><![CDATA[flicky]]></dc:creator><pubDate>Tue, 19 Jan 2010 18:09:59 GMT</pubDate></item><item><title><![CDATA[Reply to Event Dispatcher &#x2F; Listener - Interface Stil ... on Tue, 19 Jan 2010 21:05:20 GMT]]></title><description><![CDATA[<p>flicky schrieb:</p>
<blockquote>
<p>Basisklasse, alle Event gehen als &quot;Event *&quot; raus und werden per dynamic_cast in den Listener in den &quot;richtigen&quot; Typ gecastet und verwendet wie gewünscht - oder verworfen. Unötiger overhead, bei entsprechender Eventvielfalt unübersichtlich ...</p>
</blockquote>
<p>Wenn man den Code unten sieht ist aber der dynamic_cast unnötig! Der Type wird eh mit einem &quot;event-&gt;t&quot; bekannt. Wenn der type vom jeweiligen Konstruktor gesetzt wird sollte der Typ einwandfrei bestimmt sein, dann ist auch ein static_cast möglich der keinen Overhead mit sich bringt.</p>
<p>Ansonsten gibt es doch genügend große Fraimworks (Qt, wxWidgets, z.B.) die scheinbar ein funktionierendes Event-System integriert haben. Warum dort nicht spicken?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1841669</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1841669</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Tue, 19 Jan 2010 21:05:20 GMT</pubDate></item><item><title><![CDATA[Reply to Event Dispatcher &#x2F; Listener - Interface Stil ... on Wed, 20 Jan 2010 17:51:29 GMT]]></title><description><![CDATA[<p>Ich kann folgendes empfehlen (Functor-Realisierung):</p>
<p>Zu jedem Event-Type gibt es eine Functor-Liste (Empfänger-Liste).<br />
Das Event-System dispatcht genau einmal und läuft dann die Functor-Liste durch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1842152</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1842152</guid><dc:creator><![CDATA[nurf]]></dc:creator><pubDate>Wed, 20 Jan 2010 17:51:29 GMT</pubDate></item></channel></rss>