<?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[Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot;]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>also ich tue mich beim Design immer noch wahnsinnig schwer, daher hier mal 2 meiner aktuellen Probleme:</p>
<p>1. Design der Ereignisklassen:<br />
Es geht darum, dass eine Aktion (z.B. durch den menschlichen Spieler) ausgelöst wird. Dies kann z.B. über das Drücken eines Button, die Auswahl eines Menüeintrages oder einen Hotkey geschehen. Zusätzlich gibt es verschiedene dieser Aktionen (z.B. will Gebäude errichten, will Angreifen, errichtet Gebäude, greift an, ...). Die Grunddee war, eine abstrakte Basisklasse Activity zu machen, die durch eine parameterlose Methode aktiviert wird. Davon abgeleitet gibt es dann z.B. Klassen für die Aktivitäten &quot;will Gebäude errichten&quot;, &quot;will angreifen&quot; usw. Das klappt auch wunderbar. Nun hab ich aber festgestellt, dass diese beiden spezielleren Klassen eigentlich nahezu identisch in ihrem Code sind! D.h., eine Klasse, die bei Aktivierung unterscheiden kann, was passieren soll würde eigentlich langen. Das funktioniert aber nicht mit einer parameterlosen Aktivierungsmethode. Nun könnte ich entweder der Methode einen Paameter mitgeben für die Art der Aktion, oder für jede mögliche Aktione eine eigene Methode bereitstellen. Beides behagt mir nicht so recht!<br />
Qas wäre denn hier eine empfehlenswerte Vorgehensweise?</p>
<p>2. Die Koordination zwischen GUI und (mehrstufigen) Folgeaktionen:<br />
Das Thema hatte ich hier (<a href="http://www.c-plusplus.net/forum/268900" rel="nofollow">http://www.c-plusplus.net/forum/268900</a>) schon mal aufgebracht und auch in nem anderen Forum schon einiges Feedback bekommen. Problem ist hierbei Mehrstufigkeit von Aktionen. Der Spieler löst die Aktion &quot;will Gebäude errichten&quot; aus. Das sorgt z.B. für visuelles Feedback. Eine mögliche Folgeaktion durch Mausklick ins Spielfeld wäre: &quot;Gebäude errichten&quot;. Aber woher weiss ich zu dem Zeitpunkt, dass dies die gewünschte Aktion ist? Setze ich irgendwo im Spielerobjekt oder beim Maus-Ereignisverarbeiter einen entsprechenden Status? Eine andere mögliche Folgeaktion wäre nämlich auch &quot;will doch kein Gebäude errichten&quot;, eine weitere wäre &quot;will angreifen&quot;. Beide hätten andere Auswirkungen bei einem Klick ins Spielfeld. Wie bekomme ich die Information über die mögliche Folgeaktion denn vermittelt und an wen vermittle ich sie? Ein Vorschlag, den ich erhalten habe ist. dass die Aktion &quot;will Gebäude errichten&quot; als nächste Aktion &quot;Gebäude errichten&quot; an die Ereignisverarbeitung des LMB hängt. Die Aktion &quot;will Gebäude doch nicht errichten&quot; müsste dies dann bei der Ereignisverarbeitung des LMB wieder rückgängig machen. Das gefällt mir aber nicht so ganz, da dann eine Aktion ja die andere kennen müsste! Zudem müssen bei Spieler und Spielfeld später das neue Gebäude ja auch noch eingetragen werden!<br />
Ich hatte mir noch überlegt, ein Objekt für Spieleraktionen zu machen, das immer genau weiss, in welchem Zustand es sich gerade befindet. Dieses Objekt würde dann überall dort eingehanden, wo Ereignisse des menschlichen Spielers verarbeitet werden! Was haltet ihr davon?</p>
<p>Ich hoffe, ich konnte die Probleme einigermaßen beschreiben!</p>
<p>Vielen Dank schon mal!</p>
<p>Ciao</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/281712/designtips-benötigt-zu-quot-ereignisverarbeitung-quot</link><generator>RSS for Node</generator><lastBuildDate>Sun, 23 Aug 2026 14:02:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/281712.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Feb 2011 17:53:33 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 17:53:33 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>also ich tue mich beim Design immer noch wahnsinnig schwer, daher hier mal 2 meiner aktuellen Probleme:</p>
<p>1. Design der Ereignisklassen:<br />
Es geht darum, dass eine Aktion (z.B. durch den menschlichen Spieler) ausgelöst wird. Dies kann z.B. über das Drücken eines Button, die Auswahl eines Menüeintrages oder einen Hotkey geschehen. Zusätzlich gibt es verschiedene dieser Aktionen (z.B. will Gebäude errichten, will Angreifen, errichtet Gebäude, greift an, ...). Die Grunddee war, eine abstrakte Basisklasse Activity zu machen, die durch eine parameterlose Methode aktiviert wird. Davon abgeleitet gibt es dann z.B. Klassen für die Aktivitäten &quot;will Gebäude errichten&quot;, &quot;will angreifen&quot; usw. Das klappt auch wunderbar. Nun hab ich aber festgestellt, dass diese beiden spezielleren Klassen eigentlich nahezu identisch in ihrem Code sind! D.h., eine Klasse, die bei Aktivierung unterscheiden kann, was passieren soll würde eigentlich langen. Das funktioniert aber nicht mit einer parameterlosen Aktivierungsmethode. Nun könnte ich entweder der Methode einen Paameter mitgeben für die Art der Aktion, oder für jede mögliche Aktione eine eigene Methode bereitstellen. Beides behagt mir nicht so recht!<br />
Qas wäre denn hier eine empfehlenswerte Vorgehensweise?</p>
<p>2. Die Koordination zwischen GUI und (mehrstufigen) Folgeaktionen:<br />
Das Thema hatte ich hier (<a href="http://www.c-plusplus.net/forum/268900" rel="nofollow">http://www.c-plusplus.net/forum/268900</a>) schon mal aufgebracht und auch in nem anderen Forum schon einiges Feedback bekommen. Problem ist hierbei Mehrstufigkeit von Aktionen. Der Spieler löst die Aktion &quot;will Gebäude errichten&quot; aus. Das sorgt z.B. für visuelles Feedback. Eine mögliche Folgeaktion durch Mausklick ins Spielfeld wäre: &quot;Gebäude errichten&quot;. Aber woher weiss ich zu dem Zeitpunkt, dass dies die gewünschte Aktion ist? Setze ich irgendwo im Spielerobjekt oder beim Maus-Ereignisverarbeiter einen entsprechenden Status? Eine andere mögliche Folgeaktion wäre nämlich auch &quot;will doch kein Gebäude errichten&quot;, eine weitere wäre &quot;will angreifen&quot;. Beide hätten andere Auswirkungen bei einem Klick ins Spielfeld. Wie bekomme ich die Information über die mögliche Folgeaktion denn vermittelt und an wen vermittle ich sie? Ein Vorschlag, den ich erhalten habe ist. dass die Aktion &quot;will Gebäude errichten&quot; als nächste Aktion &quot;Gebäude errichten&quot; an die Ereignisverarbeitung des LMB hängt. Die Aktion &quot;will Gebäude doch nicht errichten&quot; müsste dies dann bei der Ereignisverarbeitung des LMB wieder rückgängig machen. Das gefällt mir aber nicht so ganz, da dann eine Aktion ja die andere kennen müsste! Zudem müssen bei Spieler und Spielfeld später das neue Gebäude ja auch noch eingetragen werden!<br />
Ich hatte mir noch überlegt, ein Objekt für Spieleraktionen zu machen, das immer genau weiss, in welchem Zustand es sich gerade befindet. Dieses Objekt würde dann überall dort eingehanden, wo Ereignisse des menschlichen Spielers verarbeitet werden! Was haltet ihr davon?</p>
<p>Ich hoffe, ich konnte die Probleme einigermaßen beschreiben!</p>
<p>Vielen Dank schon mal!</p>
<p>Ciao</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017437</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017437</guid><dc:creator><![CDATA[Reth]]></dc:creator><pubDate>Sun, 06 Feb 2011 17:53:33 GMT</pubDate></item><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 18:08:03 GMT]]></title><description><![CDATA[<p><strong>1.</strong> Ginge da nicht ein <code>enum</code> für die unterschiedlichen Aktionen?</p>
<p>Und warum ist <code>Activity</code> im Grundzustand inaktiv und muss erst aktiviert werden? Ich würde sonst einen Konstruktor bereitstellen, der die Art der Aktion (eben dieses <code>enum</code> ) als Parameter nimmt.</p>
<p><strong>2.</strong> Ich würde jetzt spontan in einer entsprechenden Verwaltungsklasse zwischenspeichern, was gerade getan wird, und welche Semantik der nächste Mausklick hat. Das ist auch praktisch, weil du diesen Status wahrscheinlich nicht nur für das Ereignis (&quot;beginne Bau&quot;) selbst, sondern für andere Dinge wie die Darstellung (&quot;zeige Gebäude-Umriss an der Stelle des Mauszeigers&quot;) benutzen kannst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017445</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017445</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 06 Feb 2011 18:08:03 GMT</pubDate></item><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 18:22:55 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p><strong>1.</strong> Ginge da nicht ein <code>enum</code> für die unterschiedlichen Aktionen?</p>
<p>Und warum ist <code>Activity</code> im Grundzustand inaktiv und muss erst aktiviert werden? Ich würde sonst einen Konstruktor bereitstellen, der die Art der Aktion (eben dieses <code>enum</code> ) als Parameter nimmt.</p>
</blockquote>
<p>Naja, die Activities hängen an den Buttons, Menüeinträgen etc. Bei Auslösen wird die activate()-Methode gerufen. Hier mal ein Auszug:</p>
<p>Abstrakte Basisklasse:</p>
<pre><code class="language-cpp">#include &quot;UserActivityC.h&quot;

UserActivityC::UserActivityC(AnimObjectC&amp; cursorObject, PlayerC&amp; human) : cursor(cursorObject), humanPlayer(human)
{
}

UserActivityC::~UserActivityC() {}

void UserActivityC::changeCursorObject(const int type)
{
	// selber Aktion nochmal aktiviert =&gt; type identisch =&gt; Sichtbarkeit umschalten
	// ansonsten Animation wechseln
	if (cursor.getActiveAnimationType() == type)
	{
		cursor.toggleVisible();
	} else
	{
		cursor.setActiveAnimationType(type);
	}
}
</code></pre>
<p>Hier wird also schon die Darstellung am MausCursor zentral umgeschalten. Eine speziellere Klasse davon, die z.B. an einem Button hängt ist:</p>
<pre><code class="language-cpp">TowerGadgetActivityC::TowerGadgetActivityC(AnimObjectC&amp; cursorObject, PlayerC&amp; human) : UserActivityC(cursorObject, human)
{
}

TowerGadgetActivityC::~TowerGadgetActivityC() {}

void TowerGadgetActivityC::activate()
{
	changeCursorObject(GFX_TOWERCURSOR);
}
</code></pre>
<p>Eine andere speziellere Klasse hätte in ihrer activate-Methode nur noch</p>
<pre><code class="language-cpp">changeCursorObject(GFX_LIGHTNINGCURSOR);
</code></pre>
<p>stehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017455</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017455</guid><dc:creator><![CDATA[Reth]]></dc:creator><pubDate>Sun, 06 Feb 2011 18:22:55 GMT</pubDate></item><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 20:12:41 GMT]]></title><description><![CDATA[<p>Reth schrieb:</p>
<blockquote>
<p>Naja, die Activities hängen an den Buttons, Menüeinträgen etc. Bei Auslösen wird die activate()-Methode gerufen.</p>
</blockquote>
<p>Ah, so eine Art Commands. Die GUI-Elemente kennen den Aktionstyp wahrscheinlich nicht, daher kommt der Konstruktor am ehesten in Frage. Also statt</p>
<pre><code class="language-cpp">myButton.AddListener( new TowerGadgetActivity(...) );
</code></pre>
<p>nimmst du</p>
<pre><code class="language-cpp">myButton.AddListener( new GadgetActivity(Tower, ...) );
</code></pre>
<p>wobei dann <code>Tower</code> ein Enumerator ist. Wäre das was?</p>
<p>Übrigens, noch ein paar nebensächliche Codestilanmerkungen (ich will dir nicht zu gross im Stil rumpfuschen, fasse sie als Anregungen auf ;)):</p>
<ul>
<li>Warum ein explizites &quot;C&quot;-Postfix, um Klassen zu erkennen? Immerhin kein Präfix, aber trotzdem <a href="http://www.c-plusplus.net/forum/p2005233#2005233" rel="nofollow">eventuelle Gegenargumente</a>.</li>
<li>Willst du nicht ein <code>enum</code> statt <code>int</code> nehmen, wenn nur eine festgelegte Anzahl an Zuständen möglich sein soll?</li>
<li>Warum definierst du bei abgeleiteten Klassen leere Destruktoren?</li>
<li>Top-Level-Consts bei Parametern ( <code>const int</code> ) würde ich vermeiden, da sie nicht wirklich was bringen (im Gegensatz zu Zeigern und Referenzen auf <code>const</code> ) – siehe auch <a href="http://www.c-plusplus.net/forum/273622-10" rel="nofollow">hier</a></li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/2017510</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017510</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 06 Feb 2011 20:12:41 GMT</pubDate></item><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 21:28:32 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Reth schrieb:</p>
<blockquote>
<p>Naja, die Activities hängen an den Buttons, Menüeinträgen etc. Bei Auslösen wird die activate()-Methode gerufen.</p>
</blockquote>
<p>Ah, so eine Art Commands. Die GUI-Elemente kennen den Aktionstyp wahrscheinlich nicht, daher kommt der Konstruktor am ehesten in Frage. Also statt</p>
<pre><code class="language-cpp">myButton.AddListener( new TowerGadgetActivity(...) );
</code></pre>
<p>nimmst du</p>
<pre><code class="language-cpp">myButton.AddListener( new GadgetActivity(Tower, ...) );
</code></pre>
<p>wobei dann <code>Tower</code> ein Enumerator ist. Wäre das was?</p>
</blockquote>
<p>Genau so ähnlich meinte ich das mit der parametrierbaren activate-Methode. Denn eigentlich bräuchte ich ja dann nicht mehr verschiedene Activity-Objekte pro Button sondern nur noch eines für alle, so lange ich im Code keine Fallunterscheidungen mehr machen müsste, sondern den Typ nur durchreiche (habe dafür schon Symbols, die auch an anderen Stellen verwendet werden).</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Übrigens, noch ein paar nebensächliche Codestilanmerkungen (ich will dir nicht zu gross im Stil rumpfuschen, fasse sie als Anregungen auf ;)):</p>
</blockquote>
<p>Danke! Immer gerne!</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>[*]Willst du nicht ein <code>enum</code> statt <code>int</code> nehmen, wenn nur eine festgelegte Anzahl an Zuständen möglich sein soll?</p>
</blockquote>
<p>Wofür meinst Du? Für die Werte wie: GFX_TOWERCURSOR? Dafür hatte ich mir von Anfang an Symbols definiert. Spricht aber nichts gg. ne enum (was ist denn dann der Vorteil?).</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>[*]Warum definierst du bei abgeleiteten Klassen leere Destruktoren?</p>
</blockquote>
<p>Öhm, hm, tja. Hatte ich in diesem Thread noch nicht erwähnt, bin noch relativer C++-Anfänger. Braucht man das nicht?</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>[*]Top-Level-Consts bei Parametern ( <code>const int</code> ) würde ich vermeiden, da sie nicht wirklich was bringen (im Gegensatz zu Zeigern und Referenzen auf <code>const</code> ) – siehe auch <a href="http://www.c-plusplus.net/forum/273622-10" rel="nofollow">hier</a></p>
</blockquote>
<p>Hier hatte ich mich an nen Grundsatz aus nem C++-Buch gehalten, quasi zu consten, was das Zeug hält. Zumindest kann man dann den Parameter in der Methode nicht mehr versehentlich ändern!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017567</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017567</guid><dc:creator><![CDATA[Reth]]></dc:creator><pubDate>Sun, 06 Feb 2011 21:28:32 GMT</pubDate></item><item><title><![CDATA[Reply to Designtips benötigt zu &amp;quot;Ereignisverarbeitung&amp;quot; on Sun, 06 Feb 2011 21:43:48 GMT]]></title><description><![CDATA[<p>Reth schrieb:</p>
<blockquote>
<p>Wofür meinst Du? Für die Werte wie: GFX_TOWERCURSOR? Dafür hatte ich mir von Anfang an Symbols definiert. Spricht aber nichts gg. ne enum (was ist denn dann der Vorteil?).</p>
</blockquote>
<p>Ja, genau für die Werte. Der Vorteil von <code>enum</code> gegenüber <code>int</code> ist vor allem Typsicherheit:</p>
<pre><code class="language-cpp">enum Cursor { GFX_TOWERCURSOR, ... };

void f(int cursor);
void g(Cursor cursor);

f(3); // (fälschlicherweise) ok
g(3); // Compilerfehler
</code></pre>
<p>Ausserdem wird den einzelnen Enumeratoren jeweils ein einzigartiger Wert zugewiesen, d.h. du musst dich nicht um die IDs kümmern. Gegenüber <code>#define</code> hat <code>enum</code> den zusätzlichen Vorteil, dass der Scope berücksichtigt wird und Debug-Symbole vorhanden sind.</p>
<p>Reth schrieb:</p>
<blockquote>
<p>Braucht man das nicht?</p>
</blockquote>
<p>Nur bei virtuellen Destruktoren, und auch da nur einmal in der Basisklasse (in abgeleiteten Klassen wäre der Destruktor dann automatisch auch virtuell). Der Destruktor gehört zu den automatisch generierten Funktionen und tut meist das Richtige. Erst wenn du spezielle Funktionalität brauchst, musst du ihn selbst definieren – aber dann ist er auch nicht leer.</p>
<p>Reth schrieb:</p>
<blockquote>
<p>Hier hatte ich mich an nen Grundsatz aus nem C++-Buch gehalten, quasi zu consten, was das Zeug hält.</p>
</blockquote>
<p>Das halte ich für eine schlechte Idee, denn auf diese Weise gehen wichtige <code>const</code> s unter. Wichtig ist z.B. bei Zeigern/Referenzen auf konstante Objekte, um dem Aufrufer mitzuteilen, dass die Objekte von der Funktion nicht verändert werden. Bei Kopien (wie <code>int</code> ) spielt es keine Rolle, was in der Funktion getan wird.</p>
<p>Dass die versehentliche Änderung verhindert wird, stimmt natürlich. Das ist ein Grund für <code>const</code> in der Funktionsdefinition, aber nicht in der -deklaration (die Funktionstypen sind in beiden Fällen identisch). Denn die Deklaration gehört zur Schnittstelle, dort bringt die Information des <code>const</code> rein gar nichts, aber führt tendenziell zur Verwirrung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017572</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017572</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 06 Feb 2011 21:43:48 GMT</pubDate></item></channel></rss>