Plug-in-Schnittstelle: Unterschied zwischen den Versionen

Aus OMSIWiki
Wechseln zu:Navigation, Suche
(zunächst nur Foren-Link als Erinnerung)
 
(Anlegen des Artikels)
Zeile 1: Zeile 1:
http://omnibussimulator.forumieren.com/t2628-api-dll-fur-zugriff-auf-interne-variablen
+
''Hinweis: Noch nicht ins Englische übersetzt!''
 +
 
 +
= Allgemeines Prinzip =
 +
 
 +
OMSI verfügt über die Möglichkeit, 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 *opt-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, zunächst der Hauptunit (Test.dpr):
 +
 
 +
<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 durchläuft OMSI diese Schleife für alle in der *.opl-Datei gelisteten lokalen Variablen. 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.
  
 
[[Kategorie:Nachschlagewerk_für_Addon-Entwickler]]
 
[[Kategorie:Nachschlagewerk_für_Addon-Entwickler]]

Version vom 18. November 2011, 01:25 Uhr

Hinweis: Noch nicht ins Englische übersetzt!

Allgemeines Prinzip

OMSI verfügt über die Möglichkeit, 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).

Oberfläche des Beispiel-Plugins

Aufbau der *opt-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, zunächst der Hauptunit (Test.dpr):

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 durchläuft OMSI diese Schleife für alle in der *.opl-Datei gelisteten lokalen Variablen. 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.