diff options
| author | Paul Buetow <paul@buetow.org> | 2008-08-10 21:43:31 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2008-08-10 21:43:31 +0000 |
| commit | 4c9cf79770dddfe2b2e7d25ffa61b0116568eadf (patch) | |
| tree | 3d18fc26854ad41d936677aa7f9bf1dd72a87e94 /LaTeX/chapters/implementierung.tex | |
| parent | 49766c20b9c73278fdf2b0078dc57cfb407f8e98 (diff) | |
spell checking
Diffstat (limited to 'LaTeX/chapters/implementierung.tex')
| -rw-r--r-- | LaTeX/chapters/implementierung.tex | 328 |
1 files changed, 164 insertions, 164 deletions
diff --git a/LaTeX/chapters/implementierung.tex b/LaTeX/chapters/implementierung.tex index 9b4379e..8d281ce 100644 --- a/LaTeX/chapters/implementierung.tex +++ b/LaTeX/chapters/implementierung.tex @@ -1,24 +1,24 @@ \chapter{Die Implementierung}
-In diesem Kapitel wird auf die Implementierung des Simulators eingegangen. Der Simulator wurde in der Programmiersprache Java entwickelt. Bei der Betrachtung der Zielgruppe wird klar, dass Java f\"{u}r die gestellte Aufgabe die geigneste Programmiersprache ist. Der Simulator ist somit auf jeder Platform verf\"{u}gbar, f\"{u}r die es die JRE (Java Runtime Environment) gibt und erstreckt sich somit \"{u}ber alle g\"{a}ngigen Betriebssysteme. Da an der Fachhochschule Aachen auch Java gelehrt wird, sollten hier die meisten Studenten auch eigene Erweiterungen, wie eigene Protokolle, entwerfen k\"{o}nnen. Der Simulator wurde mit dem derzeit aktuellsten Java SDK (Software Development Kit) in der Version 6 (1.6) entwickelt.
+In diesem Kapitel wird auf die Implementierung des Simulators eingegangen. Der Simulator wurde in der Programmiersprache Java entwickelt. Bei der Betrachtung der Zielgruppe wird klar, dass Java für die gestellte Aufgabe die geeignetste Programmiersprache ist. Der Simulator ist somit auf jeder Plattform verfügbar, für die es die JRE (Java Runtime Environment) gibt und erstreckt sich somit über alle gängigen Betriebssysteme. Da an der Fachhochschule Aachen auch Java gelehrt wird, sollten hier die meisten Studenten auch eigene Erweiterungen, wie eigene Protokolle, entwerfen können. Der Simulator wurde mit dem derzeit aktuellsten Java SDK (Software Development Kit) in der Version 6 (1.6) entwickelt.
\begin{table}
\fbox{
\begin{tabular}{l|l}
\textbf{Paketname} & \textbf{Beschreibung} \\
\hline
- \textit{core} & Klassen f\"{u}r Prozesse und Nachrichten\\
- \textit{core.time} & Klassen f\"{u}r Zeitformate\\
- \textit{events} & Basisklassen f\"{u}r Ereignisse\\
+ \textit{core} & Klassen für Prozesse und Nachrichten\\
+ \textit{core.time} & Klassen für Zeitformate\\
+ \textit{events} & Basisklassen für Ereignisse\\
\textit{events.implementations} & Implementierungen von Ereignissen\\
\textit{events.internal} & Implementierungen von internen Ereignissen\\
- \textit{exceptions} & Klassen f\"{u}r Fehlerbehandlungen\\
- \textit{prefs} & Klassen f\"{u}r die Einstellungen\\
- \textit{prefs.editors} & Klassen f\"{u}r die Editoren\\
- \textit{protocols} & Basisklassen f\"{u}r Protokolle\\
+ \textit{exceptions} & Klassen für Fehlerbehandlungen\\
+ \textit{prefs} & Klassen für die Einstellungen\\
+ \textit{prefs.editors} & Klassen für die Editoren\\
+ \textit{protocols} & Basisklassen für Protokolle\\
\textit{protocols.implementations} & Implementierungen von Protokollen\\
- \textit{serialize} & Helferklassen f\"{u}r die Serialisierung von Simulationen\\
- \textit{simulator} & Klassen f\"{u}r die GUI und die Visualisierung\\
+ \textit{serialize} & Helferklassen für die Serialisierung von Simulationen\\
+ \textit{simulator} & Klassen für die GUI und die Visualisierung\\
\textit{utils} & Diverse Helferklassen\\
\end{tabular}
}
@@ -26,15 +26,15 @@ In diesem Kapitel wird auf die Implementierung des Simulators eingegangen. Der S \label{tb:Pakete}
\end{table}
-Da es sonst den Rahmen sprengen w\"{u}rde, soll im Folgenden der komplette Quelltext nicht bis in das letzte Detail behandelt werden. Der Quelltext erstreckt sich n\"{a}mlich, einschließlich Kommentare, auf \"{u}ber 15.000 Zeilen und \"{u}ber 61 Dateien. Zudem ist die generierte Quelltext-Dokumentation (Javadoc) \"{u}ber 2MB groß. Alle folgenden UML-Diagramme stellen aufgrund der \"{U}bersichtlichkeit lediglich die wesentlichen Dinge dar. Alle Details lassen sich im Quelltext und der dazugeh\"{o}rigen Dokumentation einsehen. Die Paketstruktur des Quelltextes ist in Tabelle \ref{tb:Pakete} in alphanumerischer Reihenfolge aufgef\"{u}hrt.
+Da es sonst den Rahmen sprengen würde, soll im Folgenden der komplette Quelltext nicht bis in das letzte Detail behandelt werden. Der Quelltext erstreckt sich nämlich, einschließlich Kommentare, auf über 15.000 Zeilen und über 61 Dateien. Zudem ist die generierte Quelltext-Dokumentation (Javadoc) über 2MB groß. Alle folgenden UML-Diagramme stellen aufgrund der Übersichtlichkeit lediglich die wesentlichen Dinge dar. Alle Details lassen sich im Quelltext und der dazugehörigen Dokumentation einsehen. Die Paketstruktur des Quelltextes ist in Tabelle \ref{tb:Pakete} in alphanumerischer Reihenfolge aufgeführt.
\section{Einstellungen und Editoren}
-Eine Simulation ist von einer Vielzahl von Einstellungen abh\"{a}ngig. Da auf diese Einstellungen in den weiteren Teilkapitel sets zur\"{u}ckgegriffen wird, macht es Sinn die dazugeh\"{o}rigen Klassen zuerst zu betrachten.
+Eine Simulation ist von einer Vielzahl von Einstellungen abhängig. Da auf diese Einstellungen in den weiteren Teilkapitel stets zurückgegriffen wird, macht es Sinn die dazugehörigen Klassen zuerst zu betrachten.
\subsection{Einstellungsobjekte}
-Auf Abbilung \ref{fig:PackagePrefs} ist der Aufbau des Pakets \textit{prefs} zu sehen. In einer Instanz der Klasse \textit{VSPrefs} lassen sich viele verschiedene Daten als Variablen f\"{u}r eine sp\"{a}tere Verwendung dynamisch ablegen und stellt somit einen Container f\"{u}r diese Daten dar. In einem \textit{VSPrefs}-Objekt speichert der Simulator alle seine Einstellungen ab. Zudem besitzt jedes Prozessobjekt und jedes Ereignisobjekt f\"{u}r lokale Einstellungen seine eigene Instanz von \textit{VSPrefs}. Sp\"{a}ter wird noch erkl\"{a}rt, dass Protokollobjekte auch als Ereignisse eingesetzt werden. Somit k\"{o}nnen Protokolleinstellungen auch in ein \textit{VSPrefs}-Objekt abgespeichert werden. Selbst Nachrichtenobjekte besitzt hiervon eine eigene Instanz, wobei hier die zu verschickenden Daten abgelegt werden k\"{o}nnen.
+Auf Abbildung \ref{fig:PackagePrefs} ist der Aufbau des Pakets \textit{prefs} zu sehen. In einer Instanz der Klasse \textit{VSPrefs} lassen sich viele verschiedene Daten als Variablen für eine spätere Verwendung dynamisch ablegen und stellt somit einen Container für diese Daten dar. In einem \textit{VSPrefs}-Objekt speichert der Simulator alle seine Einstellungen ab. Zudem besitzt jedes Prozessobjekt und jedes Ereignisobjekt für lokale Einstellungen seine eigene Instanz von \textit{VSPrefs}. Später wird noch erklärt, dass Protokollobjekte auch als Ereignisse eingesetzt werden. Somit können Protokolleinstellungen auch in ein \textit{VSPrefs}-Objekt abgespeichert werden. Selbst Nachrichtenobjekte besitzt hiervon eine eigene Instanz, wobei hier die zu verschickenden Daten abgelegt werden können.
\begin{figure}[h]
\centering
@@ -43,11 +43,11 @@ Auf Abbilung \ref{fig:PackagePrefs} ist der Aufbau des Pakets \textit{prefs} zu \label{fig:PackagePrefs}
\end{figure}
-Jede Variable besteht aus einen Datentypen, einen Variablenamen und einer optionalen Beschreibung sowie einen Wert. Einige Datentypen unterst\"{u}tzen auch die Angabe von Minimum- und Maximumwerten (zum Beispiel besteht eine Prozentangabe aus einen Integerwert zwischen \textit{0} und \textit{100}), was mithilfe der \textit{VSPrefsRestriction}-Klasse implementiert wird. Da man beispielsweise bei Prozent ein \textit{\%} und bei Millisekunden ein \textit{ms} hinter der Variable sehen m\"{o}chte, kann f\"{u}r jede Variable auch ein optionaler Einheiten-String abgespeichert werden.
+Jede Variable besteht aus einen Datentypen, einen Variablennamen und einer optionalen Beschreibung sowie einen Wert. Einige Datentypen unterstützen auch die Angabe von Minimal- und Maximalwerten (zum Beispiel besteht eine Prozentangabe aus einen Integerwert zwischen \textit{0} und \textit{100}), was mithilfe der \textit{VSPrefsRestriction}-Klasse implementiert wird. Da man beispielsweise bei Prozent ein \textit{\%} und bei Millisekunden ein \textit{ms} hinter der Variable sehen möchte, kann für jede Variable auch ein optionaler Einheiten-String abgespeichert werden.
-Eine Variablenbeschreibung wird f\"{u}r die Darstellung im GUI verwendet, w\"{a}hrend der Variablenname eher f\"{u}r die interne Verwendung vom Simulator verwendet wird. Zum Beispiel hat die Variable \textit{message.prob.outage} (Verlustwahrscheinlichkeit einer Nachricht) die Variablenbeschreibung ``Nachrichtenverlustw'keit''. Wenn f\"{u}r eine Variable keine Beschreibung existiert so wird, wie auf Abbildung \ref{fig:SimulationseinstellungenExperten} anhand der Farbvariablen schon gesehen wurde, f\"{u}r die Anzeige einer Variable der Datentyp und der Variablenname verwendet. Variablennamen verwenden die auf Tabelle \ref{tb:VariablenPrefixe} angegebenen Prefixkonventionen. Alle verf\"{u}gbaren Typen wurden bereits in Tabelle \ref{tb:VariablenDatentypen} aufgelistet. \textit{VSPrefs} stellt f\"{u}r alle Variablentypen entsprechende Zugriffsmethoden zur Verf\"{u}gung.
+Eine Variablenbeschreibung wird für die Darstellung im GUI verwendet, während der Variablenname eher für die interne Verwendung vom Simulator verwendet wird. Zum Beispiel hat die Variable \textit{message.prob.outage} (Verlustwahrscheinlichkeit einer Nachricht) die Variablenbeschreibung ``Nachrichtenverlustw'keit''. Wenn für eine Variable keine Beschreibung existiert so wird, wie auf Abbildung \ref{fig:SimulationseinstellungenExperten} anhand der Farbvariablen schon gesehen wurde, für die Anzeige einer Variable der Datentyp und der Variablenname verwendet. Variablennamen verwenden die auf Tabelle \ref{tb:VariablenPrefixe} angegebenen Prefixkonventionen. Alle verfügbaren Typen wurden bereits in Tabelle \ref{tb:VariablenDatentypen} aufgelistet. \textit{VSPrefs} stellt für alle Variablentypen entsprechende Zugriffsmethoden zur Verfügung.
-Im Folgenden werden nicht alle exisierenden Methoden aufgelistet, da diese auch in der Quelltext-Dokumentation eingesehen werden k\"{o}nnen. Die Methoden werden nun nur anhand des Integer-Datentyps verdeutlicht. F\"{u}r alle anderen Typen gilt fast alles analog. F\"{u}r Integer stehen in \textit{VSPrefs} folgende Methoden zur Verf\"{u}gung:
+Im Folgenden werden nicht alle existierenden Methoden aufgelistet, da diese auch in der Quelltext-Dokumentation eingesehen werden können. Die Methoden werden nun nur anhand des Integer-Datentyps verdeutlicht. Für alle anderen Typen gilt fast alles analog. Für Integer stehen in \textit{VSPrefs} folgende Methoden zur Verfügung:
\begin{itemize}
\setlength{\itemsep}{-2mm}
@@ -73,34 +73,34 @@ Im Folgenden werden nicht alle exisierenden Methoden aufgelistet, da diese auch \hline
\textit{col} & Farbvariablen & \textit{Color: col.background = Color-Objekt}\\
\textit{div} & Diverse versteckte Variablen & \textit{Integer: div.window.loggsize = 300} \\
- \textit{keyevent} & Variablen, die Tastaturk\"{u}rzel definieren & \textit{Integer: keyevent.close = KeyEvent.VK\_C} \\
+ \textit{keyevent} & Variablen, die Tastaturkürzel definieren & \textit{Integer: keyevent.close = KeyEvent.VK\_C} \\
\textit{lang} & Variablen, die Text beinhalten & \textit{String: lang.activate = aktivieren}\\
\textit{message} & Variablen, die Nachrichten betreffen & \textit{Integer: message.prob.outage = 0}\\
\textit{process} & Variablen, die Prozesse betreffen & \textit{Integer: process.prob.crash = 0}\\
\textit{sim} & Allgemeine Simulationsvariablen & \textit{Integer: sim.process.num = 3}\\
\end{tabular}
}
- \caption{Konventionen f\"{u}r Variablennamen-Prefixe in \textit{VSDefautPrefs}}
+ \caption{Konventionen für Variablennamen-Präfixe in \textit{VSDefautPrefs}}
\label{tb:VariablenPrefixe}
\end{table}
-Hierbei stellt \textit{key} den Variablennamen- und \textit{val} den Variablenwert dar. \textit{descr} ist eine optionale Variablenbeschreibung. Es k\"{o}nnen sowohl Java's Integer-Objekte, als auch Java's primitiver Integer-Typ \textit{int} verwendet werden. Ein \textit{int}-Wert wird intern allerdings als Integer-Objekt abgespeichert (f\"{u}r eine sp\"{a}tere Serialisierung, mehr dazu aber sp\"{a}ter) und macht somit keinen großen Unterschied. Die Methode \textit{getIntegerKeySet} gibt alle vorhandenen Integer-Variablennamen (\textit{key}s) als \textit{Set} zur\"{u}ck.
+Hierbei stellt \textit{key} den Variablennamen- und \textit{val} den Variablenwert dar. \textit{descr} ist eine optionale Variablenbeschreibung. Es können sowohl Java's Integer-Objekte, als auch Java's primitiver Integer-Typ \textit{int} verwendet werden. Ein \textit{int}-Wert wird intern allerdings als Integer-Objekt abgespeichert (für eine spätere Serialisierung, mehr dazu aber später) und macht somit keinen großen Unterschied. Die Methode \textit{getIntegerKeySet} gibt alle vorhandenen Integer-Variablennamen (\textit{key}s) als \textit{Set} zurück.
-\textit{VSPrefs} bietet auch eine Reihe von \textit{initInteger}-Methoden an, welche sich von den \textit{setInteger}-Methoden dadurch unterscheiden, dass sie eine Variable nur einen Wert zuweisen, wenn sie vorher noch nicht initialisiert wurde, was durch \textit{setInteger} oder \textit{initInteger} selbst geschehen sein kann. Eine komplette \"{U}bersicht aller Methoden (auch f\"{u}r andere Datentypen) gibt es in der Quelltext-Dokumentation.
+\textit{VSPrefs} bietet auch eine Reihe von \textit{initInteger}-Methoden an, welche sich von den \textit{setInteger}-Methoden dadurch unterscheiden, dass sie eine Variable nur einen Wert zuweisen, wenn sie vorher noch nicht initialisiert wurde, was durch \textit{setInteger} oder \textit{initInteger} selbst geschehen sein kann. Eine komplette Übersicht aller Methoden (auch für andere Datentypen) gibt es in der Quelltext-Dokumentation.
-\textit{VSPrefs} speichert alle Integervariablen in einem \textit{HashMap<String,Integer>}-Objekt ab, wobei der String-Wert den Variablenamen \textit{key} angibt. F\"{u}r die Beschreibung \textit{descr}, den Einheiten-String \textit{unit} sowie m\"{o}glichen Minimum- und Maximumwerte werden separate Instanzen von \textit{HashMap} verwendet. Da alle \textit{HashMap}-Objekte synchronisiert sind, k\"{o}nnen alle Methoden von verschiednenen Threads gleichzeitig verwendet werden.
+\textit{VSPrefs} speichert alle Integervariablen in einem \textit{HashMap<String,Integer>}-Objekt ab, wobei der String-Wert den Variablennamen \textit{key} angibt. Für die Beschreibung \textit{descr}, den Einheiten-String \textit{unit} sowie möglichen Minimal- und Maximalwerte werden separate Instanzen von \textit{HashMap} verwendet. Da alle \textit{HashMap}-Objekte synchronisiert sind, können alle Methoden von verschiednenen Threads gleichzeitig verwendet werden.
-\textit{VSSerializablePrefs} implementiert das Interface \textit{VSSerializable} und kann somit alle enthaltenen Daten in eine Datei abspeichern beziehungsweiseladen. Auf die Serialisierung und Deserialisierung von Simulationen wird sp\"{a}ter genauer eingegangen.
+\textit{VSSerializablePrefs} implementiert das Interface \textit{VSSerializable} und kann somit alle enthaltenen Daten in eine Datei abspeichern beziehungsweise laden. Auf die Serialisierung und Deserialisierung von Simulationen wird später genauer eingegangen.
-Die Klasse \textit{VSDefaultPrefs} erweitert \textit{VSSerializablePrefs} und initialisiert bei Instanzierung automatisch alle verf\"{u}gbaren Simulationsvariablen mit ihren Standardwerten. Dort sind auch alle Spracheinstellungen abgelegt. Sollte jemand den Simulator in eine andere Sprache, zum Beispiel ins Englische, \"{u}bersetzen wollen, so muß er lediglich diese Datei und die Protokoll-Klassen (mehr dazu sp\"{a}ter) editieren. Die Spracheinstellungen sind n\"{a}mlich in einem \textit{VSPrefs}--Objekt als versteckte String-Variablen abgespeichert. Spracheinstellungen f\"{u}r Protokolle wurden in den Protokollklassen direkt angegeben, da dies mehr Komfort f\"{u}r den Protokollentwickler bietet und f\"{u}r jede neue Textausgabe nicht st\"{a}ndig \textit{VSDefaultPrefs.java} editiert werden muss.
+Die Klasse \textit{VSDefaultPrefs} erweitert \textit{VSSerializablePrefs} und initialisiert bei Instantiierung automatisch alle verfügbaren Simulationsvariablen mit ihren Standardwerten. Dort sind auch alle Spracheinstellungen abgelegt. Sollte jemand den Simulator in eine andere Sprache, zum Beispiel ins Englische, übersetzen wollen, so muß er lediglich diese Datei und die Protokoll-Klassen (mehr dazu später) editieren. Die Spracheinstellungen sind nämlich in einem \textit{VSPrefs}--Objekt als versteckte String-Variablen abgespeichert. Spracheinstellungen für Protokolle wurden in den Protokollklassen direkt angegeben, da dies mehr Komfort für den Protokollentwickler bietet und für jede neue Textausgabe nicht ständig \textit{VSDefaultPrefs.java} editiert werden muss.
Alle Variablen die als Prefix \textit{lang}, \textit{keyevent}, \textit{div} oder \textit{col} im Namen tragen, sind versteckte Variablen und werden in einem Editor nicht angezeigt. Im Expertenmodus sind hingegen nur Variablen die mit \textit{lang} und \textit{keyevent} beginnen versteckt. Somit lassen sich im Expertenmodus weitere Variablen vom Anwender editieren.
\subsection{Editorobjekte}
-Wie Variablen intern abgespeichert werden ist bereits bekannt. F\"{u}r das Editieren der Variablen werden Editor-Objekte verwendet. Auf Abbildung \ref{fig:PackagePrefsEditors} ist die Klassenstruktur des dazugeh\"{o}rigen Paketes \textit{prefs.editors} angegeben.
+Wie Variablen intern abgespeichert werden ist bereits bekannt. Für das Editieren der Variablen werden Editor-Objekte verwendet. Auf Abbildung \ref{fig:PackagePrefsEditors} ist die Klassenstruktur des dazugehörigen Paketes \textit{prefs.editors} angegeben.
-Die Basis eines Editors stellt die abstrakte Klasse \textit{VSAbstractEditor} dar, dem ein \textit{VSPrefs} Objekt zum Editieren \"{u}bergeben wird. Ein Editor stellt alle verf\"{u}gbaren nicht-versteckten Variablen des \textit{VSPrefs}-Objektes im GUI dar und bietet gleichzeitig die M\"{o}glichkeit alle Variablen dar\"{u}ber zu editieren an. F\"{u}r das Editieren von Farbwerten wird auf \textit{VSColorChooser} zur\"{u}ckgegriffen. Die Klasse \textit{VSEditorTable} ist f\"{u}r das \textit{JTable}-Objekt aus Java's Swing-Bibliothek zust\"{a}ndig, welches bei der graphischen Darstellung aller Variablen eingesetzt wird. Die abstrakte Klasse \textit{VSAbstractBetterEditor} wurde, wegen der \"{U}bersicht, als Zwischenschritt eingef\"{u}gt.
+Die Basis eines Editors stellt die abstrakte Klasse \textit{VSAbstractEditor} dar, dem ein \textit{VSPrefs} Objekt zum Editieren übergeben wird. Ein Editor stellt alle verfügbaren nicht-versteckten Variablen des \textit{VSPrefs}-Objektes im GUI dar und bietet gleichzeitig die Möglichkeit alle Variablen darüber zu editieren an. Für das Editieren von Farbwerten wird auf \textit{VSColorChooser} zurückgegriffen. Die Klasse \textit{VSEditorTable} ist für das \textit{JTable}-Objekt aus Java's Swing-Bibliothek zuständig, welches bei der graphischen Darstellung aller Variablen eingesetzt wird. Die abstrakte Klasse \textit{VSAbstractBetterEditor} wurde, wegen der Übersicht, als Zwischenschritt eingefügt.
\begin{figure}[h]
\centering
@@ -109,13 +109,13 @@ Die Basis eines Editors stellt die abstrakte Klasse \textit{VSAbstractEditor} da \label{fig:PackagePrefsEditors}
\end{figure}
-Die Klasse \textit{VSSimulatorEditor} dient f\"{u}r das Editieren der globalen Simulationseinstellungen und \textit{VSProcessEditor} f\"{u}r das Editieren der Prozesseinstellungen sowie der dazugeh\"{o}rigen Protokollvariablen. Da diese beiden Klassen von \textit{VSAbstractBetterEditor} erben, k\"{o}nnen sie mithilfe von \textit{VSEditorFrame} in einem separaten Fenster angezeigt werden. Alternativ k\"{o}nnen die Editoren auch in der Sidebar im Tab ``Variablen'' angezeigt werden. Auf Abbildung \ref{fig:Simulationseinstellungen} wurde bereits ein \textit{VSEditorFrame} in Aktion gesehen. Auf Abbildung \ref{fig:NeueSimulationVariablen} wurde hingegen ein Prozesseditor in der Sidebar ge\"{o}ffnet. F\"{u}r Protokolle gibt es keine separate Editor-Klasse, da sie bereits vom Prozesseditor aus editiert werden k\"{o}nnen. Dabei iteriert der Prozesseditor \"{u}ber alle f\"{u}r den jeweiligen Prozess verf\"{u}gbaren Protokollobjekte und f\"{u}gt deren Variablen zus\"{a}tzlich in den Prozesseditor ein. Somit erscheinen die Prozess- und die dazugeh\"{o}rigen Protokollvariablen im selben Editor und bieten dem Benutzer so eine bessere \"{U}bersicht.
+Die Klasse \textit{VSSimulatorEditor} dient für das Editieren der globalen Simulationseinstellungen und \textit{VSProcessEditor} für das Editieren der Prozesseinstellungen sowie der dazugehörigen Protokollvariablen. Da diese beiden Klassen von \textit{VSAbstractBetterEditor} erben, können sie mithilfe von \textit{VSEditorFrame} in einem separaten Fenster angezeigt werden. Alternativ können die Editoren auch in der Sidebar im Tab ``Variablen'' angezeigt werden. Auf Abbildung \ref{fig:Simulationseinstellungen} wurde bereits ein \textit{VSEditorFrame} in Aktion gesehen. Auf Abbildung \ref{fig:NeueSimulationVariablen} wurde hingegen ein Prozesseditor in der Sidebar geöffnet. Für Protokolle gibt es keine separate Editor-Klasse, da sie bereits vom Prozesseditor aus editiert werden können. Dabei iteriert der Prozesseditor über alle für den jeweiligen Prozess verfügbaren Protokollobjekte und fügt deren Variablen zusätzlich in den Prozesseditor ein. Somit erscheinen die Prozess- und die dazugehörigen Protokollvariablen im selben Editor und bieten dem Benutzer so eine bessere Übersicht.
\section{Ereignisse}
\subsection{Funktionsweise von Ereignissen}
-F\"{u}r jedes Ereignis existiert eine dazugeh\"{o}rige Klasse, welche die auszuf\"{u}hrenden Aktionen implementiert. Eine Instanz davon wird f\"{u}r eine sp\"{a}tere Ausf\"{u}hrung dem Task-Manager \"{u}bergeben. Auf den Task-Manager wird sp\"{a}ter noch genauer eingegangen.
+Für jedes Ereignis existiert eine dazugehörige Klasse, welche die auszuführenden Aktionen implementiert. Eine Instanz davon wird für eine spätere Ausführung dem Task-Manager übergeben. Auf den Task-Manager wird später noch genauer eingegangen.
\begin{figure}[h]
\centering
\includegraphics[width=13.5cm]{images/events}
@@ -123,58 +123,58 @@ F\"{u}r jedes Ereignis existiert eine dazugeh\"{o}rige Klasse, welche die auszuf \label{fig:PackageEvents}
\end{figure}
-Jedes programmierbare Ereignis muß, bevor es vom Simulator verwendet werden kann, in der statischen Klasse \textit{VSRegisteredEvents} registriert werden. Da sich die Anzahl der verf\"{u}gbaren Ereignisklassen des Simulators bei Laufzeit nicht \"{a}ndert, gibt es keine Instanzen von \textit{VSRegisteredEvents}. Alle Methoden und Klassenattribute sind hier statisch. Wenn beispielsweise eigene Ereignisse implementiert werden, dann m\"{u}ssen alle neuen Ereignisse per Hand in die Datei \textit{VSRegisteredEvents.java} \"{u}bernommen- und der Simulator neu kompiliert werden.
+Jedes programmierbare Ereignis muß, bevor es vom Simulator verwendet werden kann, in der statischen Klasse \textit{VSRegisteredEvents} registriert werden. Da sich die Anzahl der verfügbaren Ereignisklassen des Simulators bei Laufzeit nicht ändert, gibt es keine Instanzen von \textit{VSRegisteredEvents}. Alle Methoden und Klassenattribute sind hier statisch. Wenn beispielsweise eigene Ereignisse implementiert werden, dann müssen alle neuen Ereignisse per Hand in die Datei \textit{VSRegisteredEvents.java} übernommen- und der Simulator neu kompiliert werden.
In der Implementierung wird zwischen drei Haupttypen von Ereignissen unterschieden, die jeweils in verschiedenen Paketen liegen (Abbildung \ref{fig:PackageEvents}):
\begin{enumerate}
- \item \textit{events.implementations}: In diesem Paket befinden sich alle Ereignisse, die ohne weitere Spezialbehanldung vom Simulator eingesetzt werden k\"{o}nnen und vom Benutzer direkt im Ereigniseditor programmierbar sind.
+ \item \textit{events.implementations}: In diesem Paket befinden sich alle Ereignisse, die ohne weitere Spezialbehandlung vom Simulator eingesetzt werden können und vom Benutzer direkt im Ereigniseditor programmierbar sind.
\begin{itemize}
- \item \textit{VSProcessCrashEvent}: Dieses Ereignis l\"{a}sst den dazugeh\"{o}rigen Prozess abst\"{u}rzen.
- \item \textit{VSProcessRecoverEvent}: Dieses Ereignis l\"{a}sst den dazugeh\"{o}rigen Prozess wiederbeleben.
+ \item \textit{VSProcessCrashEvent}: Dieses Ereignis lässt den dazugehörigen Prozess abstürzen.
+ \item \textit{VSProcessRecoverEvent}: Dieses Ereignis lässt den dazugehörigen Prozess wiederbeleben.
\end{itemize}
- \item \textit{events.internal}: In diesem Paket befinden sich alle Ereignisse, die vom Simulator intern verwendet werden. Bevor der Simulator von diesen Ereignissen gebrauch machen kann, muss er vorher einige Spezialbehandlungen durchf\"{u}hren.
+ \item \textit{events.internal}: In diesem Paket befinden sich alle Ereignisse, die vom Simulator intern verwendet werden. Bevor der Simulator von diesen Ereignissen Gebrauch machen kann, muss er vorher einige Spezialbehandlungen durchführen.
\begin{itemize}
- \item \textit{VSAbstractInternalEvent}: Diese Klasse stellt weitere Methoden zur Verf\"{u}gung, die von allen internen Ereignissen ben\"{o}tigt werden. Derzeit betrifft dies nur Methoden zur Serialisierung der gegebenen Objekte. Auf die Serialisierung (Abspeichern/Laden) von Simulationen wird sp\"{a}ter noch genauer eingegangen.
- \item \textit{VSMessageReceiveEvent}: Diese Klasse wird f\"{u}r die Ankunft einer Nachricht bei einem Empf\"{a}ngerprozess ben\"{o}tigt. Sie kapselt die eigentliche Nachricht und \"{u}berpr\"{u}ft, ob der Empf\"{a}ngerprozess das zur Nachricht dazugeh\"{o}rige Protokoll versteht. Diese Klasse \"{u}berpr\"{u}ft auch die Simulationseinstellung ``Nur relevante Nachrichten anzeigen'' und entscheidet, ob die Nachricht nach Eintreffen in der Visualisierung und im Loggfenster ber\"{u}cksichtigt werden soll oder nicht.
- \item \textit{VSProtocolEvent}: Diese Klasse implementiert gleichzeitig vier verschiedene Ereignisse: Das Aktivieren/Deaktivieren eines Servers/Clients eines gegebenen Protokolls. Der Ereigniseditor berechnet anhand der verf\"{u}gbaren Protokolle automatisch alle m\"{o}glichen Kombinationen und bietet sie dem Anwender in seiner Auswahl an. F\"{u}r alle dieser vier Ereignisse wird jeweils ein Objekt von \textit{VSProtocolEvent} verwendet, jedoch mit jeweils anderen Attributwerten.
- \item \textit{VSProtocolScheduleEvent}: Diese Klasse wird f\"{u}r die Wecker-Ereignisse ben\"{o}tigt. Wecker-Ereignisse k\"{o}nnen nur von Protokollen (mehr dazu sp\"{a}ter) erstellt werden. \textit{VSProtocolScheduleEvent} besitzt eine Referenz auf das gegebene Protokoll und ruft bei Ereigniseintrittszeit entweder die Methode \textit{onServerScheduleStart} bei einem Server- oder \textit{onClientScheduleStart} bei einem Clientprotokoll auf.
+ \item \textit{VSAbstractInternalEvent}: Diese Klasse stellt weitere Methoden zur Verfügung, die von allen internen Ereignissen benötigt werden. Derzeit betrifft dies nur Methoden zur Serialisierung der gegebenen Objekte. Auf die Serialisierung (Abspeichern/Laden) von Simulationen wird später noch genauer eingegangen.
+ \item \textit{VSMessageReceiveEvent}: Diese Klasse wird für die Ankunft einer Nachricht bei einem Empfangsprozess benötigt. Sie kapselt die eigentliche Nachricht und überprüft, ob der Empfangsprozess das zur Nachricht dazugehörige Protokoll versteht. Diese Klasse überprüft auch die Simulationseinstellung ``Nur relevante Nachrichten anzeigen'' und entscheidet, ob die Nachricht nach Eintreffen in der Visualisierung und im Loggfenster berücksichtigt werden soll oder nicht.
+ \item \textit{VSProtocolEvent}: Diese Klasse implementiert gleichzeitig vier verschiedene Ereignisse: Das Aktivieren/Deaktivieren eines Servers/Clients eines gegebenen Protokolls. Der Ereigniseditor berechnet anhand der verfügbaren Protokolle automatisch alle möglichen Kombinationen und bietet sie dem Anwender in seiner Auswahl an. Für alle dieser vier Ereignisse wird jeweils ein Objekt von \textit{VSProtocolEvent} verwendet, jedoch mit jeweils anderen Attributwerten.
+ \item \textit{VSProtocolScheduleEvent}: Diese Klasse wird für die Wecker-Ereignisse benötigt. Wecker-Ereignisse können nur von Protokollen (mehr dazu später) erstellt werden. \textit{VSProtocolScheduleEvent} besitzt eine Referenz auf das gegebene Protokoll und ruft bei Ereigniseintrittszeit entweder die Methode \textit{onServerScheduleStart} bei einem Server- oder \textit{onClientScheduleStart} bei einem Clientprotokoll auf.
\end{itemize}
- \item \textit{protocols.implementations}: In diesem Paket befinden sich alle Protokollimplementierung. Jedes Protokoll besitzt hier seine eigene Klasse. Alle Protokolle erben hierbei von der auf Abbildung \ref{fig:PackageEvents} zu sehenden Klasse \textit{protocols.VSAbstractProtocol}. Da \textit{protocols.VSAbstractProtocol} von \textit{events.VSAbstractEvent} erbt, kann ein Protokollobjekt auch als Ereignis eingesetzt werden. Ein solches Ereignis ruft bei Eintritt entweder die Methode \textit{onServerStart} oder die Methode \textit{onClientStart} des Protokolls auf, was einer Server- beziehungsweise einer Clientanfrage entspricht. Die Implementierung von Protokollen wird sp\"{a}ter genauer behandelt.
+ \item \textit{protocols.implementations}: In diesem Paket befinden sich alle Protokollimplementierung. Jedes Protokoll besitzt hier seine eigene Klasse. Alle Protokolle erben hierbei von der auf Abbildung \ref{fig:PackageEvents} zu sehenden Klasse \textit{protocols.VSAbstractProtocol}. Da \textit{protocols.VSAbstractProtocol} von \textit{events.VSAbstractEvent} erbt, kann ein Protokollobjekt auch als Ereignis eingesetzt werden. Ein solches Ereignis ruft bei Eintritt entweder die Methode \textit{onServerStart} oder die Methode \textit{onClientStart} des Protokolls auf, was einer Server- beziehungsweise einer Clientanfrage entspricht. Die Implementierung von Protokollen wird später genauer behandelt.
\end{enumerate}
-Alle Ereignisse, die das Interface \textit{VSCopyableEvent} implementieren, k\"{o}nnen vom Anwender im Ereigniseditor mit einem Rechtsklick kopiert werden und m\"{u}ssen die Methode \textit{initCopy(VSAbstractEvent copy)} implementieren. Dort werden dann alle relevanten Attribute in das neue Ereignis \textit{copy} kopiert.
+Alle Ereignisse, die das Interface \textit{VSCopyableEvent} implementieren, können vom Anwender im Ereigniseditor mit einem Rechtsklick kopiert werden und müssen die Methode \textit{initCopy(VSAbstractEvent copy)} implementieren. Dort werden dann alle relevanten Attribute in das neue Ereignis \textit{copy} kopiert.
-Alle Ereignisklassen erweitern die abstrakte Klasse \textit{VSAbstractEvent} und m\"{u}ssen folgende abstrakten Methoden implementieren:
+Alle Ereignisklassen erweitern die abstrakte Klasse \textit{VSAbstractEvent} und müssen folgende abstrakten Methoden implementieren:
\begin{itemize}
- \item \textit{abstract public void onInit()}: Bevor ein Ereignisobjekt vom Simulator verwendet werden kann, muß es initialisiert werden. Je nach Ereignis k\"{o}nnen hier verschiedene Werte initialisiert werden. Diese Methode wird pro Ereignisobjekt nach Erstellung nur ein einziges Mal ausgef\"{u}hrt.
- \item \textit{abstract public void onStart()}: Diese Methode wird jedes Mal ausgef\"{u}hrt, wenn das Ereignis eintritt. Sie stellt somit das Kernst\"{u}ck eines Ereignisses dar.
+ \item \textit{abstract public void onInit()}: Bevor ein Ereignisobjekt vom Simulator verwendet werden kann, muß es initialisiert werden. Je nach Ereignis können hier verschiedene Werte initialisiert werden. Diese Methode wird pro Ereignisobjekt nach Erstellung nur ein einziges Mal ausgeführt.
+ \item \textit{abstract public void onStart()}: Diese Methode wird jedes Mal ausgeführt, wenn das Ereignis eintritt. Sie stellt somit das Kernstück eines Ereignisses dar.
\end{itemize}
Des Weiteren werden folgende nicht-abstrakte Methoden von \textit{VSAbstractEvent} vererbt:
\begin{itemize}
\item \textit{public void logg(String message)}: Diese Methode schreibt eine Loggnachricht in das Simulationsloggfenster.
- \item \textit{public VSAbstractEvent getCopy()}: Diese Methode erstellt vom aktuellen Ereignis eine Kopie, worauf eine Referenz zur\"{u}ckgegeben wird. Alle Ereignisse die kopiert werden k\"{o}nnen m\"{u}ssen ebenso das Interface \textit{VSCopyableEvent} implementieren. Wenn ein Ereignis dies nicht tut und \textit{getCopy()} aufgerufen wird, dann wird von Java die Ausnahme \textit{exceptions.VSEventNotCopyable} geworfen.
+ \item \textit{public VSAbstractEvent getCopy()}: Diese Methode erstellt vom aktuellen Ereignis eine Kopie, worauf eine Referenz zurückgegeben wird. Alle Ereignisse die kopiert werden können müssen ebenso das Interface \textit{VSCopyableEvent} implementieren. Wenn ein Ereignis dies nicht tut und \textit{getCopy()} aufgerufen wird, dann wird von Java die Ausnahme \textit{exceptions.VSEventNotCopyable} geworfen.
\item \textit{public VSAbstractEvent getCopy(VSInternalProcess process)}: Diese Methode erstellt vom aktuellen Ereignis ebenfalls eine Kopie, jedoch mit dem Unterschied, dass das Ereignis einem anderen Prozess zugewiesen wird.
\end{itemize}
-Jede Ereiginsklasse hat außerdem Zugriff auf folgende Attribute, die von \textit{VSAbstractEvent} vererbt werden:
+Jede Ereignisklasse hat außerdem Zugriff auf folgende Attribute, die von \textit{VSAbstractEvent} vererbt werden:
\begin{itemize}
- \item \textit{protected VSPrefs prefs}: Eine Referenz auf das Simulationseinstellungsobjekt. Hier\"{u}ber lassen sich alle Simulationseinstellungen beziehen.
+ \item \textit{protected VSPrefs prefs}: Eine Referenz auf das Simulationseinstellungsobjekt. Hierüber lassen sich alle Simulationseinstellungen beziehen.
\item \textit{protected VSAbstractProcess process}: Eine Referenz auf das Prozessobjekt des jeweiligen Prozesses, auf welches das Ereignis angewendet wird.
\end{itemize}
-Da \textit{VSAbstractEvent} die Klasse \textit{VSSerializablePrefs} erweitert, k\"{o}nnen alle Ereignisse mit allen ihren Variablen serialisiert werden. Hierauf wird sp\"{a}ter nochmal eingegangen.
+Da \textit{VSAbstractEvent} die Klasse \textit{VSSerializablePrefs} erweitert, können alle Ereignisse mit allen ihren Variablen serialisiert werden. Hierauf wird später nochmal eingegangen.
\subsection{Beispielimplementierung eines Ereignisses}
-Im Folgenden wird als Beispiel die Implementierung des Prozessabsturzereignisses \textit{VSProcessCrashEvent} behandelt. Da die dazugeh\"{o}rige Klasse keine Attribute besitzt, verbleibt hier auch die \textit{initCopy}-Methode mit leerem Rumpf. Jede Ereignisklasse muss in \textit{onInit()} mit \textit{setClassname} den eigenen Klassennamen mitteilen. In \textit{onStart()} wird das eigentliche Ereignis ausgef\"{u}hrt. Hier wird obligatorisch \"{u}berpr\"{u}ft, ob der Prozess bereits abgest\"{u}rzt (hier eigentlich nicht Notwendig, verbessert aber die Lesbarkeit der Logik) ist und gegebenenfalls wird der Prozess dann zum Absturz bewegt.
+Im Folgenden wird als Beispiel die Implementierung des Prozessabsturzereignisses \textit{VSProcessCrashEvent} behandelt. Da die dazugehörige Klasse keine Attribute besitzt, verbleibt hier auch die \textit{initCopy}-Methode mit leerem Rumpf. Jede Ereignisklasse muss in \textit{onInit()} mit \textit{setClassname} den eigenen Klassennamen mitteilen. In \textit{onStart()} wird das eigentliche Ereignis ausgeführt. Hier wird obligatorisch überprüft, ob der Prozess bereits abgestürzt (hier eigentlich nicht Notwendig, verbessert aber die Lesbarkeit der Logik) ist und gegebenenfalls wird der Prozess dann zum Absturz bewegt.
-Der Task-Manager \"{u}berpr\"{u}ft bereits, ob der Prozess abgest\"{u}rzt ist oder nicht, d.h. ein Ereignis wird bei einem abgest\"{u}rztem Prozess gar nicht erst ausgef\"{u}hrt. Die einzige Ausnahme bildet ein Wiederbelebungsereignis (\text{VSProcessRecover}), welches vom Task-Manager ausgef\"{u}hrt wird, auch wenn der Prozess abgest\"{u}rzt ist. Mit \textit{logg} wird eine Nachricht (die \"{u}ber \textit{prefs} bezogen wird) in das Loggfenster geschrieben.
+Der Task-Manager überprüft bereits, ob der Prozess abgestürzt ist oder nicht, d.h. ein Ereignis wird bei einem abgestürztem Prozess gar nicht erst ausgeführt. Die einzige Ausnahme bildet ein Wiederbelebungsereignis (\text{VSProcessRecover}), welches vom Task-Manager ausgeführt wird, auch wenn der Prozess abgestürzt ist. Mit \textit{logg} wird eine Nachricht (die über \textit{prefs} bezogen wird) in das Loggfenster geschrieben.
\begin{code}
package events.implementations;
@@ -198,7 +198,7 @@ extends VSAbstractEvent implements VSCopyableEvent { }
\end{code}
-In der Datei \textit{events/VSRegisteredEvents.java} muss in der \textit{init}-Methode f\"{u}r jedes programmierbare Ereignis ein Eintrag existieren. Die \textit{init}-Methode wird einmal beim Starten des Simulators ausgef\"{u}hrt:
+In der Datei \textit{events/VSRegisteredEvents.java} muss in der \textit{init}-Methode für jedes programmierbare Ereignis ein Eintrag existieren. Die \textit{init}-Methode wird einmal beim Starten des Simulators ausgeführt:
\begin{code}
public static void init(VSPrefs prefs_) {
@@ -219,7 +219,7 @@ Als Resultat kann das Prozessabsturzereignis nach Belieben via GUI programmieren \subsection{Funktionsweise}
-Das Paket \textit{core.time} auf Abbildung \ref{fig:PackageCoreTime} stellt lediglich die Klassen f\"{u}r die Vektor- und Lamportzeitstempel zur Verf\"{u}gung. F\"{u}r die normale lokale Prozesszeit wird aus Performancegr\"{u}nden keine eigene Klasse, sondern ein einfaches \textit{long}-Attribut des Prozessobjektes verwendet.
+Das Paket \textit{core.time} auf Abbildung \ref{fig:PackageCoreTime} stellt lediglich die Klassen für die Vektor- und Lamportzeitstempel zur Verfügung. Für die normale lokale Prozesszeit wird aus Performancegründen keine eigene Klasse, sondern ein einfaches \textit{long}-Attribut des Prozessobjektes verwendet.
\begin{figure}[h]
\centering
@@ -228,9 +228,9 @@ Das Paket \textit{core.time} auf Abbildung \ref{fig:PackageCoreTime} stellt ledi \label{fig:PackageCoreTime}
\end{figure}
-Auf Abbildung \ref{fig:PackageCore} ist stark vereinfacht das Paket \textit{core} dargestellt. F\"{u}r jedes auszuf\"{u}hrendes Ereignis wird eine Instanz von \textit{VSTask} ben\"{o}tigt, welche die Ereigniseintrittszeit als Attribut abgespeichert hat sowie eine Referenz auf das Objekt des auszuf\"{u}hrenden Ereignisses (\textit{VSAbstractEvent}) und dem Prozessobjekt besitzt. Geplante \textit{VSTask}-Instanzen werden f\"{u}r eine sp\"{a}tere Ausf\"{u}hrung dem Task-Manager \"{u}bergeben.
+Auf Abbildung \ref{fig:PackageCore} ist stark vereinfacht das Paket \textit{core} dargestellt. Für jedes auszuführendes Ereignis wird eine Instanz von \textit{VSTask} benötigt, welche die Ereigniseintrittszeit als Attribut abgespeichert hat sowie eine Referenz auf das Objekt des auszuführenden Ereignisses (\textit{VSAbstractEvent}) und dem Prozessobjekt besitzt. Geplante \textit{VSTask}-Instanzen werden für eine spätere Ausführung dem Task-Manager übergeben.
-Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-Objekt erlaubt es, dass die selbe \textit{VSAbstractEvent}-Instanz mehrmals auf einmal im Task-Manager geplant werden kann. Ohne dieser Kapselung g\"{a}be es f\"{u}r jedes Ereignis lediglich nur eine einzige m\"{o}gliche Eintrittszeit. Von dieser M\"{o}glichkeit wird zum Beispiel bei den Server- und Clientanfragen eines Protokollobjektes Gebrauch gemacht. F\"{u}r jedes Protokoll kann der Anwender in einer Simulation beliebig viele Anfragen programmieren, wobei f\"{u}r jede Anfrage stets das selbe Protokollobjekt als Ereignis verwendet wird.
+Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-Objekt erlaubt es, dass die selbe \textit{VSAbstractEvent}-Instanz mehrmals auf einmal im Task-Manager geplant werden kann. Ohne dieser Kapselung gäbe es für jedes Ereignis lediglich nur eine einzige mögliche Eintrittszeit. Von dieser Möglichkeit wird zum Beispiel bei den Server- und Clientanfragen eines Protokollobjektes Gebrauch gemacht. Für jedes Protokoll kann der Anwender in einer Simulation beliebig viele Anfragen programmieren, wobei für jede Anfrage stets das selbe Protokollobjekt als Ereignis verwendet wird.
\begin{figure}[h]
\centering
@@ -239,11 +239,11 @@ Die Kapselung eines \textit{VSAbstractEvent}-Objektes in einem \textit{VSTask}-O \label{fig:PackageCore}
\end{figure}
-Jede Simulation besitzt genau eine Instanz von \textit{VSTaskManager}. Eine Instanz dieser Klasse stellt den Task-Manager dar. Er verwaltet alle \textit{VSTask}-Instanzen und \"{u}berpr\"{u}ft periodisch, ob es auszuf\"{u}hrende Ereignisse gibt. Der Task-Manager unterscheidet zwischen globalen und lokalen Ereignissen. Hierbei werden alle globalen Ereignisse (gekapselt in einem \textit{VSTask}-Objekt) in einer Priorit\"{a}ts-Warteschlange abgelegt. Die Priorit\"{a}ts-Warteschlange stellt hierbei die korrekte Ereigniseintrittsreihenfolge sicher. Da sich die lokalen Zeiten aller beteiligten Prozesse voneinander unterscheiden k\"{o}nnen, muss f\"{u}r jeden Prozess eine separate lokale Priorit\"{a}ts-Warteschlange verwendet werden, auf die jedes Prozessobjekt seine eigene Referenz hat. In den lokalen Warteschlangen sind die geplanten lokalen Ereignisse (auch gekapselt in einem \textit{VSTask}-Objekt) abgelegt. Der Task-Manager greift \"{u}ber eine \textit{java.util.ArrayList} auf alle Prozessobjekte zu und kann somit auch auf alle lokalen Warteschlangen zugreifen und verwalten.
+Jede Simulation besitzt genau eine Instanz von \textit{VSTaskManager}. Eine Instanz dieser Klasse stellt den Task-Manager dar. Er verwaltet alle \textit{VSTask}-Instanzen und überprüft periodisch, ob es auszuführende Ereignisse gibt. Der Task-Manager unterscheidet zwischen globalen und lokalen Ereignissen. Hierbei werden alle globalen Ereignisse (gekapselt in einem \textit{VSTask}-Objekt) in einer Prioritäts-Warteschlange abgelegt. Die Prioritäts-Warteschlange stellt hierbei die korrekte Ereigniseintrittsreihenfolge sicher. Da sich die lokalen Zeiten aller beteiligten Prozesse voneinander unterscheiden können, muss für jeden Prozess eine separate lokale Prioritäts-Warteschlange verwendet werden, auf die jedes Prozessobjekt seine eigene Referenz hat. In den lokalen Warteschlangen sind die geplanten lokalen Ereignisse (auch gekapselt in einem \textit{VSTask}-Objekt) abgelegt. Der Task-Manager greift über eine \textit{java.util.ArrayList} auf alle Prozessobjekte zu und kann somit auch auf alle lokalen Warteschlangen zugreifen und verwalten.
-Eine Instanz von \textit{VSMessage} stellt eine Nachricht dar, die von einem Prozess verschickt wird. F\"{u}r jedes Versenden einer Nachricht wird hiervon eine Instanz gebildet, wo der Senderprozess die zu verschickende Daten ablegt. Da \textit{VSMessage} von \textit{VSPrefs} erbt, k\"{o}nnen zwischen zwei Prozessen beliebige Datentypen (Tabelle \ref{tb:VariablenDatentypen}) \"{u}ber eine Nachricht verschickt werden. Anschließend wird f\"{u}r jeden Empf\"{a}ngerprozess das neues Ereignisobjekt der Klasse \textit{VSMessageReceiveEvent} angelegt, welches eine Referenz der verschickten Nachricht besitzt (Abbilung \ref{fig:Wrapping}). Danach wird ein \textit{VSTask}-Objekt instanziert, wo die Referenz auf das Ereignisobjekt und das dazugeh\"{o}rige Prozessobjekt sowie die Ereigniseintrittszeit als Attribute gespeichert werden. Das \textit{VSTask}-Objekt wird dann dem Task-Manager "{u}bergeben, der das dazugeh\"{o}rige Ereignis ausf\"{u}hrt, wenn die Ereigniseintrittszeit eingetroffen ist. Via Java-Polymorphie wird das \textit{VSMessageReceiveEvent}-Objekt in ein \textit{VSAbstractEvent} umgewandelt.
+Eine Instanz von \textit{VSMessage} stellt eine Nachricht dar, die von einem Prozess verschickt wird. Für jedes Versenden einer Nachricht wird hiervon eine Instanz gebildet, wo der Senderprozess die zu verschickende Daten ablegt. Da \textit{VSMessage} von \textit{VSPrefs} erbt, können zwischen zwei Prozessen beliebige Datentypen (Tabelle \ref{tb:VariablenDatentypen}) über eine Nachricht verschickt werden. Anschließend wird für jeden Empfangsprozess das neues Ereignisobjekt der Klasse \textit{VSMessageReceiveEvent} angelegt, welches eine Referenz der verschickten Nachricht besitzt (Abbildung \ref{fig:Wrapping}). Danach wird ein \textit{VSTask}-Objekt instantiiert, wo die Referenz auf das Ereignisobjekt und das dazugehörige Prozessobjekt sowie die Ereigniseintrittszeit als Attribute gespeichert werden. Das \textit{VSTask}-Objekt wird dann dem Task-Manager übergeben, der das dazugehörige Ereignis ausführt, wenn die Ereigniseintrittszeit eingetroffen ist. Via Java-Polymorphie wird das \textit{VSMessageReceiveEvent}-Objekt in ein \textit{VSAbstractEvent} umgewandelt.
-Erw\"{a}hnentswert ist auch die Klasse \textit{VSMessageStub}, welche ein \textit{VSMessage} kapselt. Ihr Zweck ist das Verstecken einiger Methoden vor dem Protokoll-API, welches f\"{u}r die Erstellung eigener Protokolle dient. Der Protokoll-Entwickler soll m\"{o}glichst nichts falsch machen k\"{o}nnen und deswegen soll den Protokoll-API ein eingeschr\"{a}nkter Funktionsumpfang zur Verf\"{u}gung gestellt werden. Da sich \textit{VSMessageStub} im selben Paket wie \textit{VSMessage} befindet, kann \textit{VSMessageStub} auf paket-private Methoden von \textit{VSMessage} zugreifen. Protokolle hingegen werden in einem anderen Paket implementiert und haben somit keinen Zugriff auf diese paket-privaten Methoden. Zwar kann der Protokollentwickler ein eigenes \textit{VSMessageStub}-Objekt anlegen, jedoch kann er auf diese Weise besser unterscheiden auf welche Mehhoden er zugreifen sollte und auf welche nicht. Das Protokoll-API wird sp\"{a}ter genauer behandelt.
+Erwähnenswert ist auch die Klasse \textit{VSMessageStub}, welche ein \textit{VSMessage} kapselt. Ihr Zweck ist das Verstecken einiger Methoden vor dem Protokoll-API, welches für die Erstellung eigener Protokolle dient. Der Protokoll-Entwickler soll möglichst nichts falsch machen können und deswegen soll den Protokoll-API ein eingeschränkter Funktionsumfang zur Verfügung gestellt werden. Da sich \textit{VSMessageStub} im selben Paket wie \textit{VSMessage} befindet, kann \textit{VSMessageStub} auf paket-private Methoden von \textit{VSMessage} zugreifen. Protokolle hingegen werden in einem anderen Paket implementiert und haben somit keinen Zugriff auf diese paket-privaten Methoden. Zwar kann der Protokollentwickler ein eigenes \textit{VSMessageStub}-Objekt anlegen, jedoch kann er auf diese Weise besser unterscheiden auf welche Methoden er zugreifen sollte und auf welche nicht. Das Protokoll-API wird später genauer behandelt.
\begin{figure}[h]
\centering
@@ -252,15 +252,15 @@ Erw\"{a}hnentswert ist auch die Klasse \textit{VSMessageStub}, welche ein \texti \label{fig:Wrapping}
\end{figure}
-Der Task-Manager speichert anschließend in der globalen Warteschlange die Nachrichtenempfangsereignisse. Die Nachricht kommt bei einem Empf\"{a}ngerprozess an, sobald das Ereignis f\"{u}r den Empfang eintritt. F\"{u}r die korrekte Implementierung der Lamport- und Vektor-Zeitstempel wird jeder Nachricht automatisch eine Referenz auf die Lamport- sowie auf die Vektorzeit des sendenden Prozesses als Attribut beigef\"{u}gt. F\"{u}r die \"{U}berpr\"{u}fung des Protokolls wird in jeder Nachricht auch der Klassenname des jeweiligen Protokolls abgespeichert.
+Der Task-Manager speichert anschließend in der globalen Warteschlange die Nachrichtenempfangsereignisse. Die Nachricht kommt bei einem Empfangsprozess an, sobald das Ereignis für den Empfang eintritt. Für die korrekte Implementierung der Lamport- und Vektor-Zeitstempel wird jeder Nachricht automatisch eine Referenz auf die Lamport- sowie auf die Vektorzeit des sendenden Prozesses als Attribut beigefügt. Für die Überprüfung des Protokolls wird in jeder Nachricht auch der Klassenname des jeweiligen Protokolls abgespeichert.
-Eine Instanz von \textit{VSInternalProcess} repr\"{a}sentiert einen simulierten Prozess. Ein \textit{VSInternalProcess} stellt alle vom Simulator intern verwendeten Methoden zur Verf\"{u}gung, w\"{a}hrend ein \textit{VSAbstractProcess} lediglich Methoden hat, die der Protokollentwickler f\"{u}r die Erstellung eigener Protokolle verwenden darf. Da \textit{VSAbstractProcess} abstrakt ist und hiervon keine Instanz gebildet werden darf, muss f\"{u}r einen neuen Prozesses stets ein \textit{VSInternalProcess}-Objekt erstellt werden. Via Polymorphie wird dieses Objekt nach \textit{VSAbstractProcess} umgewandelt und so dem Protokoll-API zur Verf\"{u}gung gestellt. Beispielsweise darf mit \textit{getTasks()} nur vom Simulator intern auf die Priorit\"{a}ts-Warteschlangen zugegriffen werden, w\"{a}hrend man im Protokoll-API selbiges vermeiden sollte und auch gar nicht direkt m\"{o}glich ist. Hierf\"{u}r h\"{a}tte man auch ein Stub-Objekt \textit{VSProcessStub} implementieren k\"{o}nnen. Da aber so gut wie alle paar Millisekunden auf die Methoden von \textit{VSInternalProcess} zugegriffen wird, wurde hier aus Performancegr\"{u}nden der Weg \"{u}ber eine Vererbungungsstufe preferiert.
+Eine Instanz von \textit{VSInternalProcess} repräsentiert einen simulierten Prozess. Ein \textit{VSInternalProcess} stellt alle vom Simulator intern verwendeten Methoden zur Verfügung, während ein \textit{VSAbstractProcess} lediglich Methoden hat, die der Protokollentwickler für die Erstellung eigener Protokolle verwenden darf. Da \textit{VSAbstractProcess} abstrakt ist und hiervon keine Instanz gebildet werden darf, muss für einen neuen Prozesses stets ein \textit{VSInternalProcess}-Objekt erstellt werden. Via Polymorphie wird dieses Objekt nach \textit{VSAbstractProcess} umgewandelt und so dem Protokoll-API zur Verfügung gestellt. Beispielsweise darf mit \textit{getTasks()} nur vom Simulator intern auf die Prioritäts-Warteschlangen zugegriffen werden, während man im Protokoll-API selbiges vermeiden sollte und auch gar nicht direkt möglich ist. Hierfür hätte man auch ein Stub-Objekt \textit{VSProcessStub} implementieren können. Da aber so gut wie alle paar Millisekunden auf die Methoden von \textit{VSInternalProcess} zugegriffen wird, wurde hier aus Performancegründen der Weg über eine Vererbungungsstufe preferiert.
-Alle einstellbaren Prozessvariablen werden von der Klasse \textit{VSPrefs} vererbt. Damit bei Neuberechnungen die Variablen nicht dauernd \"{u}ber eine \textit{HashMap} von \textit{VSPrefs} zugregriffen werden muß, speichert \textit{VSInternalProcess} aus Performancegr\"{u}nden einige Variablen als lokale Kopie ab. Zum Beispiel wird f\"{u}r die lokale Prozesszeit nicht auf das \textit{HashMap<String,Long>}-Objekt von \textit{VSPrefs}, sondern auf das Klassenattribut \textit{private long localTime} zugegriffen. Vor- und nach dem Editieren \"{u}ber den Prozesseditor werden die \textit{VSPrefs} beziehungsweise die lokalen Kopien auf den neusten Stand gebracht. Selbiges gilt f\"{u}r weitere Variablen wie zum Beispiel der Uhrabweichung eines Prozesses.
+Alle einstellbaren Prozessvariablen werden von der Klasse \textit{VSPrefs} vererbt. Damit bei Neuberechnungen die Variablen nicht dauernd über eine \textit{HashMap} von \textit{VSPrefs} zugegriffen werden muß, speichert \textit{VSInternalProcess} aus Performancegründen einige Variablen als lokale Kopie ab. Zum Beispiel wird für die lokale Prozesszeit nicht auf das \textit{HashMap<String,Long>}-Objekt von \textit{VSPrefs}, sondern auf das Klassenattribut \textit{private long localTime} zugegriffen. Vor- und nach dem Editieren über den Prozesseditor werden die \textit{VSPrefs} beziehungsweise die lokalen Kopien auf den neusten Stand gebracht. Selbiges gilt für weitere Variablen wie zum Beispiel der Uhrabweichung eines Prozesses.
-\subsection{Beispiel f\"{u}r die Erstellung von Prozessereignissen}
+\subsection{Beispiel für die Erstellung von Prozessereignissen}
-Anhand der Prozessabsturz- und Wiederbelebungsereignisse l\"{a}ßt sich wie folgt sehr gut demonstieren, wie intern Ereignisse angelegt werden k\"{o}nnen:
+Anhand der Prozessabsturz- und Wiederbelebungsereignisse läßt sich wie folgt sehr gut demonstrieren, wie intern Ereignisse angelegt werden können:
\begin{code}
void createCrashAndRecoverExample(VSTaskManager taskManager,
VSInternalProcess process) {
@@ -276,7 +276,7 @@ void createCrashAndRecoverExample(VSTaskManager taskManager, }
\end{code}
-In diesem Beispiel wurden zwei Ereignisse (Absturz- und Wiederbelebung eines gegebenen Prozesses) angelegt. Das Absturzereignis tritt bei der aktuellen lokalen Prozesszeit plus \textit{500ms} ein, w\"{a}hrend das Wiederbelebungsereignis bei einer globalen Zeit von \textit{2000ms} stattfindet. F\"{u}r den Fall, dass das Wiederbelebungsereignis vor dem Absturzereignis eintritt wird es nicht ausgef\"{u}hrt, da der Prozess noch nicht abgest\"{u}rzt ist.
+In diesem Beispiel wurden zwei Ereignisse (Absturz- und Wiederbelebung eines gegebenen Prozesses) angelegt. Das Absturzereignis tritt bei der aktuellen lokalen Prozesszeit plus \textit{500ms} ein, während das Wiederbelebungsereignis bei einer globalen Zeit von \textit{2000ms} stattfindet. Für den Fall, dass das Wiederbelebungsereignis vor dem Absturzereignis eintritt wird es nicht ausgeführt, da der Prozess noch nicht abgestürzt ist.
\section{Protokolle}
@@ -289,9 +289,9 @@ In diesem Beispiel wurden zwei Ereignisse (Absturz- und Wiederbelebung eines geg \label{fig:PackageProtocols}
\end{figure}
-In diesem Abschnitt wird auf die Implementierung der Protokolle und das Protokoll-API eingegangen. Im Protokoll-API wird in der Regel nicht direkt auf den Task-Manager und auf die explizite instanzierung von Ereignisobjekten zur\"{u}ckgegriffen. Das wird alles vom API automatisch gemacht.
+In diesem Abschnitt wird auf die Implementierung der Protokolle und das Protokoll-API eingegangen. Im Protokoll-API wird in der Regel nicht direkt auf den Task-Manager und auf die explizite Instantiierung von Ereignisobjekten zurückgegriffen. Das wird alles vom API automatisch gemacht.
-Auf Abbildung \ref{fig:PackageProtocols} sind die Pakete \textit{protocols} und \textit{protocols.implementations} dargestellt, welche f\"{u}r die Protokollimplementierungen zust\"{a}ndig sind. \textit{VSAbstractProtocol} stellt lediglich gemeinsame Methoden und Attribute zur Verf\"{u}gung, die von allen Protokollen verwendet werden k\"{o}nnen. Jedes Protokoll hat im Paket \textit{protocols.implementations} seine eigene Klasse, die von \textit{VSAbstractProtocol} erbt. Im Prinzip besitzt jedes Prozessobjekt von jedem Protokoll seine eigene Instanz. Bei \textit{10} Protokollen und \textit{3} beteiligten Prozessen werden also \textit{30} Protokollobjekte verwendet. Jedes Protokollobjekt verwaltet sowohl die Server- als auch die Clientseite eines Protokolls auf einmal. Dabei merkt sich \textit{VSAbstractProtocol} anhand eines Flags ob der aktuelle Kontext server- oder clientbezogen ist und f\"{u}hrt dementsprechen beim Eintreffen von Ereignissen die Server- beziehungsweise Clientmethoden des Protokolls auf. \textit{VSAbstractProtocol} \"{u}berpr\"{u}ft auch, ob ein Client oder ein Server \"{u}berhaupt aktiviert ist.
+Auf Abbildung \ref{fig:PackageProtocols} sind die Pakete \textit{protocols} und \textit{protocols.implementations} dargestellt, welche für die Protokollimplementierungen zuständig sind. \textit{VSAbstractProtocol} stellt lediglich gemeinsame Methoden und Attribute zur Verfügung, die von allen Protokollen verwendet werden können. Jedes Protokoll hat im Paket \textit{protocols.implementations} seine eigene Klasse, die von \textit{VSAbstractProtocol} erbt. Im Prinzip besitzt jedes Prozessobjekt von jedem Protokoll seine eigene Instanz. Bei \textit{10} Protokollen und \textit{3} beteiligten Prozessen werden also \textit{30} Protokollobjekte verwendet. Jedes Protokollobjekt verwaltet sowohl die Server- als auch die Clientseite eines Protokolls auf einmal. Dabei merkt sich \textit{VSAbstractProtocol} anhand eines Flags ob der aktuelle Kontext server- oder clientbezogen ist und führt dementsprechend beim Eintreffen von Ereignissen die Server- beziehungsweise Clientmethoden des Protokolls auf. \textit{VSAbstractProtocol} überprüft auch, ob ein Client oder ein Server überhaupt aktiviert ist.
\begin{figure}[h]
\centering
@@ -300,91 +300,91 @@ Auf Abbildung \ref{fig:PackageProtocols} sind die Pakete \textit{protocols} und \label{fig:Protokollvariablen}
\end{figure}
-Es ist bereits bekannt, dass Protokolle im Prozesseditor editierbare Variablen haben k\"{o}nnen. Da \textit{VSAbstractProtocol} von \textit{VSAbstractEvent} erbt, was wiederum von \textit{VSPrefs} erbt, werden alle Protokollvariablen einfach in die Mutterklasse \textit{VSPrefs} abgelegt. Zum Beispiel kann mit \textit{super.setBoolean(``test'', true);} eine neue Protokollvariable \textit{test} mit dem Standardwert \textit{true} angelegt werden. Diese Variable erscheint dann automatisch im Prozesseditor.
+Es ist bereits bekannt, dass Protokolle im Prozesseditor editierbare Variablen haben können. Da \textit{VSAbstractProtocol} von \textit{VSAbstractEvent} erbt, was wiederum von \textit{VSPrefs} erbt, werden alle Protokollvariablen einfach in die Mutterklasse \textit{VSPrefs} abgelegt. Zum Beispiel kann mit \textit{super.setBoolean(``test'', true);} eine neue Protokollvariable \textit{test} mit dem Standardwert \textit{true} angelegt werden. Diese Variable erscheint dann automatisch im Prozesseditor.
-Da der Simulator daf\"{u}r ausgelegt wurde eigene Protokolle zu implementieren, werden im Folgenden alle verf\"{u}gbaren Protokoll-API-Methoden etwas ausf\"{u}hrlicher als gewohnt beschrieben. Jede Protokollklasse muß die folgenden Methoden implementieren:
+Da der Simulator dafür ausgelegt wurde eigene Protokolle zu implementieren, werden im Folgenden alle verfügbaren Protokoll-API-Methoden etwas ausführlicher als gewohnt beschrieben. Jede Protokollklasse muß die folgenden Methoden implementieren:
\begin{itemize}
\setlength{\itemsep}{-2mm}
- \item Einen \"{o}ffentlichen (\textit{public}) Konstruktor. Der Konstruktor muß angeben, ob bei dem gegebene Protokoll der Client oder der Server die Anfragen startet.
- \item \textit{abstract public void onClientInit()}: Bevor das Protokollobjekt benutzt werden kann, muß es initialisiert werden. Diese Methode wird vor dem ersten Verwenden des Protokolls innerhalb einer Simulation ausgef\"{u}hrt. In der Regel werden hier Protokollvariablen unter Verwendung von \textit{VSPrefs} und Attribute der Protokollklasse initialisiert. Die hier initialisierten Protokollvariablen lassen sich vom Benutzer im Prozesseditor des jeweiligen Prozesses editieren.
- \item \textit{abstract public void onClientReset()}: Dese Methode wird jedes Mal ausgef\"{u}hrt, wenn die Simulation zur\"{u}ckgesetzt wird.
- \item \textit{abstract public void onClientStart()}: Diese Methode wird nur ben\"{o}tigt, wenn der Client immer die Anfragen startet. Diese Methode generiert in der Regel immer eine Clientanfrage, die via \textit{VSMessage}-Objekt an alle anderen beteiligten Prozesse verschickt wird.
- \item \textit{abstract public void onClientRecv(VSMessage message)}: Diese Methode wird jedes Mal Ausgef\"{u}hrt, wenn eine Servernachricht \textit{message} bei dem Client eintrifft.
- \item \textit{abstract public void onClientSchedule()}: Diese Methode wird jedes Mal ausgef\"{u}hrt, wenn ein Weckerereignis eintritt.
+ \item Einen öffentlichen (\textit{public}) Konstruktor. Der Konstruktor muß angeben, ob bei dem gegebene Protokoll der Client oder der Server die Anfragen startet.
+ \item \textit{abstract public void onClientInit()}: Bevor das Protokollobjekt benutzt werden kann, muß es initialisiert werden. Diese Methode wird vor dem ersten Verwenden des Protokolls innerhalb einer Simulation ausgeführt. In der Regel werden hier Protokollvariablen unter Verwendung von \textit{VSPrefs} und Attribute der Protokollklasse initialisiert. Die hier initialisierten Protokollvariablen lassen sich vom Benutzer im Prozesseditor des jeweiligen Prozesses editieren.
+ \item \textit{abstract public void onClientReset()}: Diese Methode wird jedes Mal ausgeführt, wenn die Simulation zurückgesetzt wird.
+ \item \textit{abstract public void onClientStart()}: Diese Methode wird nur benötigt, wenn der Client immer die Anfragen startet. Diese Methode generiert in der Regel immer eine Clientanfrage, die via \textit{VSMessage}-Objekt an alle anderen beteiligten Prozesse verschickt wird.
+ \item \textit{abstract public void onClientRecv(VSMessage message)}: Diese Methode wird jedes Mal Ausgeführt, wenn eine Servernachricht \textit{message} bei dem Client eintrifft.
+ \item \textit{abstract public void onClientSchedule()}: Diese Methode wird jedes Mal ausgeführt, wenn ein Weckerereignis eintritt.
\item \textit{public String toString()}: Diese Methode ist nur optional. Hiermit lassen sich die Loggnachrichten eines Protokolls anpassen. Wenn diese Methode in einer Protokollimplementierung ausgelassen wird, so wird stets die \textit{toString}-Methode der Mutterklasse \textit{VSAbstractProtocol} verwendet.
\end{itemize}
-F\"{u}r alle hier aufgelisteten Client-Methoden sind auch die korespondierenen Server-Methoden anzugeben. Die Server-Methoden sind analog zu den Client-Methoden aufgebaut, wobei lediglich \textit{Client} durch \textit{Server} ausgetauscht werden muß.
+Für alle hier aufgelisteten Client-Methoden sind auch die korrespondierenden Server-Methoden anzugeben. Die Server-Methoden sind analog zu den Client-Methoden aufgebaut, wobei lediglich \textit{Client} durch \textit{Server} ausgetauscht werden muß.
-Jede Protokollklasse bekommt folgende Methoden von \textit{VSAbstractProtocol} vererbt, welche allesamt vom Protokollentwickler verwendet werden k\"{o}nnen:
+Jede Protokollklasse bekommt folgende Methoden von \textit{VSAbstractProtocol} vererbt, welche allesamt vom Protokollentwickler verwendet werden können:
\begin{itemize}
\setlength{\itemsep}{-2mm}
- \item \textit{pubic void sendMessage(VSMessage message)}: Hiermit verchickt das Protokoll eine Nachricht.
- \item \textit{pubic final boolean hasOnServerStart()}: Hiermit l\"{a}ßt sich bestimmen, ob der Server- oder der Client bei dem aktuellen Protokoll die Anfragen startet.
- \item \textit{pubic final boolean isServer()}: Hiermit l\"{a}ßt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll serverseitig aktiviert hat.
- \item \textit{pubic final boolean isClient()}: Hiermit l\"{a}ßt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll clientseitig aktiviert hat.
- \item \textit{pubic final void scheduleAt(long time)}: Diese Methode stellt einen Wecker, der zur angegebenen lokalen Prozesszeit eintritt. Nach Ablauf des Weckers wird, abh\"{a}ngig ob der aktuelle Kontext Client- oder Serverseitig ist, \textit{onClientSchedue} beziehungsweise \textit{onServerSchedule} ausgef\"{u}hrt.
+ \item \textit{pubic void sendMessage(VSMessage message)}: Hiermit verschickt das Protokoll eine Nachricht.
+ \item \textit{pubic final boolean hasOnServerStart()}: Hiermit läßt sich bestimmen, ob der Server- oder der Client bei dem aktuellen Protokoll die Anfragen startet.
+ \item \textit{pubic final boolean isServer()}: Hiermit läßt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll serverseitig aktiviert hat.
+ \item \textit{pubic final boolean isClient()}: Hiermit läßt sich bestimmen, ob der aktuelle Prozess das aktuelle Protokoll clientseitig aktiviert hat.
+ \item \textit{pubic final void scheduleAt(long time)}: Diese Methode stellt einen Wecker, der zur angegebenen lokalen Prozesszeit eintritt. Nach Ablauf des Weckers wird, abhängig ob der aktuelle Kontext Client- oder Serverseitig ist, \textit{onClientSchedue} beziehungsweise \textit{onServerSchedule} ausgeführt.
\item \textit{pubic final void removeSchedules()}: Entfernt alle gesetzten Wecker des aktuellen Kontextes (Server oder Client).
- \item \textit{pubic final int getNumProcesses()}: Gibt die Anzahl an der Simulation beteiligten Prozesse zur\"{u}ck.
+ \item \textit{pubic final int getNumProcesses()}: Gibt die Anzahl an der Simulation beteiligten Prozesse zurück.
\end{itemize}
-Bei der Implementierung von Protokollen k\"{o}nnen zus\"{a}tzlich auf die vererbten Attribute \textit{VSAbstractProcess process} und \textit{VSPrefs prefs} zugegriffen werden. Verf\"{u}gbare Methoden von \textit{VSPrefs} wurden bereits behandelt. \"{U}ber \textit{prefs} lassen sich alle globalen Simulationseinstellungen abrufen (zum Beispiel die Simulationsvariable die Angibt, ob Prozesse eigene Nachrichten empfangen: \textit{bool recvOwn = prefs.getBoolean(``sim.message.own.recv'')}). Folgende Prozessmethoden d\"{u}rfen auf \textit{process} aus dem Protokoll-API verwendet werden:
+Bei der Implementierung von Protokollen können zusätzlich auf die vererbten Attribute \textit{VSAbstractProcess process} und \textit{VSPrefs prefs} zugegriffen werden. Verfügbare Methoden von \textit{VSPrefs} wurden bereits behandelt. über \textit{prefs} lassen sich alle globalen Simulationseinstellungen abrufen (zum Beispiel die Simulationsvariable die Angibt, ob Prozesse eigene Nachrichten empfangen: \textit{bool recvOwn = prefs.getBoolean(``sim.message.own.recv'')}). Folgende Prozessmethoden dürfen auf \textit{process} aus dem Protokoll-API verwendet werden:
\begin{itemize}
\setlength{\itemsep}{-2mm}
- \item \textit{public float getClockVariance()}: Gibt die Uhrabweichung zur\"{u}ck.
+ \item \textit{public float getClockVariance()}: Gibt die Uhrabweichung zurück.
\item \textit{public void setClockVariance(float clockVariance)}: Setzt die Uhrabweichung des Prozesses.
- \item \textit{public long getGlobalTime()}: Gibt die aktuelle globale Simulationszeit zur\"{u}ck.
- \item \textit{public long getTime()}: Gibt die aktuelle lokale Prozesszeit zur\"{u}ck.
+ \item \textit{public long getGlobalTime()}: Gibt die aktuelle globale Simulationszeit zurück.
+ \item \textit{public long getTime()}: Gibt die aktuelle lokale Prozesszeit zurück.
\item \textit{public void setTime(long time)}: Setzt die aktuelle lokale Prozesszeit.
- \item \textit{public long getLamportTime()}: Gibt die aktuelle Lamportzeit des Prozesses zur\"{u}ck.
+ \item \textit{public long getLamportTime()}: Gibt die aktuelle Lamportzeit des Prozesses zurück.
\item \textit{public void setLamportTime(long lamportTime)}: Setzt die aktuelle Lamportzeit des Prozesses.
\item \textit{public void increaseLamportTime()}: Inkrementiert die Lamportzeit um eins.
\item \textit{public void updateLamportTime(long lamportTime)}: Erneuert die Lamportzeit. Siehe Kapitel 2.6.1 wie die Lamportzeiten erneuert werden.
- \item \textit{public VSVectorTime getVectorTime()}: Gibt die aktuelle Vektor-Zeit des Prozesses zur\"{u}ck.
- \item \textit{public VSTime[] getLamportTimeArray()}: Gibt die gesamte Lamportzeitstempelhistorie des Prozesses zur\"{u}ck. Kann jeweils nach VSLamportTime gecastet werden.
- \item \textit{public VSTime getVectorTimeArray()}: Gibt die gesamte Vektor-Zeitstempelhistorie des Prozesses zur\"{u}ck. Kann jeweils nach VSVectorTime gecastet werden.
+ \item \textit{public VSVectorTime getVectorTime()}: Gibt die aktuelle Vektor-Zeit des Prozesses zurück.
+ \item \textit{public VSTime[] getLamportTimeArray()}: Gibt die gesamte Lamportzeitstempelhistorie des Prozesses zurück. Kann jeweils nach VSLamportTime umgewandelt werden.
+ \item \textit{public VSTime getVectorTimeArray()}: Gibt die gesamte Vektor-Zeitstempel-Historie des Prozesses zurück. Kann jeweils nach VSVectorTime umgewandelt werden.
\item \textit{public void updateVectorTime(VSVectorTime vectorTimeUpdate)}: Erneuert die Vektorzeit. Siehe Kapitel 2.6.1 wie die Vektorzeiten erneuert werden.
\item \textit{public void increaseVectorTime()}: Inkrementiert die Vektorzeit an lokalem Index um eins.
- \item \textit{public int getProcessID()}: Gibt die PID zur\"{u}ck.
- \item \textit{public void setProcessID(int processID)}: Setz die PID.
- \item \textit{public int getProcessNum()}: Gibt die Prozessnummer zur\"{u}ck. Dieser Wert unterscheidet sich von der PID. Die Prozessnummer gibt an, um den wievielten Prozess, beginnend bei 0, es sich handelt.
- \item \textit{public int getRandomPercentage()}: Gibt einen Zufallswert zwischen \textit{0} und \textit{100} zur\"{u}ck.
- \item \textit{public boolean hasCrashed()}: Gibt \textit{true} zur\"{u}ck, wenn der Prozess w\"{a}hrend der aktuellen Simulation schonmal abgest\"{u}rzt ist.
- \item \textit{public boolean isCrashed()}: Gibt \textit{true} zur\"{u}ck, wenn der Prozess aktuell abgest\"{u}rzt ist.
- \item \textit{public void isCrashed(boolean isCrashed)}: Hiermit kann man den Prozess abst\"{u}rzen (\textit{isCrashed = true}) und wiederbeleben (\textit{isCrashed = false}) lassen.
+ \item \textit{public int getProcessID()}: Gibt die PID zurück.
+ \item \textit{public void setProcessID(int processID)}: Setzt die PID.
+ \item \textit{public int getProcessNum()}: Gibt die Prozessnummer zurück. Dieser Wert unterscheidet sich von der PID. Die Prozessnummer gibt an, um den wievielten Prozess, beginnend bei 0, es sich handelt.
+ \item \textit{public int getRandomPercentage()}: Gibt einen Zufallswert zwischen \textit{0} und \textit{100} zurück.
+ \item \textit{public boolean hasCrashed()}: Gibt \textit{true} zurück, wenn der Prozess während der aktuellen Simulation schon mal abgestürzt ist.
+ \item \textit{public boolean isCrashed()}: Gibt \textit{true} zurück, wenn der Prozess aktuell abgestürzt ist.
+ \item \textit{public void isCrashed(boolean isCrashed)}: Hiermit kann man den Prozess abstürzen (\textit{isCrashed = true}) und wiederbeleben (\textit{isCrashed = false}) lassen.
\end{itemize}
-In der Regel werden in Protokollen auch Nachrichten (\textit{VSMessage}) verschickt. Folgende Methoden d\"{u}rfen davon im Protokoll-API verwendet werden:
+In der Regel werden in Protokollen auch Nachrichten (\textit{VSMessage}) verschickt. Folgende Methoden dürfen davon im Protokoll-API verwendet werden:
\begin{itemize}
\setlength{\itemsep}{-2mm}
- \item \textit{public VSMessage()}: Der Standardkonstruktor f\"{u}r die Erstellung einer neuen Nachricht.
- \item \textit{public int getmessageID()}: Gibt die Nachrichten-ID zur\"{u}ck.
- \item \textit{public boolean equals(VSMessage message)}: Hiermit l\"{a}ßt sich \"{u}berpr\"{u}fen, ob eine weitere Nachricht die selbe NID besitzt (wobei es sich dann um die selbe Nachricht handeln w\"{u}rde).
+ \item \textit{public VSMessage()}: Der Standardkonstruktor für die Erstellung einer neuen Nachricht.
+ \item \textit{public int getmessageID()}: Gibt die Nachrichten-ID zurück.
+ \item \textit{public boolean equals(VSMessage message)}: Hiermit läßt sich überprüfen, ob eine weitere Nachricht die selbe NID besitzt (wobei es sich dann um die selbe Nachricht handeln würde).
\end{itemize}
-Folgende weitere Methoden von \textit{VSMessage} k\"{o}nnen bei Erhalt einer Nachricht verwendet werden:
+Folgende weitere Methoden von \textit{VSMessage} können bei Erhalt einer Nachricht verwendet werden:
\begin{itemize}
\setlength{\itemsep}{-2mm}
- \item \textit{public String getName()}: Gibt den Namen des zur Nachricht dazugeh\"{o}rigen Protokolls zur\"{u}ck. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
- \item \textit{public String getProtocolClassname()}: Gibt den Klassennamen des zur Nachricht dazugeh\"{o}rigen Protokolls zur\"{u}ck. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
- \item \textit{public VSAbstractProcess getSendingProcess()}: Gibt eine Referenz auf den Senderprozess zur\"{u}ck. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
- \item \textit{public long getLamportTime()}: Gibt die Lamportzeit des Senderprozesses zur\"{u}ck. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
- \item \textit{public VSVectorTime getLamportTime()}: Gibt die Vektorzeit des Senderprozesses zur\"{u}ck. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
- \item \textit{public boolean isServerMessage()}: Hiermit l\"{a}ßt sich entscheiden, ob es sich um eine Server- oder eine Clientnachricht handelt. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public String getName()}: Gibt den Namen des zur Nachricht dazugehörigen Protokolls zurück. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public String getProtocolClassname()}: Gibt den Klassennamen des zur Nachricht dazugehörigen Protokolls zurück. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public VSAbstractProcess getSendingProcess()}: Gibt eine Referenz auf den Senderprozess zurück. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public long getLamportTime()}: Gibt die Lamportzeit des Senderprozesses zurück. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public VSVectorTime getLamportTime()}: Gibt die Vektorzeit des Senderprozesses zurück. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
+ \item \textit{public boolean isServerMessage()}: Hiermit läßt sich entscheiden, ob es sich um eine Server- oder eine Clientnachricht handelt. Diese Methode funktioniert nur bei empfangenen Nachrichten richtig.
\end{itemize}
-Wenn \"{u}ber eine Nachricht Daten verschickt werden sollen, so werden die von \textit{VSPrefs} vererben Methoden verwendet.
+Wenn über eine Nachricht Daten verschickt werden sollen, so werden die von \textit{VSPrefs} vererben Methoden verwendet.
\subsection{Beispielimplementierung eines Protokolls}
-Im Folgenden wird die Implementierung des zuverl\"{a}ssigen Multicast-Protokolls \textit{VSReliableMulticastProtocol.java} als Beispiel aufgef\"{u}hrt. Die Funktionsweise des Protokolls wurde bereits in Kapitel 2.5.10 beschrieben. Client- und Serverseite werden in der selben Klasse implementiert.
+Im Folgenden wird die Implementierung des zuverlässigen Multicast-Protokolls \textit{VSReliableMulticastProtocol.java} als Beispiel aufgeführt. Die Funktionsweise des Protokolls wurde bereits in Kapitel 2.5.10 beschrieben. Client- und Serverseite werden in der selben Klasse implementiert.
-Im Konstruktor muß stets angegeben werden, ob beim gegebenen Protokoll der Client oder der Server die Anfragen startet. Mit \textit{HAS\_ON\_CLIENT\_START} wird dem API mitgeteilt, dass der Client die Anfragen startet. F\"{u}r \textit{HAS\_ON\_SERVER\_START} und Serveranfragen gilt Selbiges analog. Da ein Protokoll auch ein \textit{VSAbstractEvent} ist, muss auch hier im Konstruktor mit \textit{setClassname} der Klassenname des aktuellen Protokolls angegeben werden:
+Im Konstruktor muß stets angegeben werden, ob beim gegebenen Protokoll der Client oder der Server die Anfragen startet. Mit \textit{HAS\_ON\_CLIENT\_START} wird dem API mitgeteilt, dass der Client die Anfragen startet. Für \textit{HAS\_ON\_SERVER\_START} und Serveranfragen gilt Selbiges analog. Da ein Protokoll auch ein \textit{VSAbstractEvent} ist, muss auch hier im Konstruktor mit \textit{setClassname} der Klassenname des aktuellen Protokolls angegeben werden:
\begin{code}
package protocols.implementations;
@@ -404,7 +404,7 @@ public class VSReliableMulticastProtocol \subsubsection{Clientseite des Protokolls}
-Das private Klassenattribut \textit{pids} wird f\"{u}r die Zwischenspeicherung beteiligter PIDs ben\"{o}tigt. Hier sind alle PIDs abgelegt, von denen noch Best\"{a}tigungsnachrichten erwartet werden. Hier werden als Standard-PIDs \textit{1} und \textit{3} verwendet. Die Methoden \textit{initVector} und \textit{initLong} wurden von \textit{VSPrefs} vererbt und initialisieren die Protokollvariablen \textit{pids} und \textit{timeout}, welche vom Benutzer im Prozesseditor editiert werden k\"{o}nnen (siehe Abbildung \ref{fig:Protokollvariablen} unter ``Reliable Multicast Client'' ganz unten):
+Das private Klassenattribut \textit{pids} wird für die Zwischenspeicherung beteiligter PIDs benötigt. Hier sind alle PIDs abgelegt, von denen noch Bestätigungsnachrichten erwartet werden. Hier werden als Standard-PIDs \textit{1} und \textit{3} verwendet. Die Methoden \textit{initVector} und \textit{initLong} wurden von \textit{VSPrefs} vererbt und initialisieren die Protokollvariablen \textit{pids} und \textit{timeout}, welche vom Benutzer im Prozesseditor editiert werden können (siehe Abbildung \ref{fig:Protokollvariablen} unter ``Reliable Multicast Client'' ganz unten):
\begin{code}
private ArrayList<Integer> pids;
@@ -412,13 +412,13 @@ Das private Klassenattribut \textit{pids} wird f\"{u}r die Zwischenspeicherung b Vector<Integer> vec = new Vector<Integer>();
vec.add(1); vec.add(3);
super.initVector("pids", vec,
- "PIDs beteilitger Prozesse");
+ "PIDs beteiligter Prozesse");
super.initLong("timeout", 2500,
"Zeit bis erneute Anfrage", "ms");
}
\end{code}
-Wenn die Simulation zur\"{u}ckgesetzt wird, dann wird auch \textit{pids} reinitialisiert:
+Wenn die Simulation zurückgesetzt wird, dann wird auch \textit{pids} reinitialisiert:
\begin{code}
public void onClientReset() {
pids.clear();
@@ -426,7 +426,7 @@ Wenn die Simulation zur\"{u}ckgesetzt wird, dann wird auch \textit{pids} reiniti }
\end{code}
-In \textit{onClientStart} wird gepr\"{u}ft, ob eine Clientanfrage gestartet werden soll. Wenn dies der Fall ist (wenn von mindestens einem beteiligten Prozess noch keine Best\"{a}tigung erhalten wurde), wird ein neues Nachrichtenobjekt erstellt, und mit dem Inhalt \textit{Boolean: isMulticast=true} verschickt (intern wird hier f\"{u}r jeden Empf\"{a}ngerprozess ein \textit{VSMessageReceiveEvent} erzeugt). Mit \textit{scheduleAt} wird ein Wecker festgelegt, zur welchen lokalen Prozesszeit die Methode \textit{onClientSchedule} aufgerufen werden soll (intern wird hier ein \textit{VSProtocolScheduleEvent} erzeugt):
+In \textit{onClientStart} wird geprüft, ob eine Clientanfrage gestartet werden soll. Wenn dies der Fall ist (wenn von mindestens einem beteiligten Prozess noch keine Bestätigung erhalten wurde), wird ein neues Nachrichtenobjekt erstellt, und mit dem Inhalt \textit{Boolean: isMulticast=true} verschickt (intern wird hier für jeden Empfangsprozess ein \textit{VSMessageReceiveEvent} erzeugt). Mit \textit{scheduleAt} wird ein Wecker festgelegt, zur welchen lokalen Prozesszeit die Methode \textit{onClientSchedule} aufgerufen werden soll (intern wird hier ein \textit{VSProtocolScheduleEvent} erzeugt):
\begin{code}
public void onClientStart() {
if (pids.size() != 0) {
@@ -441,7 +441,7 @@ In \textit{onClientStart} wird gepr\"{u}ft, ob eine Clientanfrage gestartet werd }
\end{code}
-Wenn eine Serverantwort eintrifft, dann wird \textit{onClientRecv} aufgerufen. Hier wird \"{u}berpr\"{u}ft, ob \"{u}berhaupt noch Multicast-Best\"{a}tigungen ben\"{o}tigt werden. Wenn dies der Fall ist, dann wird geschaut, ob es sich bei der Antwort um eine noch nicht eingetroffene Best\"{a}tigung handelt. Gegebenenfalls wird die jeweilige PID aus \textit{pids} entfernt. Wenn \textit{pids} leer ist, dann wurde von allen beteiligten Prozessen eine Best\"{a}tigung erhalten und der Client entfernt mit \textit{removeSchedules} alle seine derzeit programmierten Wecker.
+Wenn eine Serverantwort eintrifft, dann wird \textit{onClientRecv} aufgerufen. Hier wird überprüft, ob überhaupt noch Multicast-Bestätigungen benötigt werden. Wenn dies der Fall ist, dann wird geschaut, ob es sich bei der Antwort um eine noch nicht eingetroffene Bestätigung handelt. Gegebenenfalls wird die jeweilige PID aus \textit{pids} entfernt. Wenn \textit{pids} leer ist, dann wurde von allen beteiligten Prozessen eine Bestätigung erhalten und der Client entfernt mit \textit{removeSchedules} alle seine derzeit programmierten Wecker.
\begin{code}
public void onClientRecv(VSMessage recvMessage) {
@@ -465,7 +465,7 @@ Wenn eine Serverantwort eintrifft, dann wird \textit{onClientRecv} aufgerufen. H }
\end{code}
-F\"{u}r das erneute Verschicken einer Clientanfrage ruft \textit{onClientSchedule} lediglich die Methode \textit{onClientStart} auf, die wiederum einen neuen Wecker planen kann:
+Für das erneute Verschicken einer Clientanfrage ruft \textit{onClientSchedule} lediglich die Methode \textit{onClientStart} auf, die wiederum einen neuen Wecker planen kann:
\begin{code}
public void onClientSchedule() {
onClientStart();
@@ -474,7 +474,7 @@ F\"{u}r das erneute Verschicken einer Clientanfrage ruft \textit{onClientSchedul \subsubsection{Serverseite des Protokolls}
-Die Serverseite des Protokolls speichert im Attribut \textit{ackSent} ab, ob es bereits eine Best\"{a}tigung des Multicasts verschickt hat oder nicht. In diesem Protokoll werden in \textit{onServerInit} keine Initialisierungen vorgenommen. Demach gibt es f\"{u}r den Benutzer auch keine serverseitigen Protokollvariablen zu editieren. Beim Zur\"{u}cksetzen der Simulation wird lediglich \textit{ackSent} auf den Ursprungswert \textit{false} gesetzt:
+Die Serverseite des Protokolls speichert im Attribut \textit{ackSent} ab, ob es bereits eine Bestätigung des Multicasts verschickt hat oder nicht. In diesem Protokoll werden in \textit{onServerInit} keine Initialisierungen vorgenommen. Demnach gibt es für den Benutzer auch keine serverseitigen Protokollvariablen zu editieren. Beim Zurücksetzen der Simulation wird lediglich \textit{ackSent} auf den Ursprungswert \textit{false} gesetzt:
\begin{code}
private boolean ackSent = false;
@@ -485,7 +485,7 @@ Die Serverseite des Protokolls speichert im Attribut \textit{ackSent} ab, ob es }
\end{code}
-Wenn der Server eine Clientanfrage erhalten hat, so \"{u}berpr\"{u}ft der Server, ob es sich um eine Multicast-Nachricht handelte. Anschließend wird gegebenenfalls die Best\"{a}tigungsnachricht mit \textit{Boolean: isAck=true} und der Server-PID verschickt. Jenachdem ob bereits eine Best\"{a}tigung verschickt wurde oder nicht wird eine andere Nachricht geloggt:
+Wenn der Server eine Clientanfrage erhalten hat, so überprüft der Server, ob es sich um eine Multicast-Nachricht handelte. Anschließend wird gegebenenfalls die Bestätigungsnachricht mit \textit{Boolean: isAck=true} und der Server-PID verschickt. Je nachdem ob bereits eine Bestätigung verschickt wurde oder nicht wird eine andere Nachricht geloggt:
\begin{code}
public void onServerRecv(VSMessage recvMessage) {
if (recvMessage.getBoolean("isMulticast")) {
@@ -512,20 +512,20 @@ Der Server benutzt in diesem Beispiel keinen Wecker. Dementsprechend hat die Met \subsection{Erstellung eigener Protokolle (Schnelldurchlauf)}
-Hier werden alle Schritte zusammegefasst, die f\"{u}r die Erstellung eines eigenen Protokolls \textit{VSMyProtocol} durchgef\"{u}rt werden m\"{u}ssen.
+Hier werden alle Schritte zusammengefasst, die für die Erstellung eines eigenen Protokolls \textit{VSMyProtocol} durchgeführt werden müssen.
\begin{enumerate}
\item VS-Simulator Quelltext beziehen und in das Verzeichnis \textit{vs/sources/protocols/implementations} wechseln.
\item Das Template-Protokoll \textit{VSDummyProtocol.java} nach \textit{VSMyProtocol.java} kopieren.
\item \textit{VSDummyProtocol.java} editieren und den Klassennamen dort anpassen (\textit{VSDummyProtocol} $\rightarrow$ \textit{VSMyProtocol}).
\item In das oberste Verzeichnis \textit{vs/} wechseln.
- \item Die datei \textit{sources/events/VSRegisteredEvents.java} editieren, und in der \textit{init}-Methode folgende Zeile hinzuf\"{u}gen:
+ \item Die Datei \textit{sources/events/VSRegisteredEvents.java} editieren, und in der \textit{init}-Methode folgende Zeile hinzufügen:
\begin{code}
registerEvent("protocols.implementations.VSMyProtocol",
- "Langer Name des Protokolls", // Langer name
+ "Langer Name des Protokolls", // Langer Name
"Neues Protokoll"); // Kurzer Name
\end{code}
- \item Mit dem Befehl \textit{ant compile} die \"{A}nderungen \"{u}bernehmen und mit \textit{ant test} testen, ob der Simulator das Protokoll \"{u}bernommen hat. Hierbei wird der Simulator direkt aus dem Quellverzeichnis gestartet. ``Neues Protokoll'' sollte nun im Ereigniseditor programmiert werden k\"{o}nnen.
+ \item Mit dem Befehl \textit{ant compile} die Änderungen übernehmen und mit \textit{ant test} testen, ob der Simulator das Protokoll übernommen hat. Hierbei wird der Simulator direkt aus dem Quellverzeichnis gestartet. ``Neues Protokoll'' sollte nun im Ereigniseditor programmiert werden können.
\item Mit dem Befehl \textit{ant dist} das Archiv \textit{dist/lib/VS-Sim-Latest.jar} erstellen und verwenden.
\end{enumerate}
@@ -533,11 +533,11 @@ registerEvent("protocols.implementations.VSMyProtocol", \subsection{Funktionsweise}
-Das Paket \textit{simulator} (vereinfacht auf Abbildung \ref{fig:PackageProtocols} dargestellt) implementiert die eigentliche graphische Benutzeroberf\"{a}che des Simulators. Ausnahmen sind die Editorklassen in \textit{prefs.editors} sowie \textit{utils.VSFrame}.
+Das Paket \textit{simulator} (vereinfacht auf Abbildung \ref{fig:PackageProtocols} dargestellt) implementiert die eigentliche graphische Benutzeroberfläche des Simulators. Ausnahmen sind die Editorklassen in \textit{prefs.editors} sowie \textit{utils.VSFrame}.
-Beim Starten des Simulators wird auf die Main-Methode, welche sich in \textit{VSMain} befindet, aufgerufen. Sie instanziiert ein \textit{VSDefaultPrefs}-Objekt, wo alle Standardeinstellungen des Simulators abgelegt sind. Anschließend wird ein \textit{VSSimulatorFrame} erzeugt, welches ein Simulatorfenster (wie bereits schon auf Abbildung \ref{fig:NeuesFenster} zu sehen war) implementiert. Das Simulatorfenster erstellt f\"{u}r jede neue Simulation jeweils ein Objekt von \textit{VSSimulator}. Jede Simulation hat im Simulationsfenster einen eigenen Tab. Auf Abbildung \ref{fig:NeuErstellteSimulation} wurde bereits eine neue Simulation erstellt, wo auch unten links der dazugeh\"{o}rige Tab mit der Beschriftung ``Simulator 1'' zu sehen ist. Jede Simulation besitzt dabei eine eigene Simulationsnummer, die bei jeder neuen Simulation um eins inkrementiert wird. Jedes \textit{VSSimulator}-Objekt greift auf \textit{VSSimulatorVisualization} zur\"{u}ck, was die Simulationsvisualisierung (Abbildung \ref{fig:Visualisierung}) implementiert.
+Beim Starten des Simulators wird auf die Main-Methode, welche sich in \textit{VSMain} befindet, aufgerufen. Sie instantiiert ein \textit{VSDefaultPrefs}-Objekt, wo alle Standardeinstellungen des Simulators abgelegt sind. Anschließend wird ein \textit{VSSimulatorFrame} erzeugt, welches ein Simulatorfenster (wie bereits schon auf Abbildung \ref{fig:NeuesFenster} zu sehen war) implementiert. Das Simulatorfenster erstellt für jede neue Simulation jeweils ein Objekt von \textit{VSSimulator}. Jede Simulation hat im Simulationsfenster einen eigenen Tab. Auf Abbildung \ref{fig:NeuErstellteSimulation} wurde bereits eine neue Simulation erstellt, wo auch unten links der dazugehörige Tab mit der Beschriftung ``Simulator 1'' zu sehen ist. Jede Simulation besitzt dabei eine eigene Simulationsnummer, die bei jeder neuen Simulation um eins inkrementiert wird. Jedes \textit{VSSimulator}-Objekt greift auf \textit{VSSimulatorVisualization} zurück, was die Simulationsvisualisierung (Abbildung \ref{fig:Visualisierung}) implementiert.
-\textit{VSSimulatorVisualization} greift auf Java's Grafikbibliothek Java2D zur\"{u}ck und ist aus Performancegr\"{u}nden mit dem Simulationsverlauf stark verzahnt \cite{Games}. Klassenattribute, dessen Wert sich nie \"{a}ndert, wurden stets als \textit{final} deklariert. Attribute, die von Konfigurationen oder Einstellungen abh\"{a}ngig sind, die sich nur nach Konfigurations\"{a}nderung oder Vergr\"{o}ßern beziehungsweise Verkleinern des Simulationsfensters \"{a}ndern (Werte, die f\"{u}r die Berechnung des Sekunden-Gatters notwendig sind), werden nur wenn es n\"{o}tig ist neu berechnet.
+\textit{VSSimulatorVisualization} greift auf Java's Grafikbibliothek Java2D zurück und ist aus Performancegründen mit dem Simulationsverlauf stark verzahnt \cite{Games}. Klassenattribute, dessen Wert sich nie ändert, wurden stets als \textit{final} deklariert. Attribute, die von Konfigurationen oder Einstellungen abhängig sind, die sich nur nach Konfigurationsänderung oder Vergrößern beziehungsweise Verkleinern des Simulationsfensters ändern (Werte, die für die Berechnung des Sekunden-Gatters notwendig sind), werden nur wenn es nötig ist neu berechnet.
\begin{figure}[h]
\centering
@@ -546,32 +546,32 @@ Beim Starten des Simulators wird auf die Main-Methode, welche sich in \textit{VS \label{fig:PackageProtocols}
\end{figure}
-Die Klasse \textit{VSMenuItemStates} wird f\"{u}r die Synchronisierung des Simulationsstatusses, der Toolbar und des Simulations-Men\"{u}s (beide Letztere auf Abbildung \ref{fig:Toolbar} zu sehen) verwendet. Abh\"{a}ngig davon kann der Benutzer bestimmte Aktionen durchf\"{u}hren oder nicht (beispielsweise kann eine Simulation nur pausiert werden, wenn sie aktuell abgespielt wird). Alle hier m\"{o}glichen Aktionen wurden bereits in Kapitel 2.1 im Abschnitt ``Die Toolbar'' behandelt.
+Die Klasse \textit{VSMenuItemStates} wird für die Synchronisierung des Simulationsstatusses, der Toolbar und des Simulations-Menüs (beide Letztere auf Abbildung \ref{fig:Toolbar} zu sehen) verwendet. Abhängig davon kann der Benutzer bestimmte Aktionen durchführen oder nicht (beispielsweise kann eine Simulation nur pausiert werden, wenn sie aktuell abgespielt wird). Alle hier möglichen Aktionen wurden bereits in Kapitel 2.1 im Abschnitt ``Die Toolbar'' behandelt.
Die Klasse \textit{VSCreateTask} wird vom Ereigniseditor verwendet. Der Ereigniseditor (Abbildung \ref{fig:SidebarMitEreignissen}) wird in der Klasse \textit{VSSimulator} implementiert. Hinter jeder Ereignisauswahl verbirgt sich intern ein \textit{VSCreateTask}-Objekt, welches definiert wie das jeweilige Ereignis anzulegen ist.
-\textit{VSLogging} kapselt ein \textit{javax.swing.JTextArea}-Objekt, wo alle Nachrichten geloggt werden. Hier werden alle Loggfunktionen (inklusive Loggfilter sowie tempor\"{a}re Deaktivierung des Loggen) implementiert. Die \textit{JTextArea} wird dem \textit{VSSimulator}-Objekt \"{u}bergeben und dort dargestellt. F\"{u}r den Loggfilter wird intern auf das Java-Standardpaket \textit{java.util.regex} zugegriffen, womit anhand von regul\"{a}ren Ausdr\"{u}cken in Java-Syntax die Loggs gefiltert werden k\"{o}nnen.
+\textit{VSLogging} kapselt ein \textit{javax.swing.JTextArea}-Objekt, wo alle Nachrichten geloggt werden. Hier werden alle Loggfunktionen (inklusive Loggfilter sowie temporäre Deaktivierung des Loggen) implementiert. Die \textit{JTextArea} wird dem \textit{VSSimulator}-Objekt übergeben und dort dargestellt. Für den Loggfilter wird intern auf das Java-Standardpaket \textit{java.util.regex} zugegriffen, womit anhand von regulären Ausdrücken in Java-Syntax die Loggs gefiltert werden können.
\subsection{Threads und Zeitsynchronisierung}
-Ziel vom Simulator is es bis auf jede Millisekunde genau simulieren zu k\"{o}nnen. Jede simulierte Sekunde soll relativ zur echten Zeit fortschreiten. Die Simulationsabspielgeschwindigkeit l\"{a}ßt sich bei den Simulationseinstellungen unter ``Abspielgeschwindigkeit der Simulation'' (Float: \textit{sim.clock.speed}) einstellen. Damit dies gew\"{a}hrleistet wird, muß folgendes ber\"{u}cksichtigt werden:
+Ziel vom Simulator ist es bis auf jede Millisekunde genau simulieren zu können. Jede simulierte Sekunde soll relativ zur echten Zeit fortschreiten. Die Simulationsabspielgeschwindigkeit läßt sich bei den Simulationseinstellungen unter ``Abspielgeschwindigkeit der Simulation'' (Float: \textit{sim.clock.speed}) einstellen. Damit dies gewährleistet wird, muß folgendes berücksichtigt werden:
\begin{itemize}
- \item Das Zeichnen der Visualisierung ben\"{o}tigt pro Aktualisierung einige Millisekunden. Dies ist der Rechenintensivste Teil des Simulators. Hier werden st\"{a}ndig mathematische Berechnungen (wie zum Beispiel die Gerade einer Nachrichtenlinie, die automatische Skalierung des Diagrams die sich automatisch an die Fenstergr\"{o}ße und der Simulationsdauer anpasst und vieles mehr).
- \item Das Neuberechnen der Simulation ben\"{o}tigt pro Aktualisierung einige Millisekunden. Hier wird insbesondere der Task-Manager beansprucht, der \"{u}berpr\"{u}ft, ob Ereignisse auszuf\"{u}hren sind und sie gegebenenfalls dann auch ausf\"{u}hrt.
- \item Jeder simulierte Prozess sollte mit selber Geschwindigkeit fortschreiten, und dies auf jedem Rechner wo der Simulator ausgef\"{u}hrt wird. Da Java-Threads nicht komplett platformunabh\"{a}ngig sind (Threads sind im Betriebssystem implementiert), kann das Verhalten auf verschiedenen Rechnern minimal variieren. Ausserdem \"{u}bernimmt das Betriebssystem die Entscheidung, wann welcher Thread arbeiten darf. Ausser man synchronisiert Threads manuell so, dass sie den eigenen Anspr\"{u}chen entsprechen. Letzteres bedeutet aber auch mehr Programmieraufwand.
- \item Die Simulationszeit ist stets in Millisekunden angegeben, welche in einer \textit{long}-Variable abgespeichert wird. Somit kann eine Simulationszeit immer nur eine ganze Zahl sein. Berechnungsrundungsfehler wegen \textit{sim.clock.speed} m\"{u}ssen ber\"{u}cksichtig werden.
- \item Der Simulator soll nicht st\"{a}ndig die komplette CPU des Anwender-Computers voll beanspruchen.
+ \item Das Zeichnen der Visualisierung benötigt pro Aktualisierung einige Millisekunden. Dies ist der rechen-intensivste Teil des Simulators. Hier werden ständig mathematische Berechnungen (wie zum Beispiel die Gerade einer Nachrichtenlinie, die automatische Skalierung des Diagramms die sich automatisch an die Fenstergröße und der Simulationsdauer anpasst und vieles mehr).
+ \item Das Neuberechnen der Simulation benötigt pro Aktualisierung einige Millisekunden. Hier wird insbesondere der Task-Manager beansprucht, der überprüft, ob Ereignisse auszuführen sind und sie gegebenenfalls dann auch ausführt.
+ \item Jeder simulierte Prozess sollte mit selber Geschwindigkeit fortschreiten, und dies auf jedem Rechner wo der Simulator ausgeführt wird. Da Java-Threads nicht komplett plattformunabhängig sind (Threads sind im Betriebssystem implementiert), kann das Verhalten auf verschiedenen Rechnern minimal variieren. Außerdem übernimmt das Betriebssystem die Entscheidung, wann welcher Thread arbeiten darf. Außer man synchronisiert Threads manuell so, dass sie den eigenen Ansprüchen entsprechen. Letzteres bedeutet aber auch mehr Programmieraufwand.
+ \item Die Simulationszeit ist stets in Millisekunden angegeben, welche in einer \textit{long}-Variable abgespeichert wird. Somit kann eine Simulationszeit immer nur eine ganze Zahl sein. Berechnungsrundungsfehler wegen \textit{sim.clock.speed} müssen berücksichtigt werden.
+ \item Der Simulator soll nicht ständig die komplette CPU des Anwender-Computers voll beanspruchen.
\end{itemize}
-Es wurde folgende relativ einfache L\"{o}sung gew\"{a}hlt, bei der lediglich ein einziger Thread fuer die Visualisierung und die Berechnung der Simulation zust\"{a}ndig ist (alle Zeitangaben sind in Millisekunden). Der Algorithmus verl\"{a}uft leicht vereinfacht in folgender Form ab:
+Es wurde folgende relativ einfache Lösung gewählt, bei der lediglich ein einziger Thread für die Visualisierung und die Berechnung der Simulation zuständig ist (alle Zeitangaben sind in Millisekunden). Der Algorithmus verläuft leicht vereinfacht in folgender Form ab:
\begin{enumerate}
- \item Die simulierte globale Startzeit sei $s$ und die globale Zeit wo die Simulation aufh\"{o}rt sei $e$.
+ \item Die simulierte globale Startzeit sei $s$ und die globale Zeit wo die Simulation aufhört sei $e$.
\item Wenn $s > e$, dann $s := e$ setzen.
\item Neuberechnen und Zeichnen der Visualisierung zum Zeitpunkt $s$. Die dabei verstrichene Zeit sei $v$.
\item Wenn $s = e$, dann Simulation beenden.
- \item F\"{u}r einige Millisekunden den Thread pausieren (schlafen lassen). Hierbei sei $p$ die beim Schlafen verstrichene Zeit.
+ \item Für einige Millisekunden den Thread pausieren (schlafen lassen). Hierbei sei $p$ die beim Schlafen verstrichene Zeit.
\item
\begin{verbatim}
for (i = s; i < s + v + p && i < e; i++)
@@ -580,15 +580,15 @@ for (i = s; i < s + v + p && i < e; i++) \item Bei Punkt 2 mit neuer Startzeit $s := s + v + p$ weitermachen.
\end{enumerate}
-Hinzu kommt noch die Ber\"{u}cksichtigung der Simulationsvariable \textit{sim.clock.speed}, die wegen der \"{U}bersicht im Algorithmus nicht dargestellt wurde. Intern hat der Simulator die echte Zeit und die Simulationszeit abgespeichert. Es werden st\"{a}ndig die verstrichenen echten Zeiten gemessen und anschliessend anhand von \textit{sim.clock.speed} die neuen tats\"{a}chlichen Simulationszeiten berechnet. Rundungsfehler werden pro Durchgang in eine \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert und wenn der Betrag der Rundungsfehler $>= 1$ ist, dann werden davon die ganzen Werteanteile in der Simulationszeit ber\"{u}cksichtigt.
+Hinzu kommt noch die Berücksichtigung der Simulationsvariable \textit{sim.clock.speed}, die wegen der Übersicht im Algorithmus nicht dargestellt wurde. Intern hat der Simulator die echte Zeit und die Simulationszeit abgespeichert. Es werden ständig die verstrichenen echten Zeiten gemessen und anschließend anhand von \textit{sim.clock.speed} die neuen tatsächlichen Simulationszeiten berechnet. Rundungsfehler werden pro Durchgang in eine \textit{double}-Variable (Fließkommazahl doppelter Genauigkeit) abgespeichert und wenn der Betrag der Rundungsfehler $>= 1$ ist, dann werden davon die ganzen Wertanteile in der Simulationszeit berücksichtigt.
-Jede Simulation besitzt somit seinen eigenen Simulationsthread. Bei mehreren parallel laufenden Simulationen laufen auch mehrere parallele voneinander unabh\"{a}ngige Threads. Des Weiteren gibt es noch den Java Swing-Thread, der f\"{u}r die GUI und der Anwenderinteraktion zust\"{a}ndig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen. Anwendereingriffe werden deswegen synchronisiert, da es ansonsten zu zeitgleichen Zugriffen/\"{A}nderungen gleicher Objekte kommen kann und somit eine Java-Ausnahme geworfen wird die das Stoppen eines Threads verursacht.
+Jede Simulation besitzt somit seinen eigenen Simulationsthread. Bei mehreren parallel laufenden Simulationen laufen auch mehrere parallele voneinander unabhängige Threads. Des Weiteren gibt es noch den Java Swing-Thread, der für die GUI und der Anwenderinteraktion zuständig ist. Der Anwender kann zu jedem Zeitpunkt in die Simulation eingreifen. Anwendereingriffe werden deswegen synchronisiert, da es ansonsten zu zeitgleichen Zugriffen/Änderungen gleicher Objekte kommen kann und somit eine Java-Ausnahme geworfen wird die das Stoppen eines Threads verursacht.
\section{Serialisierung und Deserialisierung von Simulationen}
\subsection{Funktionsweise}
-Der Anwender kann eine erstellte Simulation im Datei-Men\"{u} speichern und/oder eine bereits abgespeicherte Simulation laden. Hierbei wird von den aus Java angebotenen M\"{o}glichkeit Objekte zu Serialisieren gebrauch gemacht. Im Paket \textit{serialize} (Abbildung \ref{fig:PackageSerialize}) befinden sich Helfer, die bei einer Serialisierung und einer Deserialisierung einer Simulation unter die Arme greifen.
+Der Anwender kann eine erstellte Simulation im Datei-Menü speichern und/oder eine bereits abgespeicherte Simulation laden. Hierbei wird von den aus Java angebotenen Möglichkeit Objekte zu Serialisieren Gebrauch gemacht. Im Paket \textit{serialize} (Abbildung \ref{fig:PackageSerialize}) befinden sich Helfer, die bei einer Serialisierung und einer Deserialisierung einer Simulation unter die Arme greifen.
Der Simulator serialisiert nur notwendige Daten, und nicht jedes existierende Objekt. Alle Serialisierbaren Klassen implementieren das Interface \textit{VSSerializable} mit folgenden zwei Methoden:
@@ -597,7 +597,7 @@ Der Simulator serialisiert nur notwendige Daten, und nicht jedes existierende Ob \item \textit{public void deserialize(VSSerialize serialize, ObjectInputStream ois)}: Diese Methode wird bei jedem Deserialisierungsvorgang aufgerufen (beim Laden einer Simulation).
\end{itemize}
-Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einen Dateistream auch ein \textit{VSSerialize}-Objekt. F\"{u}r jeden (De)serialisierungsvorgang wird ein \textit{VSSerialize}-Objekt erzeugt, welches dabei Hilft die ben\"{o}tigten Aktionen durchzuf\"{u}hren. Eine zu serialisierende Simulation besteht aus vielen voneinander abh\"{a}ngigen Objekten. Jedes Objekt kann dabei Referenzen auf andere Objekte besitzen. W\"{u}rde jedes Objekt komplett serialisiert werden, so w\"{u}rden Objekte, auf denen mehrere Referenzen existieren, in mehrfacher Ausf\"{u}hrung behandelt (in eine Datei abgespeichert) werden. Bei Kreissverweisen (Objekt A hat eine Referenz auf Objekt B und Objekt B hat eine Referenz auf Objekt A als Attribut gespeichert) w\"{u}rde die Serialisierung sogar in einer Endlosschleife enden. \textit{VSSerialize} hilft hierbei dies zu vermeiden und merkt sich Informationen von allen bereits serialisierten Objekten, sodass jedes Objekt nur genau einmal serialisiert wird. Bei der Deserialisierung werden alle Objekte wieder automatisch mit den richtigen Referenzen ausgestattet, wobei kein Objekt doppelt deserialisiert wird.
+Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einen Dateistream auch ein \textit{VSSerialize}-Objekt. Für jeden (De)serialisierungsvorgang wird ein \textit{VSSerialize}-Objekt erzeugt, welches dabei Hilft die benötigten Aktionen durchzuführen. Eine zu serialisierende Simulation besteht aus vielen voneinander abhängigen Objekten. Jedes Objekt kann dabei Referenzen auf andere Objekte besitzen. Würde jedes Objekt komplett serialisiert werden, so würden Objekte, auf denen mehrere Referenzen existieren, in mehrfacher Ausführung behandelt (in eine Datei abgespeichert) werden. Bei Kreissverweisen (Objekt A hat eine Referenz auf Objekt B und Objekt B hat eine Referenz auf Objekt A als Attribut gespeichert) würde die Serialisierung sogar in einer Endlosschleife enden. \textit{VSSerialize} hilft hierbei dies zu vermeiden und merkt sich Informationen von allen bereits serialisierten Objekten, sodass jedes Objekt nur genau einmal serialisiert wird. Bei der Deserialisierung werden alle Objekte wieder automatisch mit den richtigen Referenzen ausgestattet, wobei kein Objekt doppelt deserialisiert wird.
\begin{figure}[h]
\centering
@@ -606,9 +606,9 @@ Die Methoden \textit{serialize} und \textit{deserialize} erhalten neben einen Da \label{fig:PackageSerialize}
\end{figure}
-Alle Klassen, die \textit{VSSerializePrefs} erweitern, k\"{o}nnen automatisch s\"{a}mtliche Einstellungen komfortabel serialisieren und deserialiseren. Beispielsweise speichert ein Simulator (\textit{VSSimulator}) alle seine globalen Simulationseinstellungen bei einer Serialisierung automatisch ab. Bei den Prozessen und den Ereignissen (und somit auch Protokollen) gilt selbiges analog.
+Alle Klassen, die \textit{VSSerializePrefs} erweitern, können automatisch sämtliche Einstellungen komfortabel serialisieren und deserialiseren. Beispielsweise speichert ein Simulator (\textit{VSSimulator}) alle seine globalen Simulationseinstellungen bei einer Serialisierung automatisch ab. Bei den Prozessen und den Ereignissen (und somit auch Protokollen) gilt selbiges analog.
-Abgespeicherte Simulationen sollen auch mit zuk\"{u}nftigen Versionen des Simulators kompatibel bleiben. Deshalb werden alle Objekte derjenigen Klassen, die \textit{VSSerializable} implementieren, nicht komplett serialisiert. Bei der Serialisierung werden nur relevante Klassenattriute, die der Simulationsprogrammierung- und nicht bispielsweise GUI-komponenten angeh\"{o}ren, serialisiert.
+Abgespeicherte Simulationen sollen auch mit zukünftigen Versionen des Simulators kompatibel bleiben. Deshalb werden alle Objekte derjenigen Klassen, die \textit{VSSerializable} implementieren, nicht komplett serialisiert. Bei der Serialisierung werden nur relevante Klassenattribute, die der Simulationsprogrammierung- und nicht beispielsweise GUI-Komponenten angehören, serialisiert.
\subsection{Beispielimplementierung einer \textit{serialize}-Methode}
@@ -628,14 +628,14 @@ Der folgende Quelltext-Ausschnitt zeigt eine Beispielimplementierung von \textit }
\end{code}
-Vor- und nach der eigenlichen Objektserialisierung wird jeweils ein boolsches Flag serialisiert, welches auf \textit{true} gesetzt wird, sobald in sp\"{a}teren Simulator-Versionen (was relativ unwahrscheinlich, aber m\"{o}glich ist) weitere zu serialisierende Klassenattribute hinzukommen. Eine Deserialisiernug kann die Flags dann abfragen und separat behandeln. Somit bleiben \"{a}ltere bereits abgespeicherte Simulationen stets zur neusten Version des Simulators kompatibel. Wenn ein Flag auf \textit{true} gesetzt wird, dann kann unter den neuen Attributserialisierungen ein weiteres Flag gesetzt werden. Somit k\"{o}nnen beliebig viele Erweiterungen in die Serialisierung Einzug halten.
+Vor- und nach der eigentlichen Objektserialisierung wird jeweils ein boolesches Flag serialisiert, welches auf \textit{true} gesetzt wird, sobald in späteren Simulator-Versionen (was relativ unwahrscheinlich, aber möglich ist) weitere zu serialisierende Klassenattribute hinzukommen. Eine Deserialisierung kann die Flags dann abfragen und separat behandeln. Somit bleiben ältere bereits abgespeicherte Simulationen stets zur neusten Version des Simulators kompatibel. Wenn ein Flag auf \textit{true} gesetzt wird, dann kann unter den neuen Attributserialisierungen ein weiteres Flag gesetzt werden. Somit können beliebig viele Erweiterungen in die Serialisierung Einzug halten.
-Das zu serialisierende Objekt besitzt hier lediglich zwei Attribute, die serialisiert werden sollen. Alle anderen Klassenattribute k\"{o}nnen vernachl\"{a}ßigt werden. Mit \textit{serialize.setObject} speichert \textit{serialize} eine Referenz auf das aktuelle Objekt ab, worauf andere Objektserialisierungen zur\"{u}ckgreifen k\"{o}nnen. Danach wird ein \textit{prefs} und \textit{someOtherSerializableObject} serialisiert. Die Deserialisierung folgt genau den Umgekehrten weg. Wobei hier zuerst die Instanzen der Klassen auf normalen Weg erstellt werden und dann nachtr\"{a}glich die relevanten Attribute deserialisiert und den Objekten zugewiesen werden. Hierbei werden auch mithilfe von \textit{VSSerialize} mehrere Referenzen auf das selbe Objekt korrekt behandelt.
+Das zu serialisierende Objekt besitzt hier lediglich zwei Attribute, die serialisiert werden sollen. Alle anderen Klassenattribute können vernachlässigt werden. Mit \textit{serialize.setObject} speichert \textit{serialize} eine Referenz auf das aktuelle Objekt ab, worauf andere Objektserialisierungen zurückgreifen können. Danach wird ein \textit{prefs} und \textit{someOtherSerializableObject} serialisiert. Die Deserialisierung folgt genau den Umgekehrten weg. Wobei hier zuerst die Instanzen der Klassen auf normalen Weg erstellt werden und dann nachträglich die relevanten Attribute deserialisiert und den Objekten zugewiesen werden. Hierbei werden auch mithilfe von \textit{VSSerialize} mehrere Referenzen auf das selbe Objekt korrekt behandelt.
-Wenn der Anwender \textit{Datei $\rightarrow$ Simulation speichern} w\"{a}hlt, dann wird zun\"{a}chst ein \textit{VSSerialize}-Objekt erstellt. Ausgehend davon wird \textit{serialize} auf \textit{VSSimulator} ausgef\"{u}hrt (siehe Serialisierungssequenz auf Abbildung \ref{fig:SequenceSerialize}). Das Simulator-Objekt f\"{u}hrt \textit{serialize} wiederum auf das \textit{VSSimulatorVisualization}-Objekt aus. Dort wird jeder Prozess inklusive alle Protokollobjekte serialisiert. Anschliessend folgt der Task-Manager inklusive allen programmierten Ereignissen.
+Wenn der Anwender \textit{Datei $\rightarrow$ Simulation speichern} wählt, dann wird zunächst ein \textit{VSSerialize}-Objekt erstellt. Ausgehend davon wird \textit{serialize} auf \textit{VSSimulator} ausgeführt (siehe Serialisierungssequenz auf Abbildung \ref{fig:SequenceSerialize}). Das Simulator-Objekt führt \textit{serialize} wiederum auf das \textit{VSSimulatorVisualization}-Objekt aus. Dort wird jeder Prozess inklusive alle Protokollobjekte serialisiert. Anschließend folgt der Task-Manager inklusive allen programmierten Ereignissen.
-\section{Helferklassen und Klassen f\"{u}r Ausnahmebehandlungen}
+\section{Helferklassen und Klassen für Ausnahmebehandlungen}
\begin{figure}[h]
\centering
@@ -647,14 +647,14 @@ Wenn der Anwender \textit{Datei $\rightarrow$ Simulation speichern} w\"{a}hlt, d Es wurden noch nicht die Klassen der Pakete \textit{utils} (Abbildung \ref{fig:PackageUtils}) sowie \textit{exceptions} (Abbildung \ref{fig:PackageExceptions}) vorgestellt. \textit{utils} fasst lediglich einige Helferklassen zusammen, die vom restlichen Quelltext verwendet werden.
\begin{itemize}
- \item \textit{VSFrame}: Alle Objekte, die ein eigenes Swing-Fenster besitzen, erben von der Klasse \textit{VSFrame}. Sie stellt sicher, dass neue Fenster an der richtigen Position der Bildf\"{a}che platziert werden und dass Unterfenster (Fenster, die aus einem anderen Fenster aus ge\"{o}ffnet wurden) automatisch mitgeschlossen werden, sobald ihre ``Erzeugerfenster'' geschlossen werden.
- \item \textit{VSAboutFrame}: Dieses Fenster implementiert die ``About-Anzeige'' die im Simulator \"{u}ber das Datei-Men\"{u} aufgerufen werden kann.
- \item \textit{VSInfoArea}: Ist f\"{u}r die Textanzeige in \textit{VSAboutFrame} zust\"{a}ndig.
- \item \textit{VSClassLoader}: Diese Klasse wird f\"{u}r die automatische Instanzierung von Ereignisobjekten ben\"{o}tigt, wenn dem Simulator lediglich die Klassennamen (aus \textit{events.VSRegisteredEvents}) bekannt sind.
- \item \textit{VSHelper}: In dieser Klasse befinden sich statische Hilfsmethoden, die in keine andere Klasse passen.
- \item \textit{VSPriorityQueue}: Diese Klasse wird f\"{u}r das Verwalten von \textit{core.VSTask}-Objekte im Task-Manager ben\"{o}tigt. \textit{VSPriorityQueue} passt die Priorit\"{a}ts-Warteschlange aus der Java-Standardbibliothek den Anforderungen des Simulators an.
- \item \textit{VSRandom}: Wird f\"{u}r Zufallsereignisse ben\"{o}tigt. Jedes Prozessobjekt besitzt einen solchen eigenen Pseudozufallsgenerator. Diese Klasse setzt gleichzeitig einen eigenen Seed basierend auf der lokalen Systemzeit und anderer Berechnungen fest.
- \item \textit{VSTupel}: Diese Klasse ist eine Implementierung eines sehr einfach aufgebauten 3-Tupel Datentyps. Alle 3 Elemente k\"{o}nnen von einem anderen Typ sein, was mithilfe der Java-Generics verwirklicht wurde. \textit{VSTupel} wird von den Editorklassen f\"{u}r die Generierung von GUI-Elementen ben\"{o}tigt.
+ \item \textit{VSFrame}: Alle Objekte, die ein eigenes Swing-Fenster besitzen, erben von der Klasse \textit{VSFrame}. Sie stellt sicher, dass neue Fenster an der richtigen Position der Bildfläche platziert werden und dass Unterfenster (Fenster, die aus einem anderen Fenster aus geöffnet wurden) automatisch mit-geschlossen werden, sobald ihre ``Erzeugerfenster'' geschlossen werden.
+ \item \textit{VSAboutFrame}: Dieses Fenster implementiert die ``About-Anzeige'' die im Simulator über das Datei-Menü aufgerufen werden kann.
+ \item \textit{VSInfoArea}: Ist für die Textanzeige in \textit{VSAboutFrame} zuständig.
+ \item \textit{VSClassLoader}: Diese Klasse wird für die automatische Instantiierung von Ereignisobjekten benötigt, wenn dem Simulator lediglich die Klassennamen (aus \textit{events.VSRegisteredEvents}) bekannt sind.
+ \item \textit{VSHelper}: In dieser Klasse befinden sich statische Helfermethoden, die in keine andere Klasse passen.
+ \item \textit{VSPriorityQueue}: Diese Klasse wird für das Verwalten von \textit{core.VSTask}-Objekte im Task-Manager benötigt. \textit{VSPriorityQueue} passt die Prioritäts-Warteschlange aus der Java-Standardbibliothek den Anforderungen des Simulators an.
+ \item \textit{VSRandom}: Wird für Zufallsereignisse benötigt. Jedes Prozessobjekt besitzt einen solchen eigenen Pseudozufallsgenerator. Diese Klasse setzt gleichzeitig einen eigenen Seed basierend auf der lokalen Systemzeit und anderer Berechnungen fest.
+ \item \textit{VSTupel}: Diese Klasse ist eine Implementierung eines sehr einfach aufgebauten 3-Tupel Datentyps. Alle 3 Elemente können von einem anderen Typ sein, was mithilfe der Java-Generics verwirklicht wurde. \textit{VSTupel} wird von den Editorklassen für die Generierung von GUI-Elementen benötigt.
\end{itemize}
\begin{figure}[h]
@@ -664,7 +664,7 @@ Es wurden noch nicht die Klassen der Pakete \textit{utils} (Abbildung \ref{fig:P \label{fig:PackageExceptions}
\end{figure}
-Im Paket \textit{exceptions} befinden sich lediglich einige Objekte die f\"{u}r Ausnahmebehandlungen verwendet werden. \textit{VSNotCopyableException} wird w\"{a}hrend einem Kopierversuch eines nicht-kopierbaren Ereignis geworfen. \textit{VSNegatieNumberException} wird geworfen, wenn intern negative Zahlen dort auftreten wo sie es nicht sollten. Wenn ein Editorobjekt die Benutzereingabe einer Integer-Vektor-Variable nicht parsen kann, so greifen es auf \textit{VSParseIntegerVectorException} zur\"{u}ck.
+Im Paket \textit{exceptions} befinden sich lediglich einige Objekte die für Ausnahmebehandlungen verwendet werden. \textit{VSNotCopyableException} wird während einem Kopierversuch eines nicht-kopierbaren Ereignis geworfen. \textit{VSNegatieNumberException} wird geworfen, wenn intern negative Zahlen dort auftreten wo sie es nicht sollten. Wenn ein Editorobjekt die Benutzereingabe einer Integer-Vektor-Variable nicht parsen kann, so greifen es auf \textit{VSParseIntegerVectorException} zurück.
\begin{figure}
\centering
@@ -677,33 +677,33 @@ Im Paket \textit{exceptions} befinden sich lediglich einige Objekte die f\"{u}r \section{Programmierrichtlinien}
-Die Programmierrichtlinien \cite{Richtlinien} entsprechen in den meisten F\"{a}llen denen aus der Vorlesung \cite{OOS}. Die Main-Methode befindet sich in der Klasse \textit{simulator.VSMain}.
+Die Programmierrichtlinien \cite{Richtlinien} entsprechen in den meisten Fällen denen aus der Vorlesung \cite{OOS}. Die Main-Methode befindet sich in der Klasse \textit{simulator.VSMain}.
\begin{itemize}
- \item Alle Klassen- und Interfacenamen beginnen mit großen Buchstaben, w\"{a}hrend alle Variablen-, Methoden- und Attributnamen mit kleinen Buchstaben beginnen. Namen finaler Variablen und Attribute sind komplett in Großbuchstaben gehalten.
+ \item Alle Klassen- und Interfacenamen beginnen mit großen Buchstaben, während alle Variablen-, Methoden- und Attributnamen mit kleinen Buchstaben beginnen. Namen finaler Variablen und Attribute sind komplett in Großbuchstaben gehalten.
\item Alle Quelltext-Dateien besitzen einen Header, der Informationen der verwendeten Lizenz angibt.
- \item Alle Quelltext-Dateien sind vollst\"{a}ndig mit Javadoc dokumentiert worden.
+ \item Alle Quelltext-Dateien sind vollständig mit Javadoc dokumentiert worden.
\item Der komplette Quelltext inklusive Dokumentation werden in englischer Sprache verfasst.
- \item Eine Quelltext-Datei hat eine maximale Zeilenl\"{a}nge von 80 Zeichen. Eine Ausnahme stellt die Klasse \textit{prefs.VSDefaultPrefs} dar, denn hier befinden sich auch l\"{a}ngere Texte die in Strings abgespeichert werden, wo manuelle Zeilenumbr\"{u}che wenig Sinn ergeben.
+ \item Eine Quelltext-Datei hat eine maximale Zeilenlänge von 80 Zeichen. Eine Ausnahme stellt die Klasse \textit{prefs.VSDefaultPrefs} dar, denn hier befinden sich auch längere Texte die in Strings abgespeichert werden, wo manuelle Zeilenumbrüche wenig Sinn ergeben.
\item Es werden zuerst Klassen aus der Java-Standardbibliothek importiert, bevor Klassen aus dem VS-Simulator selbst importiert werden.
- \item F\"{u}r die Einr\"{u}ckung des Quelltextes wird das Tool \textit{astyle} mit den Aufrufparametern \textit{--style=java --mode=java} verwendet. Hierbei wird eine Einr\"{u}ckungsl\"{a}nge von 4 Zeichen verwendet.
+ \item Für die Einrückung des Quelltextes wird das Tool \textit{astyle} mit den Aufrufparametern \textit{--style=java --mode=java} verwendet. Hierbei wird eine Einrückungslänge von 4 Zeichen verwendet.
\item Namen abstrakter Klassen tragen stets das Prefix \textit{VSAbstract}.
- \item Namen aller Klassen und Interfaces tragen als Prefix stets \textit{VS}, was f\"{u}r Verteilte Systeme steht.
+ \item Namen aller Klassen und Interfaces tragen als Prefix stets \textit{VS}, was für Verteilte Systeme steht.
\item Namen aller Protokollklassen tragen als Postfix \textit{Protocol} (zum Beispiel \textit{VSPingPongProtocol}).
- \item \"{U}berall wo es Sinn ergibt werden Java-Generic-Datentypen verwendet (z.B. \textit{java.util.Vector<Integer>} anstelle von \textit{java.util.Vector}.
+ \item überall wo es Sinn ergibt werden Java-Generic-Datentypen verwendet (z.B. \textit{java.util.Vector<Integer>} anstelle von \textit{java.util.Vector}.
\end{itemize}
\section{Entwicklungsumgebung}
-In diesem Teilkapitel soll ein kleiner Einblick in die Umgebung, in der der Simulator entwickelt wurde, gew\"{a}hrt werden. F\"{u}r diese Diplomarbeit wurde ausschließlich Open Source Software verwendet. Die einzige Ausnahme stellt Microsoft Windows XP dar, worauf der Simulator zus\"{a}tzlich getestet wurde. Der Simulator wurde jedoch haupts\"{a}chlich unter dem Betriebssystem FreeBSD 7.0, was ein open source Unix-Derivat ist, programmiert.
+In diesem Teilkapitel soll ein kleiner Einblick in die Umgebung, in der der Simulator entwickelt wurde, gewährt werden. Für diese Diplomarbeit wurde ausschließlich Open Source Software verwendet. Die einzige Ausnahme stellt Microsoft Windows XP dar, worauf der Simulator zusätzlich getestet wurde. Der Simulator wurde jedoch hauptsächlich unter dem Betriebssystem FreeBSD 7.0, was ein open source Unix-Derivat ist, programmiert.
-Wie bereits bekannt ist, wurde Sun's Java, was mittlerweile auch Open Source Software ist, in der Version 6 (1.6) als die Implementierungssprache gew\"{a}hlt und f\"{u}r die Quelltextdokumentation kam Javadoc- und f\"{u}r die automatische Quelltexteinr\"{u}ckung astyle zum Einsatz. Als Built-Tool wurde hier auf Apache Ant gesetzt. F\"{u}r die Erstellung dieses PDF-Dokumentes wurde LaTeX in Verbindung mit dem Built-Tool GNU Make und Rubber verwendet. Eine Rechtschreib\"{u}berpr\"{u}fung wurde mit aspell sowie OpenOffice.org durchgef\"{u}hrt. xPDF diente als PDF-Anzeigeprogramm.
+Wie bereits bekannt ist, wurde Sun's Java, was mittlerweile auch Open Source Software ist, in der Version 6 (1.6) als die Implementierungssprache gewählt und für die Quelltextdokumentation kam Javadoc- und für die automatische Quelltexteinrückung astyle zum Einsatz. Als Built-Tool wurde hier auf Apache Ant gesetzt. Für die Erstellung dieses PDF-Dokumentes wurde LaTeX in Verbindung mit dem Built-Tool GNU Make und Rubber verwendet. Eine Rechtschreibüberprüfung wurde mit aspell sowie OpenOffice.org durchgeführt. xPDF diente als PDF-Anzeigeprogramm.
-Als Versionierungssystem wurde SVN (Subversion) verwendet. F\"{u}r den Zugriff auf das SVN-Repository mittels HTTPS (Hypertext Transfer Protocol Secure) wurde der Apache-Websever mit WebDAV-Plugin verwendet. Zudem kam WebSVN als Webschnitstelle des SVN-Repositories zum Einsatz. Mozilla Firefox diente f\"{u}r das Betrachten der Javadocs und der WebSVN-Oberfl\"{a}che.
+Als Versionierungssystem wurde SVN (Subversion) verwendet. Für den Zugriff auf das SVN-Repository mittels HTTPS (Hypertext Transfer Protocol Secure) wurde der Apache-Webserver mit WebDAV-Plugin verwendet. Zudem kam WebSVN als Webschnittstelle des SVN-Repository zum Einsatz. Mozilla Firefox diente für das Betrachten der Javadocs und der WebSVN-Oberfläche.
-F\"{u}r schreiben von Java-Quelltext wurde GVim (Graphical Vi IMproved) sowie Eclipse verwendet. Eclipse unterst\"{u}tzt bessere Code-Refactoring-Methoden, w\"{a}hrend GVim mit seiner Flexibilit\"{a}t und schnelleren Editierm\"{o}glichkeiten und mit Vim-Script, der eigenen Script-Engine, gl\"{a}nzt. Es wurden ausserdem das JAutoDoc- (f\"{u}r die Erstellung von Javadoc-Kommentate) und das Subversion-Eclipse-Plugin verwendet. Je nach Zweck wurde zwischen diesen beiden Umgebungen gewechselt. F\"{u}r das Verfassen des LaTeX-Dokumentes wurde GVim verwendet.
+Für schreiben von Java-Quelltext wurde GVim (Graphical Vi IMproved) sowie Eclipse verwendet. Eclipse unterstützt bessere Code-Refactoring-Methoden, während GVim mit seiner Flexibilität und schnelleren Editiermöglichkeiten und mit Vim-Script, der eigenen Script-Engine, glänzt. Es wurden außerdem das JAutoDoc- (für die Erstellung von Javadoc-Kommentare) und das Subversion-Eclipse-Plugin verwendet. Je nach Zweck wurde zwischen diesen beiden Umgebungen gewechselt. Für das Verfassen des LaTeX-Dokumentes wurde GVim verwendet.
-S\"{a}mtliche UML-Diagramme wurden mit ArgoUML angefertigt und die Screenshots mit The GIMP (GNU Image Manipulation Program) sowie ImageMagick nachbearbeitet. Mit dem zip-Programm wurden alle VS-Simulator Distributionen verpackt.
+Sämtliche UML-Diagramme wurden mit ArgoUML angefertigt und die Screenshots mit The GIMP (GNU Image Manipulation Program) sowie ImageMagick nachbearbeitet. Mit dem zip-Programm wurden alle VS-Simulator Distributionen verpackt.
\subsubsection{Linkliste der verwendeten Software}
|
