<?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[Klassendesign: IRC Client Library]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich bastle gerade an einer IRC-Client Library, komme allerdings auf keinen gruenen Zweig, wie ich das ganze designen soll. Derzeit habe ich eine Klasse irc::socket, der von irc::session verwendet wird, aber mit dem der User nicht in Beruehrung kommen soll. irc::session hat Methoden um Channels zu joinen, Nachrichten zu senden, etc und haelt die Session-Daten, wie Nickname, Channel-Liste, etc.</p>
<p>Der User kann bei irc::session Callbacks angeben, die dann fuer ihn aufgerufen werden, sobald das entsprechende Event eintritt, z.B.:</p>
<pre><code>irc::server_data server_data(&quot;irc.f00.net&quot;, 6667);
irc::session_data session_data(&quot;f00bar&quot;);
irc::session session(server_data, session_data);

session.on_connect([&amp;] { session.join(&quot;#f00&quot;); });

session.on_join
(
	[&amp;] (irc::join_event const&amp; e)
	{
		if(e.user().nickname != session_data.nickname)
			session.message(e.channel(), &quot;Welcome &quot; + e.user().nickname + &quot; to &quot; + e.channel() + &quot;!&quot;);
	}
);

session.run();
</code></pre>
<p>Irgendwie gefaellt mir das ganze ueberhaupt nicht. irc::session mutiert zu einer Gottklasse mit zig Funktionen, fuer jede Art von Aktion eine, und dazu ein Event-Handler, sowie eine Event-Registrierungsfunktion.</p>
<p>Ich wuerde gerne das Event-Handling von der Session irgendwie entkoppeln, aber das braucht ja indirekt auch das Protokoll, welches den Socket der Session braucht.</p>
<p>Hat jemand einen besseren Vorschlag?</p>
<p>Gruesse,<br />
Der Kellerautomat</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/311070/klassendesign-irc-client-library</link><generator>RSS for Node</generator><lastBuildDate>Tue, 04 Aug 2026 00:32:56 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/311070.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 26 Nov 2012 08:44:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Mon, 26 Nov 2012 08:57:16 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich bastle gerade an einer IRC-Client Library, komme allerdings auf keinen gruenen Zweig, wie ich das ganze designen soll. Derzeit habe ich eine Klasse irc::socket, der von irc::session verwendet wird, aber mit dem der User nicht in Beruehrung kommen soll. irc::session hat Methoden um Channels zu joinen, Nachrichten zu senden, etc und haelt die Session-Daten, wie Nickname, Channel-Liste, etc.</p>
<p>Der User kann bei irc::session Callbacks angeben, die dann fuer ihn aufgerufen werden, sobald das entsprechende Event eintritt, z.B.:</p>
<pre><code>irc::server_data server_data(&quot;irc.f00.net&quot;, 6667);
irc::session_data session_data(&quot;f00bar&quot;);
irc::session session(server_data, session_data);

session.on_connect([&amp;] { session.join(&quot;#f00&quot;); });

session.on_join
(
	[&amp;] (irc::join_event const&amp; e)
	{
		if(e.user().nickname != session_data.nickname)
			session.message(e.channel(), &quot;Welcome &quot; + e.user().nickname + &quot; to &quot; + e.channel() + &quot;!&quot;);
	}
);

session.run();
</code></pre>
<p>Irgendwie gefaellt mir das ganze ueberhaupt nicht. irc::session mutiert zu einer Gottklasse mit zig Funktionen, fuer jede Art von Aktion eine, und dazu ein Event-Handler, sowie eine Event-Registrierungsfunktion.</p>
<p>Ich wuerde gerne das Event-Handling von der Session irgendwie entkoppeln, aber das braucht ja indirekt auch das Protokoll, welches den Socket der Session braucht.</p>
<p>Hat jemand einen besseren Vorschlag?</p>
<p>Gruesse,<br />
Der Kellerautomat</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2274698</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2274698</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Mon, 26 Nov 2012 08:57:16 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 09:39:57 GMT]]></title><description><![CDATA[<p>*push*</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275376</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 28 Nov 2012 09:39:57 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:21:50 GMT]]></title><description><![CDATA[<p>Wie wäre folgendes:</p>
<p>Du hast eine Methode<br />
addEventListener(event, function);</p>
<p>Und wenn jetzt ein Event abgefeuert wird, muss nur die liste der EventListener durchgegangen werden und das assoziierte Event verglichen werden.</p>
<p>So ist die Session Klasse unabhängig von den Events und kann auch custom events feuern wenn client code das verlangt. Und man kann unendlich viele listener auf ein event haben.</p>
<p>PS:<br />
Was ich meine ist folgendes (Pseudo Code):</p>
<pre><code class="language-cpp">//vom client aufgerufen
void Session::addEventListener(Event evt, Function func) {
   listeners.add({evt, func});
}

//intern aufgerufen, zB bei einem join
void Session::fireEvent(Event evt) {
   for(auto obj : listeners) {
     if(obj.evt == evt) obj.func(evt);
   }
}

//Client Code wäre dann:
session.addEventListener(Event.CONNECT, ([&amp;](irc::event const&amp; e) { session.join(&quot;#f00&quot;); }));
session.addEventListener(Event.JOIN,
     [&amp;] (irc::event const&amp; e) 
     { 
         if(e.user().nickname != session_data.nickname) 
             session.message(e.channel(), &quot;Welcome &quot; + e.user().nickname + &quot; to &quot; + e.channel() + &quot;!&quot;); 
     } 
);
</code></pre>
<p>Edit:<br />
Event Parameter eingefügt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275382</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:21:50 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:24:36 GMT]]></title><description><![CDATA[<p>Das sieht zwar grundsaetzlich gut aus, aber wie wuerden dann die Events funktionieren? Du hast hier ja nur einen Event-Typ, wie funktioniert das mit den verschiedenen Event-Arten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275400</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275400</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:24:36 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:42:22 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Das sieht zwar grundsaetzlich gut aus, aber wie wuerden dann die Events funktionieren? Du hast hier ja nur einen Event-Typ, wie funktioniert das mit den verschiedenen Event-Arten?</p>
</blockquote>
<p>Was ich hier skizziert habe ist etwa das, wie ActionScript 3 das event Handling macht.</p>
<p>Du kannst ruhig mehrer events haben.</p>
<p>Event könnte zB so aussehen:</p>
<pre><code class="language-cpp">class Event {
private:
  EventData* data;
  EventType type; //eigentlich nur ein integer!

public:
  Event(EventType type, EventData* data=0)
  : type(type), data(data) {}

  ~Event() { delete data; }

  bool isEqual(Event const&amp; other) {
    return type == other.type;
  }

  EventData const* getData() const {
    return data;
  }
};
</code></pre>
<p>Wenn ich nun ein Join Event haben will, amche ich das so:</p>
<pre><code class="language-cpp">class EventData {
private:
  Time time;
public:
  EventData(Time time) : time(time) {}
  virtual ~EventData() {}
  Time getTime() const { return time; }
};
class JoinEventData : publuc EventData {
private:
  Channel chan;
public:
  JoinEventData(Time time, Channel const&amp; chan) : EventData(time), chan(chan) {}
  Channel const&amp; getChannel() const { return channel; }
};
</code></pre>
<p>und dann mache ich in Session::join folgendes:</p>
<pre><code class="language-cpp">fireEvent(Event(EventType::JOIN, new JoinEventData(getTime(), channel));
</code></pre>
<p>PS:<br />
und im Client Code dann:</p>
<pre><code class="language-cpp">session.registerEventListener(EventType::JOIN, ([&amp;](Event evt) {
  JoinEventData const* data=static_cast&lt;JoinEventData const*&gt;(evt.getData());
  cout&lt;&lt;&quot;Joined Channel: &quot;&lt;&lt;data.getChannel();
}));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2275406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275406</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:42:22 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:43:43 GMT]]></title><description><![CDATA[<p>Das haette dann aber den Nachteil, dass Client-Code explizit auf den richtigen Eventtyp casten muss. Evtl. koennte ich dann einfach addEventListener zu einem template machen, dass eine Trampolinfunktion verwendet, um auf den richtigen Typ zu casten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275408</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275408</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:43:43 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:53:37 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Das haette dann aber den Nachteil, dass Client-Code explizit auf den richtigen Eventtyp casten muss. Evtl. koennte ich dann einfach addEventListener zu einem template machen, dass eine Trampolinfunktion verwendet, um auf den richtigen Typ zu casten.</p>
</blockquote>
<p>Finde ich nicht so toll.</p>
<p>Du könntest EventData einfach so definieren, dass es immer die selben Felder sind. Ist halt unflexibler, aber du könntest sagen, jedes event hat eben einen channel, eine uhrzeit, einen sender, etc.</p>
<p>Ich finde das mit dem casten ganz angenehm - da du plötzlich komplett frei bist, was die events betrifft. Session muss nichts wissen. Und in vielen Event Listener braucht man die Event Daten ja auch garnicht. Wenn du das Casten nicht willst, mach mit einer Umwandlungs Funktion die das Casten übernimmt.</p>
<p>zB könnte getData eine Template Funktion sein:</p>
<pre><code class="language-cpp">JoinEventData const* data=evt.getData&lt;JoinEventData&gt;();
</code></pre>
<p>Oder getData liefert ein Proxy Objekt dass einen template operator T* für den Cast hat.</p>
<p>Das coole an dem System ist eben:<br />
Du kannst jederzeit neue Events hinzufügen ohne Code ändern zu müssen. Und vorallem: du kannst User Events erlauben.</p>
<p>Ich kann zB ein Plugin schreiben dass bei jeder Nachricht in einem Channel auf meinen Namen hört und wenn mein Name vorkommt dann feure ich ein Event MyNameWasMentioned ab.</p>
<p>Fixe Events vorauszusetzen ist unflexibel.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275410</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:53:37 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 10:55:31 GMT]]></title><description><![CDATA[<p>Die Events werden doch von session erzeugt und verteilt? Wie soll ich da User-Events erlauben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275411</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275411</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 28 Nov 2012 10:55:31 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 11:31:30 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Die Events werden doch von session erzeugt und verteilt? Wie soll ich da User-Events erlauben?</p>
</blockquote>
<p>Ich dachte du wolltest das entkoppeln?</p>
<p>Session muss dann ja alles checken und überwachen. Ich würde zB Session nur ganz wenige Events anbieten lassen. zB MessageReceived. Und darauf hören dann viele Listener. zB einer der Joins von anderern Usern abfängt und dann eben ein UserJoined Event triggert.</p>
<p>Wenn Session selber alles handeln soll, dann ist es ein gott objekt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Aber es reicht eine minimale Funktionalität anzubieten - wie eben MessageReceived und vielleicht ActionReceived und der Rest wird von Listenern gemacht.</p>
<p>So kannst du ohne Probleme dann so sachen wie einen bad-word filter einbauen, etc.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275420</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275420</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 28 Nov 2012 11:31:30 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 11:56:14 GMT]]></title><description><![CDATA[<p>Wollte ich auch, aber dafuer habe ich bisher keine Idee...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275429</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275429</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Wed, 28 Nov 2012 11:56:14 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 13:38:13 GMT]]></title><description><![CDATA[<p>Kellerautomat schrieb:</p>
<blockquote>
<p>Wollte ich auch, aber dafuer habe ich bisher keine Idee...</p>
</blockquote>
<p>Ansonsten schau dir einfach GUI Frameworks an - die haben alle genau diese Problematik (nur etwas komplexer) und lösen sie auf gewisse Weise.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275471</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275471</guid><dc:creator><![CDATA[Shade Of Mine]]></dc:creator><pubDate>Wed, 28 Nov 2012 13:38:13 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 16:37:23 GMT]]></title><description><![CDATA[<p>Shade Of Mine schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//Client Code wäre dann:
session.addEventListener(Event.CONNECT, ([&amp;](irc::event const&amp; e) { session.join(&quot;#f00&quot;); }));
session.addEventListener(Event.JOIN,
     [&amp;] (irc::event const&amp; e) 
     { 
         if(e.user().nickname != session_data.nickname) 
             session.message(e.channel(), &quot;Welcome &quot; + e.user().nickname + &quot; to &quot; + e.channel() + &quot;!&quot;); 
     } 
);
</code></pre>
</blockquote>
<p>Was macht das &quot;[&amp;]&quot;? ich seh das zum ersten mal</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275514</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275514</guid><dc:creator><![CDATA[hoe]]></dc:creator><pubDate>Wed, 28 Nov 2012 16:37:23 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign: IRC Client Library on Wed, 28 Nov 2012 17:16:07 GMT]]></title><description><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B" rel="nofollow">http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2275520</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2275520</guid><dc:creator><![CDATA[wikibot]]></dc:creator><pubDate>Wed, 28 Nov 2012 17:16:07 GMT</pubDate></item></channel></rss>