Plug-in-Schnittstelle: Unterschied zwischen den Versionen
(zunächst nur Foren-Link als Erinnerung) |
K |
||
(6 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | + | ''Hinweis: Änderungen dieses Artikels wurden noch nicht ins Englische übersetzt!'' | |
+ | |||
+ | ''OMSI-Version: 1.00 - 2.00, für OMSI 2 bitte letztes Kapitel beachten!'' | ||
+ | |||
+ | = Allgemeines Prinzip = | ||
+ | |||
+ | Es besteht die Möglichkeit, für den OMSI Plugin-DLLs zu programmieren, welche Lese- und Schreibzugriff auf die [[System-_und_vordefinierte_lokalen_Variablen#Fahrzeuge|Fahrzeugvariablen]] haben und [[Scriptsystem#Trigger|Fahrzeug-Trigger]] auslösen können. | ||
+ | |||
+ | Jedes Plugin besteht aus einer [[Konfigurationsdatei]] mit der Dateiendung *.opl und einer zugehörigen DLL. Beide Dateien müssen im Verzeichnis "OMSI\plugins" liegen. | ||
+ | |||
+ | = Beschreibung des Beispiels = | ||
+ | |||
+ | In OMSI enthalten ist bereits ein Beispiel-Plugin enthalten. Um es zu aktivieren, muss die Datei "test.txt" im "<OMSI>\plugins"-Verzeichnis in "test.opl" umbenannt werden. | ||
+ | |||
+ | == Funktionsumfang == | ||
+ | |||
+ | Dieses Plugin hat drei Funktionen: Einen Tacho (analog und digital) ganz oben, einen Sollwertregler für den roten Heizungsregler (obwohl da falscherweise "Rollband-Sollwert" steht) und einen Türtaster "Button1" (der aber trotzdem nur funktioniert, wenn die Haltestellenbremse aktiv und die Elektrik an ist). | ||
+ | |||
+ | [[Datei:Beispiel-Plugin.jpg|600px|thumb|right|Oberfläche des Beispiel-Plugins]] | ||
+ | |||
+ | == Aufbau der *.opl-Datei == | ||
+ | |||
+ | <pre> | ||
+ | To activate, rename this file to "test.opl" | ||
+ | |||
+ | [dll] | ||
+ | Test.dll | ||
+ | |||
+ | [varlist] | ||
+ | 2 | ||
+ | Velocity | ||
+ | cockpit_heizregler_temp | ||
+ | |||
+ | [triggers] | ||
+ | 1 | ||
+ | bus_doorfront0 | ||
+ | </pre> | ||
+ | |||
+ | Die erste Zeile ist nur eine Kommentarzeile. Der [dll]-Befehl gibt den Dateinamen der zugehörigen DLL an. | ||
+ | |||
+ | Der [varlist]-Befehl beginnt mit der Anzahl der zu erwartenden (lokalen) Fahrzeugvariablen. Hierbei können auch User-Variablen eines bestimmten Busses angegeben werden. Wenn der tatsächlich gefahrene Bus dann diese Variable nicht hat, dann werden die zugehörigen Zugriffe natürlich nicht durchgeführt. | ||
+ | |||
+ | Die Variable mit dem Index 0 ist also bei dieser DLL "Velocity", die Variable mit dem Index 1 ist "cockpit_heizregler_temp". | ||
+ | |||
+ | Der [triggers]-Befehl beginnt ebenfalls mit der Anzahl der zu erwartenden Fahrzeugtrigger. In diesem Fall ist dies nur ein Trigger: "bus_doorfront0" mit dem Index 0. | ||
+ | |||
+ | == Aufbau der DLL == | ||
+ | |||
+ | Anhand der Beispiel-DLL wird nun erklärt, wie der zugehörige Delphi-Code aussehen soll. Im Allgemeinen sollte es möglich sein, auch mit anderen Programmiersprachen passende DLLs zu programmieren. Ausprobiert habe ich dies allerdings nicht. | ||
+ | |||
+ | Die DLL besteht aus zwei Units. Erklärt wird aber nur die Hauptunit (Test.dpr) (die zweite Unit enthält nur einige wenige nicht-relevante Implementierungen für die Form): | ||
+ | |||
+ | <pre> | ||
+ | library Test; | ||
+ | |||
+ | uses | ||
+ | SysUtils, | ||
+ | Dialogs, | ||
+ | Classes, | ||
+ | TestU in 'TestU.pas' {Form1}; | ||
+ | |||
+ | {$R *.res} | ||
+ | |||
+ | procedure Start( AOwner: TComponent ); stdcall; | ||
+ | begin | ||
+ | form1 := TForm1.Create( AOwner ); | ||
+ | form1.Show; | ||
+ | end; | ||
+ | |||
+ | procedure Finalize; stdcall; | ||
+ | begin | ||
+ | form1.Free; | ||
+ | end; | ||
+ | |||
+ | procedure AccessVariable( varindex: word; var value: single; var write: boolean ); stdcall; | ||
+ | begin | ||
+ | case varindex of | ||
+ | 0: | ||
+ | begin | ||
+ | form1.Label2.Caption := floattostrF( value, ffFixed, 5, 1 ) + ' km/h'; | ||
+ | form1.Gauge1.Progress := round( value ); | ||
+ | write := false; | ||
+ | end; | ||
+ | 1: | ||
+ | begin | ||
+ | value := form1.TrackBar1.Position / 30; | ||
+ | write := true; | ||
+ | end; | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | procedure AccessTrigger( triggerindex: word; var active: boolean ); stdcall; | ||
+ | begin | ||
+ | case triggerindex of | ||
+ | 0: | ||
+ | begin | ||
+ | active := form1.button1_pressed; | ||
+ | end; | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | exports | ||
+ | AccessVariable, | ||
+ | AccessTrigger, | ||
+ | Start, | ||
+ | Finalize; | ||
+ | |||
+ | |||
+ | begin | ||
+ | end. | ||
+ | </pre> | ||
+ | |||
+ | Zunächst ist der letzte Abschnitt "exports" zu beachten: Die vier gelisteten Prozeduren sollen von der DLL angeboten werden: ''AccessVariable'', ''AccessTrigger'', ''Start'' und ''Finalize''. | ||
+ | |||
+ | Die vier Prozeduren haben folgenden Aufbau: | ||
+ | |||
+ | === Aufbau der Prozedur ''Start'' === | ||
+ | |||
+ | ''Start( AOwner: TComponent )'' wird am Anfang aufgerufen und ermöglicht es der DLL, sich zu initialisieren. In diesem Fall wird ''Form1'' erzeugt und der gleichnamigen Variable zugeordnet, welche sich jedoch in der Unit ''TestU'' befindet. Als zweiter Schritt wird der ''Show''-Befehl aufgerufen, um die ''Form1'' anzuzeigen. ''Start'' übergibt den Parameter "AOwner", welcher der Handler des Hauptprogramms von OMSI darstellt. | ||
+ | |||
+ | === Aufbau der Prozedur ''Finalize'' === | ||
+ | |||
+ | ''Finalize'' dagegen wird beim Schließen aufgerufen. Hier wird schlicht das Objekt ''Form1'' zerstört. | ||
+ | |||
+ | === Aufbau der Prozedur ''AccessVariable'' === | ||
+ | |||
+ | Im Betrieb ruft OMSI diese Prozedur für alle in der *.opl-Datei gelisteten lokalen Variablen auf. Sie übergibt dabei stets den Index der Variable (''varindex''). Die Prozedur kann nun ihrerseits die Variablen ''value'' und ''write'' schreiben. | ||
+ | |||
+ | Bei einem Lesezugriff kann die Prozedur wie im Beispiel unter "0:" die Variable über ''value'' einfach auslesen. Es ist aber wie unter "1" auch möglich, dem Wert von ''value'' einen neuen Wert zuzuweisen. Dann aber muss die Variable ''write'' auch auf ''wahr'' gesetzt werden, damit der Wert von OMSI übernommen wird. Im Beispiel wird die ''TrackBar'' ausgelesen und der Wert auf den Wert von ''value'' geschrieben. | ||
+ | |||
+ | === Aufbau der Prozedur ''AccessTrigger'' === | ||
+ | |||
+ | Diese Prozedur arbeitet recht ähnlich. Hier allerdings wird die Triggerliste durchgearbeitet. Die DLL kann bei Aufruf dieser Funktion den Wert ''active'' auf ''true'' setzen; dann löst OMSI den gewünschten Trigger aus. | ||
+ | |||
+ | = Ausführliches Tutorial = | ||
+ | |||
+ | Ein ausführliches Tutorial zur Nutzung dieser Schnittstelle - allerdings mit der Programmiersprache C++ - ist hier im Wiki in der Kategorie [[OMSI Plugin Framework|Tutorials]] zu finden. | ||
+ | |||
+ | = Neuerungen OMSI2 = | ||
+ | |||
+ | Aus Gründen der Kompatibilität wurden die folgenden Prozedurnamen geändert: | ||
+ | |||
+ | ''Start'' ==> ''PluginStart'' sowie | ||
+ | |||
+ | ''Finalize'' ==> ''PluginFinalize''. | ||
+ | |||
+ | Außerdem wurde die *.opl-Datei um die Schlüsselworte [stringvarlist] und [systemvarlist] ergänzt, mit denen nun auch auf String- und Systemvariablen zugegriffen werden kann. Deren Syntax entspricht der von [varlist]. Dementsprechend wurden folgende Methoden ergänzt: | ||
+ | |||
+ | <pre> | ||
+ | AccessSystemVariable( varindex: word; var value: single; var write: boolean ); | ||
+ | AccessStringVariable( varindex: word; str: PWideChar; var write: boolean ); | ||
+ | </pre> | ||
[[Kategorie:Nachschlagewerk_für_Addon-Entwickler]] | [[Kategorie:Nachschlagewerk_für_Addon-Entwickler]] | ||
+ | |||
+ | [[en:Plug-In Interface]] |
Aktuelle Version vom 11. Februar 2014, 10:46 Uhr
Hinweis: Änderungen dieses Artikels wurden noch nicht ins Englische übersetzt!
OMSI-Version: 1.00 - 2.00, für OMSI 2 bitte letztes Kapitel beachten!
Inhaltsverzeichnis
Allgemeines Prinzip
Es besteht die Möglichkeit, für den OMSI Plugin-DLLs zu programmieren, welche Lese- und Schreibzugriff auf die Fahrzeugvariablen haben und Fahrzeug-Trigger auslösen können.
Jedes Plugin besteht aus einer Konfigurationsdatei mit der Dateiendung *.opl und einer zugehörigen DLL. Beide Dateien müssen im Verzeichnis "OMSI\plugins" liegen.
Beschreibung des Beispiels
In OMSI enthalten ist bereits ein Beispiel-Plugin enthalten. Um es zu aktivieren, muss die Datei "test.txt" im "<OMSI>\plugins"-Verzeichnis in "test.opl" umbenannt werden.
Funktionsumfang
Dieses Plugin hat drei Funktionen: Einen Tacho (analog und digital) ganz oben, einen Sollwertregler für den roten Heizungsregler (obwohl da falscherweise "Rollband-Sollwert" steht) und einen Türtaster "Button1" (der aber trotzdem nur funktioniert, wenn die Haltestellenbremse aktiv und die Elektrik an ist).
Aufbau der *.opl-Datei
To activate, rename this file to "test.opl" [dll] Test.dll [varlist] 2 Velocity cockpit_heizregler_temp [triggers] 1 bus_doorfront0
Die erste Zeile ist nur eine Kommentarzeile. Der [dll]-Befehl gibt den Dateinamen der zugehörigen DLL an.
Der [varlist]-Befehl beginnt mit der Anzahl der zu erwartenden (lokalen) Fahrzeugvariablen. Hierbei können auch User-Variablen eines bestimmten Busses angegeben werden. Wenn der tatsächlich gefahrene Bus dann diese Variable nicht hat, dann werden die zugehörigen Zugriffe natürlich nicht durchgeführt.
Die Variable mit dem Index 0 ist also bei dieser DLL "Velocity", die Variable mit dem Index 1 ist "cockpit_heizregler_temp".
Der [triggers]-Befehl beginnt ebenfalls mit der Anzahl der zu erwartenden Fahrzeugtrigger. In diesem Fall ist dies nur ein Trigger: "bus_doorfront0" mit dem Index 0.
Aufbau der DLL
Anhand der Beispiel-DLL wird nun erklärt, wie der zugehörige Delphi-Code aussehen soll. Im Allgemeinen sollte es möglich sein, auch mit anderen Programmiersprachen passende DLLs zu programmieren. Ausprobiert habe ich dies allerdings nicht.
Die DLL besteht aus zwei Units. Erklärt wird aber nur die Hauptunit (Test.dpr) (die zweite Unit enthält nur einige wenige nicht-relevante Implementierungen für die Form):
library Test; uses SysUtils, Dialogs, Classes, TestU in 'TestU.pas' {Form1}; {$R *.res} procedure Start( AOwner: TComponent ); stdcall; begin form1 := TForm1.Create( AOwner ); form1.Show; end; procedure Finalize; stdcall; begin form1.Free; end; procedure AccessVariable( varindex: word; var value: single; var write: boolean ); stdcall; begin case varindex of 0: begin form1.Label2.Caption := floattostrF( value, ffFixed, 5, 1 ) + ' km/h'; form1.Gauge1.Progress := round( value ); write := false; end; 1: begin value := form1.TrackBar1.Position / 30; write := true; end; end; end; procedure AccessTrigger( triggerindex: word; var active: boolean ); stdcall; begin case triggerindex of 0: begin active := form1.button1_pressed; end; end; end; exports AccessVariable, AccessTrigger, Start, Finalize; begin end.
Zunächst ist der letzte Abschnitt "exports" zu beachten: Die vier gelisteten Prozeduren sollen von der DLL angeboten werden: AccessVariable, AccessTrigger, Start und Finalize.
Die vier Prozeduren haben folgenden Aufbau:
Aufbau der Prozedur Start
Start( AOwner: TComponent ) wird am Anfang aufgerufen und ermöglicht es der DLL, sich zu initialisieren. In diesem Fall wird Form1 erzeugt und der gleichnamigen Variable zugeordnet, welche sich jedoch in der Unit TestU befindet. Als zweiter Schritt wird der Show-Befehl aufgerufen, um die Form1 anzuzeigen. Start übergibt den Parameter "AOwner", welcher der Handler des Hauptprogramms von OMSI darstellt.
Aufbau der Prozedur Finalize
Finalize dagegen wird beim Schließen aufgerufen. Hier wird schlicht das Objekt Form1 zerstört.
Aufbau der Prozedur AccessVariable
Im Betrieb ruft OMSI diese Prozedur für alle in der *.opl-Datei gelisteten lokalen Variablen auf. Sie übergibt dabei stets den Index der Variable (varindex). Die Prozedur kann nun ihrerseits die Variablen value und write schreiben.
Bei einem Lesezugriff kann die Prozedur wie im Beispiel unter "0:" die Variable über value einfach auslesen. Es ist aber wie unter "1" auch möglich, dem Wert von value einen neuen Wert zuzuweisen. Dann aber muss die Variable write auch auf wahr gesetzt werden, damit der Wert von OMSI übernommen wird. Im Beispiel wird die TrackBar ausgelesen und der Wert auf den Wert von value geschrieben.
Aufbau der Prozedur AccessTrigger
Diese Prozedur arbeitet recht ähnlich. Hier allerdings wird die Triggerliste durchgearbeitet. Die DLL kann bei Aufruf dieser Funktion den Wert active auf true setzen; dann löst OMSI den gewünschten Trigger aus.
Ausführliches Tutorial
Ein ausführliches Tutorial zur Nutzung dieser Schnittstelle - allerdings mit der Programmiersprache C++ - ist hier im Wiki in der Kategorie Tutorials zu finden.
Neuerungen OMSI2
Aus Gründen der Kompatibilität wurden die folgenden Prozedurnamen geändert:
Start ==> PluginStart sowie
Finalize ==> PluginFinalize.
Außerdem wurde die *.opl-Datei um die Schlüsselworte [stringvarlist] und [systemvarlist] ergänzt, mit denen nun auch auf String- und Systemvariablen zugegriffen werden kann. Deren Syntax entspricht der von [varlist]. Dementsprechend wurden folgende Methoden ergänzt:
AccessSystemVariable( varindex: word; var value: single; var write: boolean ); AccessStringVariable( varindex: word; str: PWideChar; var write: boolean );