<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?action=history&amp;feed=atom&amp;title=OMSI_Plugin_Framework_IV</id>
	<title>OMSI Plugin Framework IV - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?action=history&amp;feed=atom&amp;title=OMSI_Plugin_Framework_IV"/>
	<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;action=history"/>
	<updated>2026-04-29T19:55:06Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in OMSIWiki</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=776&amp;oldid=prev</id>
		<title>Holmexx am 26. November 2012 um 05:51 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=776&amp;oldid=prev"/>
		<updated>2012-11-26T05:51:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 26. November 2012, 05:51 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l48&quot; &gt;Zeile 48:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 48:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Zusammen mit dem Mutex ergibt sich nun auch eine Verwendung für '''CEvent'''. Ein Event wird in der Programmierung ganz allgemein dazu benutzt, einem Thread irgendetwas zu signalisieren. Und soetwas müssen wir auch im Framework tun. Da ja der Nebenthread die meiste Zeit seines Lebens schläft, wäre es nicht so gut, wenn der Hauptthread einfach die Nachricht in die Warteschlange packt und dann noch womöglich auf die Bearbeitung wartet. Das könnte ein ziemlich langes Warten werden, da so ein Thread einen äußerst festen Schlaf hat. Aber da gibt es ja die Events. Der Schlafzustand des Nebenthreads ist nämlich an ein solches Event gebunden, da er die Funktion '''''WaitFor''''' des Events aufgerufen hat. Nachdem der Hauptthread die Nachricht in die Warteschlange gepackt hat (Zutritt bekommt er ja ohne weiteres, da der Nebenthread ja schläft), ruft er die Funktion '''''Raise''''' des Events auf. Dadurch wird der Nebenthread augenblicklich unsanft aus dem Schlummer gerissen und setzt seine Arbeit fort. Der gleiche Mechanismus wird auch für die Writable-Variablen und Trigger verwendet. Der Hauptthread packt die entsprechende Nachricht in die Warteschlange und legt sich nun seinerseits schlafen. Sobald der Nebenthread die Variable oder den Trigger bearbeitet hat, ruft er wiederum die Funktion '''''Raise''''' eines weiteren Events auf, um damit den Hauptthread wieder zu erwecken.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Zusammen mit dem Mutex ergibt sich nun auch eine Verwendung für '''CEvent'''. Ein Event wird in der Programmierung ganz allgemein dazu benutzt, einem Thread irgendetwas zu signalisieren. Und soetwas müssen wir auch im Framework tun. Da ja der Nebenthread die meiste Zeit seines Lebens schläft, wäre es nicht so gut, wenn der Hauptthread einfach die Nachricht in die Warteschlange packt und dann noch womöglich auf die Bearbeitung wartet. Das könnte ein ziemlich langes Warten werden, da so ein Thread einen äußerst festen Schlaf hat. Aber da gibt es ja die Events. Der Schlafzustand des Nebenthreads ist nämlich an ein solches Event gebunden, da er die Funktion '''''WaitFor''''' des Events aufgerufen hat. Nachdem der Hauptthread die Nachricht in die Warteschlange gepackt hat (Zutritt bekommt er ja ohne weiteres, da der Nebenthread ja schläft), ruft er die Funktion '''''Raise''''' des Events auf. Dadurch wird der Nebenthread augenblicklich unsanft aus dem Schlummer gerissen und setzt seine Arbeit fort. Der gleiche Mechanismus wird auch für die Writable-Variablen und Trigger verwendet. Der Hauptthread packt die entsprechende Nachricht in die Warteschlange und legt sich nun seinerseits schlafen. Sobald der Nebenthread die Variable oder den Trigger bearbeitet hat, ruft er wiederum die Funktion '''''Raise''''' eines weiteren Events auf, um damit den Hauptthread wieder zu erwecken.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Abschließend in diesem Abschnitt noch ein paar Worte zur Klasse CThread. Ein Thread ist nichts anderes als ein Stück Programmcode. Jedes Programm hat mindestens einen Thread. Damit ein Thread ausführbar ist, muss er eine Hauptfunktion besitzen. Der Thread läuft nun solange, bis die Hauptfunktion endet. War das der letzte (oder einzige) Thread des Programmes, endet dann auch das Programm selbst. Da Windows mit C++-Klassen rein gar nichts anfangen kann, ist die Hauptfunktion in zwei Teile aufgegliedert. Der erste Teil, die Funktion '''''ThreadFunction''''' ist der Teil, den Windows zu Gesicht bekommt. Glücklicherweise kann man einer Threadfunktion einen Parameter mitgeben. Dieser Parameter ist im Framework nun ein Zeiger auf die Instanz der Klasse '''CThread'''. Über diesen Zeiger ruft die Funktion '''''ThreadFunction''''' nun den zweiten Teil der Hauptfunktion auf, die Funktion '''''MainLoop'''''. Wie der Name schon andeutet, ist das nun die wirkliche Hauptfunktion. Im Framework wird die Hauptfunktion durch das Setzen des Feldes&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Abschließend in diesem Abschnitt noch ein paar Worte zur Klasse &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;'''&lt;/ins&gt;CThread&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;'''&lt;/ins&gt;. Ein Thread ist nichts anderes als ein Stück Programmcode. Jedes Programm hat mindestens einen Thread. Damit ein Thread ausführbar ist, muss er eine Hauptfunktion besitzen. Der Thread läuft nun solange, bis die Hauptfunktion endet. War das der letzte (oder einzige) Thread des Programmes, endet dann auch das Programm selbst. Da Windows mit C++-Klassen rein gar nichts anfangen kann, ist die Hauptfunktion in zwei Teile aufgegliedert. Der erste Teil, die Funktion '''''ThreadFunction''''' ist der Teil, den Windows zu Gesicht bekommt. Glücklicherweise kann man einer Threadfunktion einen Parameter mitgeben. Dieser Parameter ist im Framework nun ein Zeiger auf die Instanz der Klasse '''CThread'''. Über diesen Zeiger ruft die Funktion '''''ThreadFunction''''' nun den zweiten Teil der Hauptfunktion auf, die Funktion '''''MainLoop'''''. Wie der Name schon andeutet, ist das nun die wirkliche Hauptfunktion. Im Framework wird die Hauptfunktion durch das Setzen des Feldes&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''''m_bTerminate''''' auf '''true''' beendet. '''CThread''' besitzt, da sie ja von '''CWaitableObject''' abgeleitet ist, auch eine '''''WaitFor'''''-Funktion. Dadurch könnte z.B. ein anderer Thread auf die Beendigung dieses Threads warten. Anders als beim '''CMutex''' muss hier aber kein '''''Release''''' aufgerufen werden. Das übernimmt Windows freundlicherweise für uns. Die Beendigung eines Threads löst automatisch ein ''Release'' aus.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''''m_bTerminate''''' auf '''true''' beendet. '''CThread''' besitzt, da sie ja von '''CWaitableObject''' abgeleitet ist, auch eine '''''WaitFor'''''-Funktion. Dadurch könnte z.B. ein anderer Thread auf die Beendigung dieses Threads warten. Anders als beim '''CMutex''' muss hier aber kein '''''Release''''' aufgerufen werden. Das übernimmt Windows freundlicherweise für uns. Die Beendigung eines Threads löst automatisch ein ''Release'' aus.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=775&amp;oldid=prev</id>
		<title>Holmexx am 26. November 2012 um 05:49 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=775&amp;oldid=prev"/>
		<updated>2012-11-26T05:49:01Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 26. November 2012, 05:49 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l27&quot; &gt;Zeile 27:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 27:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Diese 4 Klassen kapseln Windows-Elemente in einer C++-Klasse. Dies vereinfacht den Zugriff auf diese Elemente. '''CWaitableObject''' ist dabei die Basis für die anderen drei Klassen. Der Name leitet sich davon ab, dass Programmcode im wahrsten Sinne des Wortes auf solche Elemente warten kann. Das wird über die Funktion '''''WaitFor''''' in den Klassen realisiert. In '''CWaitableObject''' ist diese Funktion noch ''abstract'', erst '''CEvent''', '''CMutex''' und '''CThread''' erfüllen sie mit Leben. Der Partner für &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Diese 4 Klassen kapseln Windows-Elemente in einer C++-Klasse. Dies vereinfacht den Zugriff auf diese Elemente. '''CWaitableObject''' ist dabei die Basis für die anderen drei Klassen. Der Name leitet sich davon ab, dass Programmcode im wahrsten Sinne des Wortes auf solche Elemente warten kann. Das wird über die Funktion '''''WaitFor''''' in den Klassen realisiert. In '''CWaitableObject''' ist diese Funktion noch ''abstract'', erst '''CEvent''', '''CMutex''' und '''CThread''' erfüllen sie mit Leben. Der Partner für &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''''WaitFor''''' ist die Funktion '''''Release&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;'&lt;/del&gt;'''''. Nach jedem '''''WaitFor''''' muss man '''''Release''''' aufrufen (außer bei einem Thread), sonst kann es zu einem sogenannten ''Deadlock'' im Programm kommen. Ein ''Deadlock'' bedeutet, das zwei (oder mehr) Threads auf die Freigabe ein und derselben Resource warten. Passiert so etwas, kommt das Programm zum Stillstand. Für den Anwender sieht es so aus, als ob das Programm abgestürzt sei. Technisch stimmt das zwar nicht, aber das spielt für den Anwender keine Rolle. Er kann nicht mehr weiter spielen, arbeiten usw. Solche ''race conditions'', also das gegenseitige Warten auf eine Resource sind die große Schwierigkeit bei der Multithread-Programmierung. Sie sind mitunter schwer zu entdecken und eine häufige Ursache - neben den Endlosschleifen - für vermeintliche Programmabstürze. Wie kann es nun zu solchen ''race conditions'' kommen? Betrachten wir das mal konkret am Beispiel des '''''OMSI Plugin Framework'''''. Kernelement ist hier eine sogenannte Warteschlange für Nachrichten. Eine Warteschlange ist nichts anderes, als eine Datenstruktur, die auf der einen Seite Elemente entgegen nimmt und am anderen Ende der Schlange wieder ausliefert (FIFO-Prinzip: first in, first out). In einer Single-Thread-Umgebung ist eine solche Warteschlange kein Problem. Anders aber in einer Multithread-Umgebung. Nehmen wir mal den Fall, der OMSI hat gerade '''''AccessVariable''''' aufgerufen. Unter der Herrschaft des Hauptthreads wird nun ein Element an das Ende der Warteschlange gepackt. Noch bevor der Hauptthread damit fertig ist, also die Gesamtanzahl der Nachrichten in der Schlange noch nicht erhöht hat, greift der Nebenthread ebenfalls auf die Warteschlange zu und fragt die Anzahl der Nachrichten ab. Er würde z.B. fälschlicherweise 0 geliefert bekommen. Das ist allerdings der harmlosere Fall. Betrachten wir das Ganze jetzt mal von der anderen Seite. Der Nebenthread holt gerade die erste Nachricht aus der Warteschlange ab und entfernt sie aus der Schlange. Just in diesem Moment packt der Hauptthread eine neue Nachricht am anderen Ende in die Warteschlange hinein. Der Nebenthread bekommt davon aber gar nichts mit. Er räumt fein säuberlich den Platz für die eben entfernte&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''''WaitFor''''' ist die Funktion '''''Release'''''. Nach jedem '''''WaitFor''''' muss man '''''Release''''' aufrufen (außer bei einem Thread), sonst kann es zu einem sogenannten ''Deadlock'' im Programm kommen. Ein ''Deadlock'' bedeutet, das zwei (oder mehr) Threads auf die Freigabe ein und derselben Resource warten. Passiert so etwas, kommt das Programm zum Stillstand. Für den Anwender sieht es so aus, als ob das Programm abgestürzt sei. Technisch stimmt das zwar nicht, aber das spielt für den Anwender keine Rolle. Er kann nicht mehr weiter spielen, arbeiten usw. Solche ''race conditions'', also das gegenseitige Warten auf eine Resource sind die große Schwierigkeit bei der Multithread-Programmierung. Sie sind mitunter schwer zu entdecken und eine häufige Ursache - neben den Endlosschleifen - für vermeintliche Programmabstürze. Wie kann es nun zu solchen ''race conditions'' kommen? Betrachten wir das mal konkret am Beispiel des '''''OMSI Plugin Framework'''''. Kernelement ist hier eine sogenannte Warteschlange für Nachrichten. Eine Warteschlange ist nichts anderes, als eine Datenstruktur, die auf der einen Seite Elemente entgegen nimmt und am anderen Ende der Schlange wieder ausliefert (FIFO-Prinzip: first in, first out). In einer Single-Thread-Umgebung ist eine solche Warteschlange kein Problem. Anders aber in einer Multithread-Umgebung. Nehmen wir mal den Fall, der OMSI hat gerade '''''AccessVariable''''' aufgerufen. Unter der Herrschaft des Hauptthreads wird nun ein Element an das Ende der Warteschlange gepackt. Noch bevor der Hauptthread damit fertig ist, also die Gesamtanzahl der Nachrichten in der Schlange noch nicht erhöht hat, greift der Nebenthread ebenfalls auf die Warteschlange zu und fragt die Anzahl der Nachrichten ab. Er würde z.B. fälschlicherweise 0 geliefert bekommen. Das ist allerdings der harmlosere Fall. Betrachten wir das Ganze jetzt mal von der anderen Seite. Der Nebenthread holt gerade die erste Nachricht aus der Warteschlange ab und entfernt sie aus der Schlange. Just in diesem Moment packt der Hauptthread eine neue Nachricht am anderen Ende in die Warteschlange hinein. Der Nebenthread bekommt davon aber gar nichts mit. Er räumt fein säuberlich den Platz für die eben entfernte&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Nachricht. Im Speicher sieht es dann so aus:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Nachricht. Im Speicher sieht es dann so aus:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l46&quot; &gt;Zeile 46:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 46:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;wir eine ''race condition'', die zu einem ''deadlock'' geführt hat. Thread 1 wartet darauf, das Thread 2 fertig wird und umgekehrt.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;wir eine ''race condition'', die zu einem ''deadlock'' geführt hat. Thread 1 wartet darauf, das Thread 2 fertig wird und umgekehrt.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Zusammen mit dem Mutex ergibt sich nun auch eine Verwendung für '''CEvent'''. Ein Event wird in der Programmierung ganz allgemein dazu benutzt, einem Thread irgendetwas zu signalisieren. Und soetwas müssen wir auch im Framework tun. Da ja der Nebenthread die meiste Zeit seines Lebens schläft, wäre es nicht so gut, wenn der Hauptthread einfach die Nachricht in die Warteschlange packt und dann noch womöglich auf die Bearbeitung wartet. Das könnte ein ziemlich langes Warten werden, da so ein Thread einen äußerst festen Schlaf hat. Aber da gibt es ja die Events. Der Schlafzustand des Nebenthreads ist nämlich an ein solches Event gebunden. Nachdem der Hauptthread die Nachricht in die Warteschlange gepackt hat (Zutritt bekommt er ja ohne weiteres, da der Nebenthread ja schläft), ruft er die Funktion '''''Raise''''' des Events auf. Dadurch wird der Nebenthread augenblicklich unsanft aus dem Schlummer gerissen und setzt seine Arbeit fort. Der gleiche Mechanismus wird auch für die Writable-Variablen und Trigger verwendet. Der Hauptthread packt die entsprechende Nachricht in die Warteschlange und legt sich nun seinerseits schlafen. Sobald der Nebenthread die Variable oder den Trigger bearbeitet hat, ruft er wiederum die Funktion '''''Raise''''' eines weiteren Events auf, um damit den Hauptthread wieder zu erwecken.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Zusammen mit dem Mutex ergibt sich nun auch eine Verwendung für '''CEvent'''. Ein Event wird in der Programmierung ganz allgemein dazu benutzt, einem Thread irgendetwas zu signalisieren. Und soetwas müssen wir auch im Framework tun. Da ja der Nebenthread die meiste Zeit seines Lebens schläft, wäre es nicht so gut, wenn der Hauptthread einfach die Nachricht in die Warteschlange packt und dann noch womöglich auf die Bearbeitung wartet. Das könnte ein ziemlich langes Warten werden, da so ein Thread einen äußerst festen Schlaf hat. Aber da gibt es ja die Events. Der Schlafzustand des Nebenthreads ist nämlich an ein solches Event gebunden&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, da er die Funktion '''''WaitFor''''' des Events aufgerufen hat&lt;/ins&gt;. Nachdem der Hauptthread die Nachricht in die Warteschlange gepackt hat (Zutritt bekommt er ja ohne weiteres, da der Nebenthread ja schläft), ruft er die Funktion '''''Raise''''' des Events auf. Dadurch wird der Nebenthread augenblicklich unsanft aus dem Schlummer gerissen und setzt seine Arbeit fort. Der gleiche Mechanismus wird auch für die Writable-Variablen und Trigger verwendet. Der Hauptthread packt die entsprechende Nachricht in die Warteschlange und legt sich nun seinerseits schlafen. Sobald der Nebenthread die Variable oder den Trigger bearbeitet hat, ruft er wiederum die Funktion '''''Raise''''' eines weiteren Events auf, um damit den Hauptthread wieder zu erwecken.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Abschließend in diesem Abschnitt noch ein paar Worte zur Klasse CThread. Ein Thread ist nichts anderes als ein Stück Programmcode. Jedes Programm hat mindestens einen Thread. Damit ein Thread ausführbar ist, muss er eine Hauptfunktion besitzen. Der Thread läuft nun solange, bis die Hauptfunktion endet. War das der letzte (oder einzige) Thread des Programmes, endet dann auch das Programm selbst. Da Windows mit C++-Klassen rein gar nichts anfangen kann, ist die Hauptfunktion in zwei Teile aufgegliedert. Der erste Teil, die Funktion '''''ThreadFunction''''' ist der Teil, den Windows zu Gesicht bekommt. Glücklicherweise kann man einer Threadfunktion einen Parameter mitgeben. Dieser Parameter ist im Framework nun ein Zeiger auf die Instanz der Klasse '''CThread'''. Über diesen Zeiger ruft die Funktion '''''ThreadFunction''''' nun den zweiten Teil der Hauptfunktion auf, die Funktion '''''MainLoop'''''. Wie der Name schon andeutet, ist das nun die wirkliche Hauptfunktion. Im Framework wird die Hauptfunktion durch das Setzen des Feldes&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Abschließend in diesem Abschnitt noch ein paar Worte zur Klasse CThread. Ein Thread ist nichts anderes als ein Stück Programmcode. Jedes Programm hat mindestens einen Thread. Damit ein Thread ausführbar ist, muss er eine Hauptfunktion besitzen. Der Thread läuft nun solange, bis die Hauptfunktion endet. War das der letzte (oder einzige) Thread des Programmes, endet dann auch das Programm selbst. Da Windows mit C++-Klassen rein gar nichts anfangen kann, ist die Hauptfunktion in zwei Teile aufgegliedert. Der erste Teil, die Funktion '''''ThreadFunction''''' ist der Teil, den Windows zu Gesicht bekommt. Glücklicherweise kann man einer Threadfunktion einen Parameter mitgeben. Dieser Parameter ist im Framework nun ein Zeiger auf die Instanz der Klasse '''CThread'''. Über diesen Zeiger ruft die Funktion '''''ThreadFunction''''' nun den zweiten Teil der Hauptfunktion auf, die Funktion '''''MainLoop'''''. Wie der Name schon andeutet, ist das nun die wirkliche Hauptfunktion. Im Framework wird die Hauptfunktion durch das Setzen des Feldes&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=774&amp;oldid=prev</id>
		<title>Holmexx am 26. November 2012 um 05:24 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=774&amp;oldid=prev"/>
		<updated>2012-11-26T05:24:31Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 26. November 2012, 05:24 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l15&quot; &gt;Zeile 15:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 15:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Die Arbeitsweise des Frameworks ===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Die Arbeitsweise des Frameworks ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Sobald der OMSI Deine DLL geladen hat, ist Dein Plugin sozusagen Bestandteil des OMSI selbst. Die Aufrufe der 4 Funktionen geschehen somit im Context des OMSI. Um nun der [[OMSI_Plugin_Framework_II#Die_Regel_Nummer_1|Regel Nummer 1]] Rechnung zu tragen, hat das Plugin beim Aufruf der Funktion [[OMSI_Plugin_Framework_III#Die_Funktion_Start|Start]] einen weiteren Thread gestartet, der die Aufrufe der Funktionen [[OMSI_Plugin_Framework_III#Die_Funktion_AccessVariable|AccessVariable]] und [[OMSI_Plugin_Framework_III#Die_Funktion_AccessTrigger|AccessTrigger]] bearbeitet. Das hat für Variablen, auf die nur lesend zugegriffen werden soll den Vorteil, das nur sehr wenig CPU-Zeit für die direkte Bearbeitung der Funktionsaufrufe beansprucht wird. Writable-Variablen und Trigger können davon natürlich nicht profitieren, da ja hier immer auf das Ergebnis der Verarbeitung in Deinem Plugin gewartet werden muss. Für Readonly-Variablen ist noch ein weiterer Beschleunigungsmechanismus implementiert: die Bearbeitungsfunktion in Deinem Plugin wird nur dann aufgerufen, wenn sich der Wert der Variablen seit dem letzten Aufruf verändert hat.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Sobald der OMSI Deine DLL geladen hat, ist Dein Plugin sozusagen Bestandteil des OMSI selbst. Die Aufrufe der 4 Funktionen geschehen somit im Context des OMSI. Um nun der [[OMSI_Plugin_Framework_II#Die_Regel_Nummer_1|Regel Nummer 1]] Rechnung zu tragen, hat das Plugin beim Aufruf der Funktion [[OMSI_Plugin_Framework_III#Die_Funktion_Start|Start]] einen weiteren Thread gestartet, der die Aufrufe der Funktionen [[OMSI_Plugin_Framework_III#Die_Funktion_AccessVariable|AccessVariable]] und [[OMSI_Plugin_Framework_III#Die_Funktion_AccessTrigger|AccessTrigger]] bearbeitet. Das hat für Variablen, auf die nur lesend zugegriffen werden soll den Vorteil, das nur sehr wenig CPU-Zeit für die direkte Bearbeitung der Funktionsaufrufe beansprucht wird. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Writable-Variablen und Trigger können davon natürlich nicht profitieren, da ja hier immer auf das Ergebnis der Verarbeitung in Deinem Plugin gewartet werden muss. Für Readonly-Variablen ist noch ein weiterer Beschleunigungsmechanismus implementiert: die Bearbeitungsfunktion in Deinem Plugin wird nur dann aufgerufen, wenn sich der Wert der Variablen seit dem letzten Aufruf verändert hat.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;An dieser Stelle ein paar Anmerkungen zum Multithreading. Multithreading ist keinesfalls das Allheilmittel gegen schlechte Frameraten. Ganz im Gegenteil. Wenn man es mit dem Multithreading übertreibt, kann man sogar ganz schnell das umgekehrte Ergebnis erreichen: das Programm wird noch langsamer. Der Grund dafür ist, dass der Prozessor genügend Reserven haben muss, um tatsächlich mehrere Threads parallel auszuführen. Ein Threadwechsel kostet - wie soll es auch anders sein - natürlich auch wieder zusätzliche CPU-Zeit. Mit anderen Worten: auf einem älteren AMD Athlon-XP ein Multithread-Programm auszuführen, bringt gar nichts. Erst wenn der Prozessor wenigstens einen zweiten CPU-Kern hat, kann die Ausführung des Programmes deutlich beschleunigt werden. Wir gehen aber jetzt einfach mal davon aus, dass heutzutage mindestens Dual-Cores oder besser in einem Rechner stecken. Wenn ein Spieler den OMSI tatsächlich noch auf einer alten Single-Core-Maschine laufen lässt, wird er a) ja sowieso wenig Freude am OMSI haben und b) sollte er sich überlegen, ob er dann noch Plugins installiert. Das ist der knallharte Kompromiss, den wir mit diesem Framework eingehen.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;An dieser Stelle ein paar Anmerkungen zum Multithreading. Multithreading ist keinesfalls das Allheilmittel gegen schlechte Frameraten. Ganz im Gegenteil. Wenn man es mit dem Multithreading übertreibt, kann man sogar ganz schnell das umgekehrte Ergebnis erreichen: das Programm wird noch langsamer. Der Grund dafür ist, dass der Prozessor genügend Reserven haben muss, um tatsächlich mehrere Threads parallel auszuführen. Ein Threadwechsel kostet - wie soll es auch anders sein - natürlich auch wieder zusätzliche CPU-Zeit. Mit anderen Worten: auf einem älteren AMD Athlon-XP ein Multithread-Programm auszuführen, bringt gar nichts. Erst wenn der Prozessor wenigstens einen zweiten CPU-Kern hat, kann die Ausführung des Programmes deutlich beschleunigt werden. Wir gehen aber jetzt einfach mal davon aus, dass heutzutage mindestens Dual-Cores oder besser in einem Rechner stecken. Wenn ein Spieler den OMSI tatsächlich noch auf einer alten Single-Core-Maschine laufen lässt, wird er a) ja sowieso wenig Freude am OMSI haben und b) sollte er sich überlegen, ob er dann noch Plugins installiert. Das ist der knallharte Kompromiss, den wir mit diesem Framework eingehen.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Weiter gehts mit der Arbeitsweise. Bei Aufrufen von '''AccessVariable''' und '''AccessTrigger''' legt das Plugin eine entsprechende ''Nachricht'' in der internen Nachrichtenwarteschlange ab und weckt dann den zusätzlichen Thread auf. Bis dahin verbraucht dieser Thread keinerlei CPU-Zeit. Ist die Variable ''readonly'', wird die Kontrolle sofort wieder an den OMSI übergeben. Das geht sehr schnell und belastet den OMSI nur wenig. Der jetzt aktivierte zusätzliche Thread startet nun, parallel zum OMSI, die Verarbeitung der Variaben, indem er die Funktion '''''OnMessage''''' in Deinem Plugin aufruft und legt sich danach wieder schlafen. Bei einer Writable-Variablen und einem Trigger wird ebenfalls '''''OnMessage''''' aufgerufen, allerdings muss der OMSI nun auf das Ende der Bearbeitung warten. Diese Schleife wiederholt sich solange, bis der Spieler das Spiel beendet. Von diesen internen Dingen bekommst Du in Deiner '''''OnMessage'''''-Funktion nichts mit. Das eben ist genau der Vorteil eines Frameworks.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Weiter gehts mit der Arbeitsweise. Bei Aufrufen von '''AccessVariable''' und '''AccessTrigger''' legt das Plugin eine entsprechende ''Nachricht'' in der internen Nachrichtenwarteschlange ab und weckt dann den zusätzlichen Thread auf. Bis dahin verbraucht dieser Thread keinerlei CPU-Zeit. Ist die Variable ''readonly'', wird die Kontrolle sofort wieder an den OMSI übergeben. Das geht sehr schnell und belastet den OMSI nur wenig. Der jetzt aktivierte zusätzliche Thread startet nun, parallel zum OMSI, die Verarbeitung der Variaben, indem er die Funktion '''''OnMessage''''' in Deinem Plugin aufruft und legt sich danach wieder schlafen. Bei einer Writable-Variablen und einem Trigger wird ebenfalls '''''OnMessage''''' aufgerufen, allerdings muss der OMSI nun auf das Ende der Bearbeitung warten. Diese Schleife wiederholt sich solange, bis der Spieler das Spiel beendet. Von diesen internen Dingen bekommst Du in Deiner '''''OnMessage'''''-Funktion nichts mit. Das eben ist genau der Vorteil eines Frameworks.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== Die Klassen im Detail ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== CWaitableObject, CEvent, CMutex und CThread ====&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Diese 4 Klassen kapseln Windows-Elemente in einer C++-Klasse. Dies vereinfacht den Zugriff auf diese Elemente. '''CWaitableObject''' ist dabei die Basis für die anderen drei Klassen. Der Name leitet sich davon ab, dass Programmcode im wahrsten Sinne des Wortes auf solche Elemente warten kann. Das wird über die Funktion '''''WaitFor''''' in den Klassen realisiert. In '''CWaitableObject''' ist diese Funktion noch ''abstract'', erst '''CEvent''', '''CMutex''' und '''CThread''' erfüllen sie mit Leben. Der Partner für &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;'''''WaitFor''''' ist die Funktion '''''Release''''''. Nach jedem '''''WaitFor''''' muss man '''''Release''''' aufrufen (außer bei einem Thread), sonst kann es zu einem sogenannten ''Deadlock'' im Programm kommen. Ein ''Deadlock'' bedeutet, das zwei (oder mehr) Threads auf die Freigabe ein und derselben Resource warten. Passiert so etwas, kommt das Programm zum Stillstand. Für den Anwender sieht es so aus, als ob das Programm abgestürzt sei. Technisch stimmt das zwar nicht, aber das spielt für den Anwender keine Rolle. Er kann nicht mehr weiter spielen, arbeiten usw. Solche ''race conditions'', also das gegenseitige Warten auf eine Resource sind die große Schwierigkeit bei der Multithread-Programmierung. Sie sind mitunter schwer zu entdecken und eine häufige Ursache - neben den Endlosschleifen - für vermeintliche Programmabstürze. Wie kann es nun zu solchen ''race conditions'' kommen? Betrachten wir das mal konkret am Beispiel des '''''OMSI Plugin Framework'''''. Kernelement ist hier eine sogenannte Warteschlange für Nachrichten. Eine Warteschlange ist nichts anderes, als eine Datenstruktur, die auf der einen Seite Elemente entgegen nimmt und am anderen Ende der Schlange wieder ausliefert (FIFO-Prinzip: first in, first out). In einer Single-Thread-Umgebung ist eine solche Warteschlange kein Problem. Anders aber in einer Multithread-Umgebung. Nehmen wir mal den Fall, der OMSI hat gerade '''''AccessVariable''''' aufgerufen. Unter der Herrschaft des Hauptthreads wird nun ein Element an das Ende der Warteschlange gepackt. Noch bevor der Hauptthread damit fertig ist, also die Gesamtanzahl der Nachrichten in der Schlange noch nicht erhöht hat, greift der Nebenthread ebenfalls auf die Warteschlange zu und fragt die Anzahl der Nachrichten ab. Er würde z.B. fälschlicherweise 0 geliefert bekommen. Das ist allerdings der harmlosere Fall. Betrachten wir das Ganze jetzt mal von der anderen Seite. Der Nebenthread holt gerade die erste Nachricht aus der Warteschlange ab und entfernt sie aus der Schlange. Just in diesem Moment packt der Hauptthread eine neue Nachricht am anderen Ende in die Warteschlange hinein. Der Nebenthread bekommt davon aber gar nichts mit. Er räumt fein säuberlich den Platz für die eben entfernte&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Nachricht. Im Speicher sieht es dann so aus:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Vor dem Abholen der Nachricht durch den Nebenthread&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:|Nachricht_1|Nachricht_2|Nachricht_3|Letzte_Nachricht|freier_Platz_1|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Nebenthread hat Nachricht geholt, aber noch nicht vollständig aufgeräumt (die Anzahl an Nachrichten beträgt noch 4)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:|Nachricht_2|Nachricht_3|Letzte_Nachricht|freier_Platz_1|freier_Platz_2|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Hauptthread packt neue Nachricht in die Schlange. Da der Nebenthread die Anzahl noch nicht angepasst hat, geht der Hauptthread davon aus, dass noch 4 Nachrichten in der&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Schlange sind&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:|Nachricht_2|Nachricht_3|Letzte_Nachricht|freier_Platz_1|neue_Nachricht|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Und schon ist es passiert. Der Inhalt von ''freier Platz_1'' ist völlig zufällig und kann später, wenn diese ''Nachricht'' durch den Nebenthread abgeholt wird, nur zu irgendwelchem Unfug führen. Das muss also unter allen Umständen vermieden werden. Da kommt nun die Klasse '''CMutex''' ins Spiel. Der Name leitet sich vom englischen ''mutually exclusive'' (sich gegenseitig ausschließend) ab. Mit einem Mutex wird das vorherige Szenario nun wie folgt abgewickelt: Bevor ein Thread Zugriff auf die Warteschlange nimmt, ruft er die '''''WaitFor'''''-Funktion des Mutex auf. Hat eine anderer Thread das bereits vor ihm getan, wird Windows ihm den Zutritt verweigern und der Thread muss warten (daher der Name). Er muss nun solange warten, bis der erste Thread '''''Release''''' aufruft. Vergißt Du nun, die Funktion '''''Release''''' aufzurufen, wird folgendes passieren: Irgendwann ist dieser Thread ja wieder dran und ruft wieder '''''WaitFor''''' auf. Da aber der andere Thread durch das vergessene '''''Release''''' noch immer in '''''WaitFor''''' wartet und sich damit sozusagen einen Platz in der ersten Reihe reserviert hat, wird Windows nun auch diesem Thread den Zutritt verwehren. Da haben &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;wir eine ''race condition'', die zu einem ''deadlock'' geführt hat. Thread 1 wartet darauf, das Thread 2 fertig wird und umgekehrt.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Zusammen mit dem Mutex ergibt sich nun auch eine Verwendung für '''CEvent'''. Ein Event wird in der Programmierung ganz allgemein dazu benutzt, einem Thread irgendetwas zu signalisieren. Und soetwas müssen wir auch im Framework tun. Da ja der Nebenthread die meiste Zeit seines Lebens schläft, wäre es nicht so gut, wenn der Hauptthread einfach die Nachricht in die Warteschlange packt und dann noch womöglich auf die Bearbeitung wartet. Das könnte ein ziemlich langes Warten werden, da so ein Thread einen äußerst festen Schlaf hat. Aber da gibt es ja die Events. Der Schlafzustand des Nebenthreads ist nämlich an ein solches Event gebunden. Nachdem der Hauptthread die Nachricht in die Warteschlange gepackt hat (Zutritt bekommt er ja ohne weiteres, da der Nebenthread ja schläft), ruft er die Funktion '''''Raise''''' des Events auf. Dadurch wird der Nebenthread augenblicklich unsanft aus dem Schlummer gerissen und setzt seine Arbeit fort. Der gleiche Mechanismus wird auch für die Writable-Variablen und Trigger verwendet. Der Hauptthread packt die entsprechende Nachricht in die Warteschlange und legt sich nun seinerseits schlafen. Sobald der Nebenthread die Variable oder den Trigger bearbeitet hat, ruft er wiederum die Funktion '''''Raise''''' eines weiteren Events auf, um damit den Hauptthread wieder zu erwecken.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Abschließend in diesem Abschnitt noch ein paar Worte zur Klasse CThread. Ein Thread ist nichts anderes als ein Stück Programmcode. Jedes Programm hat mindestens einen Thread. Damit ein Thread ausführbar ist, muss er eine Hauptfunktion besitzen. Der Thread läuft nun solange, bis die Hauptfunktion endet. War das der letzte (oder einzige) Thread des Programmes, endet dann auch das Programm selbst. Da Windows mit C++-Klassen rein gar nichts anfangen kann, ist die Hauptfunktion in zwei Teile aufgegliedert. Der erste Teil, die Funktion '''''ThreadFunction''''' ist der Teil, den Windows zu Gesicht bekommt. Glücklicherweise kann man einer Threadfunktion einen Parameter mitgeben. Dieser Parameter ist im Framework nun ein Zeiger auf die Instanz der Klasse '''CThread'''. Über diesen Zeiger ruft die Funktion '''''ThreadFunction''''' nun den zweiten Teil der Hauptfunktion auf, die Funktion '''''MainLoop'''''. Wie der Name schon andeutet, ist das nun die wirkliche Hauptfunktion. Im Framework wird die Hauptfunktion durch das Setzen des Feldes&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;'''''m_bTerminate''''' auf '''true''' beendet. '''CThread''' besitzt, da sie ja von '''CWaitableObject''' abgeleitet ist, auch eine '''''WaitFor'''''-Funktion. Dadurch könnte z.B. ein anderer Thread auf die Beendigung dieses Threads warten. Anders als beim '''CMutex''' muss hier aber kein '''''Release''''' aufgerufen werden. Das übernimmt Windows freundlicherweise für uns. Die Beendigung eines Threads löst automatisch ein ''Release'' aus.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=773&amp;oldid=prev</id>
		<title>Holmexx am 25. November 2012 um 21:08 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=773&amp;oldid=prev"/>
		<updated>2012-11-25T21:08:46Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 25. November 2012, 21:08 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l19&quot; &gt;Zeile 19:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 19:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;An dieser Stelle ein paar Anmerkungen zum Multithreading. Multithreading ist keinesfalls das Allheilmittel gegen schlechte Frameraten. Ganz im Gegenteil. Wenn man es mit dem Multithreading übertreibt, kann man sogar ganz schnell das umgekehrte Ergebnis erreichen: das Programm wird noch langsamer. Der Grund dafür ist, dass der Prozessor genügend Reserven haben muss, um tatsächlich mehrere Threads parallel auszuführen. Ein Threadwechsel kostet - wie soll es auch anders sein - natürlich auch wieder zusätzliche CPU-Zeit. Mit anderen Worten: auf einem älteren AMD Athlon-XP ein Multithread-Programm auszuführen, bringt gar nichts. Erst wenn der Prozessor wenigstens einen zweiten CPU-Kern hat, kann die Ausführung des Programmes deutlich beschleunigt werden. Wir gehen aber jetzt einfach mal davon aus, dass heutzutage mindestens Dual-Cores oder besser in einem Rechner stecken. Wenn ein Spieler den OMSI tatsächlich noch auf einer alten Single-Core-Maschine laufen lässt, wird er a) ja sowieso wenig Freude am OMSI haben und b) sollte er sich überlegen, ob er dann noch Plugins installiert. Das ist der knallharte Kompromiss, den wir mit diesem Framework eingehen.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;An dieser Stelle ein paar Anmerkungen zum Multithreading. Multithreading ist keinesfalls das Allheilmittel gegen schlechte Frameraten. Ganz im Gegenteil. Wenn man es mit dem Multithreading übertreibt, kann man sogar ganz schnell das umgekehrte Ergebnis erreichen: das Programm wird noch langsamer. Der Grund dafür ist, dass der Prozessor genügend Reserven haben muss, um tatsächlich mehrere Threads parallel auszuführen. Ein Threadwechsel kostet - wie soll es auch anders sein - natürlich auch wieder zusätzliche CPU-Zeit. Mit anderen Worten: auf einem älteren AMD Athlon-XP ein Multithread-Programm auszuführen, bringt gar nichts. Erst wenn der Prozessor wenigstens einen zweiten CPU-Kern hat, kann die Ausführung des Programmes deutlich beschleunigt werden. Wir gehen aber jetzt einfach mal davon aus, dass heutzutage mindestens Dual-Cores oder besser in einem Rechner stecken. Wenn ein Spieler den OMSI tatsächlich noch auf einer alten Single-Core-Maschine laufen lässt, wird er a) ja sowieso wenig Freude am OMSI haben und b) sollte er sich überlegen, ob er dann noch Plugins installiert. Das ist der knallharte Kompromiss, den wir mit diesem Framework eingehen.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Weiter gehts mit der Arbeitsweise. Bei Aufrufen von '''AccessVariable''' und '''AccessTrigger''' legt das Plugin eine entsprechende ''Nachricht'' in der internen Nachrichtenwarteschlange ab und weckt dann den zusätzlichen Thread auf. Bis dahin verbraucht dieser Thread keinerlei CPU-Zeit. Ist die Variable ''readonly'', wird die Kontrolle sofort wieder an den OMSI übergeben. Das geht sehr schnell und belastet den OMSI nur wenig. Der jetzt aktivierte zusätzliche Thread startet nun, parallel zum OMSI, die Verarbeitung der Variaben, indem er die Funktion '''''OnMessage''''' in Deinem Plugin aufruft und legt sich danach wieder schlafen. Bei einer Writable-Variablen und einem Trigger wird ebenfalls '''''OnMessage''''' aufgerufen, allerdings muss der OMSI nun auf das Ende der Bearbeitung warten. Diese Schleife wiederholt sich solange, bis der Spieler das Spiel beendet.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Weiter gehts mit der Arbeitsweise. Bei Aufrufen von '''AccessVariable''' und '''AccessTrigger''' legt das Plugin eine entsprechende ''Nachricht'' in der internen Nachrichtenwarteschlange ab und weckt dann den zusätzlichen Thread auf. Bis dahin verbraucht dieser Thread keinerlei CPU-Zeit. Ist die Variable ''readonly'', wird die Kontrolle sofort wieder an den OMSI übergeben. Das geht sehr schnell und belastet den OMSI nur wenig. Der jetzt aktivierte zusätzliche Thread startet nun, parallel zum OMSI, die Verarbeitung der Variaben, indem er die Funktion '''''OnMessage''''' in Deinem Plugin aufruft und legt sich danach wieder schlafen. Bei einer Writable-Variablen und einem Trigger wird ebenfalls '''''OnMessage''''' aufgerufen, allerdings muss der OMSI nun auf das Ende der Bearbeitung warten. Diese Schleife wiederholt sich solange, bis der Spieler das Spiel beendet&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;. Von diesen internen Dingen bekommst Du in Deiner '''''OnMessage'''''-Funktion nichts mit. Das eben ist genau der Vorteil eines Frameworks&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=772&amp;oldid=prev</id>
		<title>Holmexx am 25. November 2012 um 15:00 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=772&amp;oldid=prev"/>
		<updated>2012-11-25T15:00:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 25. November 2012, 15:00 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot; &gt;Zeile 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Das OMSI Plugin Framework ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Das OMSI Plugin Framework ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;:Falls das hier wirklich schon jemand liest: Es ist bereits halb acht abends, aber ich fange trotzdem schon mal an. Morgen (25.11.2012) geht es weiter. Versprochen!&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Allgemeines ===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Allgemeines ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l9&quot; &gt;Zeile 9:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 7:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen gibt es eine ausführliche [http://omsi.sovoma.de/index.html Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen gibt es eine ausführliche [http://omsi.sovoma.de/index.html Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den '''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem [[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;an &lt;/ins&gt;ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den '''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem [[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Außerdem erweitert das '''''OMSI Plugin Framework''''' das ''Microsoft Visual Studio '' noch um einen weiteren Compiler. Dieser Compiler hat die Aufgabe, aus einer sehr einfach aufgebauten Textdatei, die die Variablen- und Triggerdeklaration enthält, zum Einen die .opl-Datei für den OMSI zu generieren und zum Anderen zwei weitere Dateien zu erzeugen, die direkt in den Code Deines Plugins einfließen. Diese beiden Dateien enthalten dann Deine Variablen und Trigger in einer für den C++-Compiler nutzbaren Form.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Außerdem erweitert das '''''OMSI Plugin Framework''''' das ''Microsoft Visual Studio '' noch um einen weiteren Compiler. Dieser Compiler hat die Aufgabe, aus einer sehr einfach aufgebauten Textdatei, die die Variablen- und Triggerdeklaration enthält, zum Einen die .opl-Datei für den OMSI zu generieren und zum Anderen zwei weitere Dateien zu erzeugen, die direkt in den Code Deines Plugins einfließen. Diese beiden Dateien enthalten dann Deine Variablen und Trigger in einer für den C++-Compiler nutzbaren Form.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das ist noch nicht alles. Weiterhin ist eine neue Umgebungsvariable für das Visual Studio vorbereitet, mit der es besonders einfach ist, nach jeder Compilierung die erzeugte DLL und die dazu passende .opl-Datei automatisch in den '''''plugins'''''-Ordner des OMSI zu kopieren.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das ist noch nicht alles. Weiterhin ist eine neue Umgebungsvariable für das Visual Studio vorbereitet, mit der es besonders einfach ist, nach jeder Compilierung die erzeugte DLL und die dazu passende .opl-Datei automatisch in den '''''plugins'''''-Ordner des OMSI zu kopieren.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== Die Arbeitsweise des Frameworks ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Sobald der OMSI Deine DLL geladen hat, ist Dein Plugin sozusagen Bestandteil des OMSI selbst. Die Aufrufe der 4 Funktionen geschehen somit im Context des OMSI. Um nun der [[OMSI_Plugin_Framework_II#Die_Regel_Nummer_1|Regel Nummer 1]] Rechnung zu tragen, hat das Plugin beim Aufruf der Funktion [[OMSI_Plugin_Framework_III#Die_Funktion_Start|Start]] einen weiteren Thread gestartet, der die Aufrufe der Funktionen [[OMSI_Plugin_Framework_III#Die_Funktion_AccessVariable|AccessVariable]] und [[OMSI_Plugin_Framework_III#Die_Funktion_AccessTrigger|AccessTrigger]] bearbeitet. Das hat für Variablen, auf die nur lesend zugegriffen werden soll den Vorteil, das nur sehr wenig CPU-Zeit für die direkte Bearbeitung der Funktionsaufrufe beansprucht wird. Writable-Variablen und Trigger können davon natürlich nicht profitieren, da ja hier immer auf das Ergebnis der Verarbeitung in Deinem Plugin gewartet werden muss. Für Readonly-Variablen ist noch ein weiterer Beschleunigungsmechanismus implementiert: die Bearbeitungsfunktion in Deinem Plugin wird nur dann aufgerufen, wenn sich der Wert der Variablen seit dem letzten Aufruf verändert hat.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;An dieser Stelle ein paar Anmerkungen zum Multithreading. Multithreading ist keinesfalls das Allheilmittel gegen schlechte Frameraten. Ganz im Gegenteil. Wenn man es mit dem Multithreading übertreibt, kann man sogar ganz schnell das umgekehrte Ergebnis erreichen: das Programm wird noch langsamer. Der Grund dafür ist, dass der Prozessor genügend Reserven haben muss, um tatsächlich mehrere Threads parallel auszuführen. Ein Threadwechsel kostet - wie soll es auch anders sein - natürlich auch wieder zusätzliche CPU-Zeit. Mit anderen Worten: auf einem älteren AMD Athlon-XP ein Multithread-Programm auszuführen, bringt gar nichts. Erst wenn der Prozessor wenigstens einen zweiten CPU-Kern hat, kann die Ausführung des Programmes deutlich beschleunigt werden. Wir gehen aber jetzt einfach mal davon aus, dass heutzutage mindestens Dual-Cores oder besser in einem Rechner stecken. Wenn ein Spieler den OMSI tatsächlich noch auf einer alten Single-Core-Maschine laufen lässt, wird er a) ja sowieso wenig Freude am OMSI haben und b) sollte er sich überlegen, ob er dann noch Plugins installiert. Das ist der knallharte Kompromiss, den wir mit diesem Framework eingehen.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Weiter gehts mit der Arbeitsweise. Bei Aufrufen von '''AccessVariable''' und '''AccessTrigger''' legt das Plugin eine entsprechende ''Nachricht'' in der internen Nachrichtenwarteschlange ab und weckt dann den zusätzlichen Thread auf. Bis dahin verbraucht dieser Thread keinerlei CPU-Zeit. Ist die Variable ''readonly'', wird die Kontrolle sofort wieder an den OMSI übergeben. Das geht sehr schnell und belastet den OMSI nur wenig. Der jetzt aktivierte zusätzliche Thread startet nun, parallel zum OMSI, die Verarbeitung der Variaben, indem er die Funktion '''''OnMessage''''' in Deinem Plugin aufruft und legt sich danach wieder schlafen. Bei einer Writable-Variablen und einem Trigger wird ebenfalls '''''OnMessage''''' aufgerufen, allerdings muss der OMSI nun auf das Ende der Bearbeitung warten. Diese Schleife wiederholt sich solange, bis der Spieler das Spiel beendet.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=771&amp;oldid=prev</id>
		<title>Holmexx am 24. November 2012 um 18:48 Uhr</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=771&amp;oldid=prev"/>
		<updated>2012-11-24T18:48:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 24. November 2012, 18:48 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l7&quot; &gt;Zeile 7:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 7:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In diesem Kapitel werde ich den Aufbau und die Arbeitsweise des Frameworks detailliert beschreiben. Vielleicht hast Du dich die ganze Zeit schon gefragt, wozu so ein Framework-Dingens überhaupt gut ist. Ganz allgemein gesagt, soll Dich ein Framework von immer wiederkehrenden Standardaufgaben entlasten und Dir eine einheitliche Schnittstelle bieten, mit der Du bestimmte Aufgaben erledigen kannst. Im Falle des '''''OMSI Plugin Frameworks''''' übernimmt es auch noch einen etwas schwierigeren Teil der Programmierung, das sogenannte Multithreading. Was es damit auf sich hat, wird im Abschnitt [[#Die_Arbeitsweise_des_Frameworks|Arbeitsweise]] näher erläutert.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In diesem Kapitel werde ich den Aufbau und die Arbeitsweise des Frameworks detailliert beschreiben. Vielleicht hast Du dich die ganze Zeit schon gefragt, wozu so ein Framework-Dingens überhaupt gut ist. Ganz allgemein gesagt, soll Dich ein Framework von immer wiederkehrenden Standardaufgaben entlasten und Dir eine einheitliche Schnittstelle bieten, mit der Du bestimmte Aufgaben erledigen kannst. Im Falle des '''''OMSI Plugin Frameworks''''' übernimmt es auch noch einen etwas schwierigeren Teil der Programmierung, das sogenannte Multithreading. Was es damit auf sich hat, wird im Abschnitt [[#Die_Arbeitsweise_des_Frameworks|Arbeitsweise]] näher erläutert.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen gibt es eine ausführliche [http://omsi.sovoma.de/index.&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;php &lt;/del&gt;Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen gibt es eine ausführliche [http://omsi.sovoma.de/index.&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;html &lt;/ins&gt;Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den '''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem [[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den '''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem [[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=770&amp;oldid=prev</id>
		<title>Holmexx: 1. Entwurf</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=770&amp;oldid=prev"/>
		<updated>2012-11-24T18:43:49Z</updated>

		<summary type="html">&lt;p&gt;1. Entwurf&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Version vom 24. November 2012, 18:43 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l5&quot; &gt;Zeile 5:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 5:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Allgemeines ===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Allgemeines ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In diesem Kapitel werde ich den Aufbau und die Arbeitsweise des Frameworks detailliert beschreiben. Vielleicht hast Du dich die ganze Zeit schon&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;In diesem Kapitel werde ich den Aufbau und die Arbeitsweise des Frameworks detailliert beschreiben. Vielleicht hast Du dich die ganze Zeit schon gefragt, wozu so ein Framework-Dingens überhaupt gut ist. Ganz allgemein gesagt, soll Dich ein Framework von immer wiederkehrenden Standardaufgaben entlasten und Dir eine einheitliche Schnittstelle bieten, mit der Du bestimmte Aufgaben erledigen kannst. Im Falle des '''''OMSI Plugin Frameworks''''' übernimmt es auch noch einen etwas schwierigeren Teil der Programmierung, das sogenannte Multithreading. Was es damit auf sich hat, wird im Abschnitt [[#Die_Arbeitsweise_des_Frameworks|Arbeitsweise]] näher erläutert.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;gefragt, wozu so ein Framework-Dingens überhaupt gut ist. Ganz allgemein gesagt, soll Dich ein Framework von immer wiederkehrenden Standardaufgaben&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;entlasten und Dir eine einheitliche Schnittstelle bieten, mit der Du bestimmte Aufgaben erledigen kannst. Im Falle des '''''OMSI Plugin Frameworks'''''&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;übernimmt es auch noch einen etwas schwierigeren Teil der Programmierung, das sogenannte Multithreading. Was es damit auf sich hat, wird im Abschnitt&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[#Die_Arbeitsweise_des_Frameworks|Arbeitsweise]] näher erläutert.&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen gibt es eine ausführliche [http://omsi.sovoma.de/index.php Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;gibt es eine ausführliche [http://omsi.sovoma.de/index.php Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den '''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem [[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;'''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Außerdem erweitert das '''''OMSI Plugin Framework''''' das ''Microsoft Visual Studio '' noch um einen weiteren Compiler. Dieser Compiler hat die Aufgabe,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Außerdem erweitert das '''''OMSI Plugin Framework''''' das ''Microsoft Visual Studio '' noch um einen weiteren Compiler. Dieser Compiler hat die Aufgabe, aus einer sehr einfach aufgebauten Textdatei, die die Variablen- und Triggerdeklaration enthält, zum Einen die .opl-Datei für den OMSI zu generieren und zum Anderen zwei weitere Dateien zu erzeugen, die direkt in den Code Deines Plugins einfließen. Diese beiden Dateien enthalten dann Deine Variablen und Trigger in einer für den C++-Compiler nutzbaren Form.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;aus einer sehr einfach aufgebauten Textdatei, die die Variablen- und Triggerdeklaration enthält, zum Einen die .opl-Datei für den OMSI zu generieren und&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;zum Anderen zwei weitere Dateien zu erzeugen, die direkt in den Code Deines Plugins einfließen. Diese beiden Dateien enthalten dann Deine Variablen und &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Trigger in einer für den C++-Compiler nutzbaren Form.&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das ist noch nicht alles. Weiterhin ist eine neue Umgebungsvariable vorbereitet, mit der es besonders einfach ist, nach jeder Compilierung die erzeugte&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Das ist noch nicht alles. Weiterhin ist eine neue Umgebungsvariable &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;für das Visual Studio &lt;/ins&gt;vorbereitet, mit der es besonders einfach ist, nach jeder Compilierung die erzeugte DLL und die dazu passende .opl-Datei automatisch in den '''''plugins'''''-Ordner des OMSI zu kopieren.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;DLL und die dazu passende .opl-Datei automatisch in den '''''plugins'''''-Ordner des OMSI zu kopieren.&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;----&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=769&amp;oldid=prev</id>
		<title>Holmexx: Die Seite wurde neu angelegt: „== Das OMSI Plugin Framework ==  :Falls das hier wirklich schon jemand liest: Es ist bereits halb acht abends, aber ich fange trotzdem schon mal an. Morgen (25.11…“</title>
		<link rel="alternate" type="text/html" href="http://wiki.omnibussimulator.de/omsiwikineu.de/index.php?title=OMSI_Plugin_Framework_IV&amp;diff=769&amp;oldid=prev"/>
		<updated>2012-11-24T18:36:54Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „== Das OMSI Plugin Framework ==  :Falls das hier wirklich schon jemand liest: Es ist bereits halb acht abends, aber ich fange trotzdem schon mal an. Morgen (25.11…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Das OMSI Plugin Framework ==&lt;br /&gt;
&lt;br /&gt;
:Falls das hier wirklich schon jemand liest: Es ist bereits halb acht abends, aber ich fange trotzdem schon mal an. Morgen (25.11.2012) geht es weiter. Versprochen!&lt;br /&gt;
&lt;br /&gt;
=== Allgemeines ===&lt;br /&gt;
&lt;br /&gt;
In diesem Kapitel werde ich den Aufbau und die Arbeitsweise des Frameworks detailliert beschreiben. Vielleicht hast Du dich die ganze Zeit schon&lt;br /&gt;
gefragt, wozu so ein Framework-Dingens überhaupt gut ist. Ganz allgemein gesagt, soll Dich ein Framework von immer wiederkehrenden Standardaufgaben&lt;br /&gt;
entlasten und Dir eine einheitliche Schnittstelle bieten, mit der Du bestimmte Aufgaben erledigen kannst. Im Falle des '''''OMSI Plugin Frameworks'''''&lt;br /&gt;
übernimmt es auch noch einen etwas schwierigeren Teil der Programmierung, das sogenannte Multithreading. Was es damit auf sich hat, wird im Abschnitt&lt;br /&gt;
[[#Die_Arbeitsweise_des_Frameworks|Arbeitsweise]] näher erläutert.&lt;br /&gt;
&lt;br /&gt;
Das '''''OMSI Plugin Framework''''' besteht aus einer handvoll C++-Klassen, die Deine Variablen und Trigger übersichtlich organisieren, den Umgang mit&lt;br /&gt;
den 4 Funktionen der Plugin-Schnittstelle regeln und eine einheitliche Schnittstelle zur Bearbeitung der Variablen und Trigger schaffen. Für diese Klassen&lt;br /&gt;
gibt es eine ausführliche [http://omsi.sovoma.de/index.php Online-Dokumentation] (in exzellentem Denglisch ;-) verfasst).&lt;br /&gt;
&lt;br /&gt;
Da es kaum möglich ist, von Anfang ein Plugin völlig fehlerfrei zu programmieren (das geht Profis auch nicht anders), gibt es zwei Debug-Hilfen, den &lt;br /&gt;
'''''OMSI Plugin Log Viewer''''' und das '''''OMSI Plugin Variables Display'''''. Das sind zwei eigenständige Programme, deren Bedienung in einem &lt;br /&gt;
[[OMSI_Plugin_Framework_V|extra Kapitel]] erläutert wird.&lt;br /&gt;
&lt;br /&gt;
Außerdem erweitert das '''''OMSI Plugin Framework''''' das ''Microsoft Visual Studio '' noch um einen weiteren Compiler. Dieser Compiler hat die Aufgabe,&lt;br /&gt;
aus einer sehr einfach aufgebauten Textdatei, die die Variablen- und Triggerdeklaration enthält, zum Einen die .opl-Datei für den OMSI zu generieren und&lt;br /&gt;
zum Anderen zwei weitere Dateien zu erzeugen, die direkt in den Code Deines Plugins einfließen. Diese beiden Dateien enthalten dann Deine Variablen und &lt;br /&gt;
Trigger in einer für den C++-Compiler nutzbaren Form.&lt;br /&gt;
&lt;br /&gt;
Das ist noch nicht alles. Weiterhin ist eine neue Umgebungsvariable vorbereitet, mit der es besonders einfach ist, nach jeder Compilierung die erzeugte&lt;br /&gt;
DLL und die dazu passende .opl-Datei automatisch in den '''''plugins'''''-Ordner des OMSI zu kopieren.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
{|style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width:33%&amp;quot; |[[OMSI Plugin Framework III|[zum Kapitel 3]]]&lt;br /&gt;
|align=&amp;quot;center&amp;quot; |[[OMSI Plugin Framework|[zum Inhaltsverzeichnis]]]&lt;br /&gt;
|style=&amp;quot;width:33%&amp;quot; align=&amp;quot;right&amp;quot; |[[OMSI Plugin Framework V|[zum Kapitel 5]]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Holmexx</name></author>
		
	</entry>
</feed>