ScriptEngines/de

From OpenSimulator

Revision as of 03:43, 5 March 2024 by Manni (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Contents

Skript-Engines

OpenSimulator unterstützt das Skripten über Skript-Engines. Skript-Engines sind normale Regionsmodule.

Diese Seite behandelt gemeinsame Teile von Skript-Engines.
OpenSimulator hat derzeit zwei öffentliche Skript-Engines, XEngine und YEngine.
Für weitere Informationen siehe bitte XEngine und YEngine.

Für Informationen zur alten DotNetEngine, die in OpenSimulator 0.6.8 veraltet war und anschließend aus dem Kernbaum entfernt wurde, siehe bitte DotNetEngine und OpenSim.Region.ScriptEngine.

Hinweis: Diese Seite stellt ein Implementierungsziel dar. Vieles davon funktioniert bereits, aber einige Teile sind noch nicht implementiert.

OpenSim.ini-Einstellungen

Mehrere Skript-Engines können jetzt gleichzeitig aktiv sein. Die Direktive script_engine in der OpenSim.ini wird nicht mehr verwendet! Stattdessen finden Sie im Abschnitt [Startup] jetzt

DefaultScriptEngine = "XEngine"

XEngine ist standardmäßig aktiviert. Um es auf eine andere Engine zu ändern, ändern Sie die Kommentare, um die Zeile zu aktivieren

DefaultScriptEngine = (irgendein Engine-Name)

XEngine kann auch deaktiviert werden, indem Sie

[XEngine]
Enabled = false

setzen. Diese sind standardmäßig auf true gesetzt.

OpenSimulator sollte in der Lage sein, mehrere Skript-Engines gleichzeitig auszuführen, aber dies sollte vermieden werden.

Verwendung mehrerer Skript-Engines

Um ein Skript auf einer bestimmten Engine auszuführen, beginnen Sie das Skript mit einer ersten Zeile wie:

//XEngine: oder //someOtherEngineName:

Optional kann dies durch einen Sprachcode ergänzt werden:

//XEngine:lsl
//someOtherEngineName:lsl

Beachten Sie: Es gibt einen kleinen Seiteneffekt. Wenn Sie Ihr Skript mit irgendetwas wie

//beliebiger Text:

(beginnend mit "//" und endend mit ":") starten, erhalten Sie einen Fehler

"Ausgewählte Engine nicht verfügbar. Skript wird auf XEngine ausgeführt."

Eine Skript-Engine definiert eine Möglichkeit, ein Skript zu laden und auszuführen. Sie verwendet Compiler und Laufzeiten, um dies zu erreichen.

Compiler nehmen Skripttext und wandeln ihn in eine .NET-Assembly um. Eine solche Assembly muss auf eine Laufzeit verweisen, die API-Stubs bereitstellt.

Derzeit existiert ein Compiler für lsl.

Eine Laufzeit existiert für die LSL-API und für die OSSL-API. LSL Status/Functions

Im Folgenden wird die Verzeichnisstruktur (unter /OpenSim/Region/) beschrieben:

ScriptEngines/XEngine/ Die Engine selbst. Methoden zum Verwalten von Threads, AppDomains usw.
ScriptEngines/Interfaces/ Gemeinsame Schnittstellen, die zur Erstellung von Skript-Engines und -Komponenten verwendet werden
ScriptEngines/Shared/CodeTools/ Der aktuelle Compiler
ScriptEngines/Shared/Api/Interface/ Die API-Schnittstellen (siehe unten)
ScriptEngines/Shared/Api/Implementation/ Die API-Implementierungen (siehe unten)
ScriptEngines/Shared/Api/Runtime/ Die API-Laufzeiten (siehe unten)

Eine API wird als Implementierung, Schnittstelle und Laufzeit definiert. Der Grund für diesen scheinbar komplizierten Ansatz liegt darin, dass Skripte in AppDomains ausgeführt werden, die vom normalen OpenSimulator-Code getrennt sind.

Die Erstellung einer API ist ziemlich unkompliziert, aber es müssen einige Namenskonventionen beachtet werden, damit die Api korrekt funktioniert. Die Skriptlaufzeit verwendet Reflexion, um Api-Laufzeiten mit Implementierungen abzugleichen, und sie verwendet Namen, um diese Abgleiche zu finden.

Erstellen Sie zuerst Ihre API-Implementierung.

namespace OpenSim.Region.ScriptEngine.Shared.Api
 {
     public class XXX_Api: MarshalByRefObject, IXXX_Api, IScriptApi
     {
        internal IScriptEngine m_ScriptEngine;
        internal SceneObjectPart m_host;
        internal uint m_localID;
        internal UUID m_itemID;
 
csharp
 
    public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
    {
        m_ScriptEngine = ScriptEngine;
        m_host = host;
        m_localID = localID;
        m_itemID = itemID;
    }
 
    public void myApiFunction()
    {
    }
 }
 
}

Hier wird der Klassenname (XXX_Api) von Reflexion verwendet, er muss mit "_Api" enden, um als Api erkannt zu werden.

Platzieren Sie die Datei in OpenSim/Region/ScriptEngines/Shared/Api/Implementaton/.

Nach Konvention sollte sie XXX_Api.cs genannt werden.

Als Nächstes erstellen Sie eine Schnittstelle, um die Api mit der Laufzeit zu verbinden:

namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
 {
     public interface IXXX_Api
     {
         void myApiFunction();
     }
 }

Platzieren Sie diese Datei in OpenSim/Region/ScriptEngines/Api/Interface, benannt als IXXX_Api.

Jetzt wird die Stub-Datei benötigt, um das Skript mit der Api zu verbinden. Diese Stub-Datei wird in die Skript-AppDomain geladen und sollte keine Verarbeitung enthalten. Sie leitet lediglich die Aufrufe an die Api außerhalb der AppDomain weiter.

namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
 {
     public partial class ScriptBaseClass : MarshalByRefObject
     {
         public IXXX_Api m_XXX_Functions;
 
csharp
 
     public void ApiTypeXXX(IScriptApi api)
     {
         if(!(api is IXXX_Api))
             return;
 
         m_XXX_Functions = (IXXX_Api)api;
     }
 
     public void myApiFunction()
     {
         m_XXX_Functions.myApiFunction();
     }
 }
 
}

Speichern Sie dies in OpenSim/Region/ScriptEngines/Shared/Api/Runtime, benannt als XXX_Stub.cs

Hier ist der Name ApiTypeXXX die obligatorische Bezeichnung, nach der die Skript-Engine diese Api erkennt und mit der API-Implementierung verknüpft.

Bitte beachten Sie, dass Ihre Api hier Teil einer teilweisen Klasse wird, die wiederum die Basisklasse des Skripts wird.

Beim Laden des Skripts wird die Api-Laufzeit (Stub) mit einem Verweis auf die IScriptApi-Schnittstelle der Implementierung aufgerufen. Diese wird dann als benutzerdefinierte Schnittstelle verwendet, um auf die Funktionsimplementierungen zuzugreifen.

Der Grund, warum wir die Implementierung nicht direkt referenzieren können, besteht darin, dass dies dazu führen würde, dass die gesamte Implementierung in die Skript-AppDomain geladen wird. Wir müssen dies vermeiden, um den Speicherbedarf gering zu halten.

Das Verzeichnis OpenSim/Region/ScriptEngines/Shared/CodeTools enthält alle Compiler, Konverter und andere Code-Manipulationstools. Es wird von allen Skript-Engines gemeinsam genutzt. Aufgrund des gemeinsam genutzten Compilers können die Skript-Engines auch kompilierte Assemblys gemeinsam nutzen, sodass jedes Skript nicht für jede Skript-Engine neu kompiliert werden muss.

Code-Generierung

Die Generierung von LSL-Code in C# ist für alle Skript-Engines gemeinsam. Dies wird derzeit durch die Übersetzung von LSL-Code in C#-Code und dessen anschließende Kompilierung erreicht. Der kompilierte Code ruft dann Methoden in LSL_Api.cs (OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs) auf, die den LSL-Funktionen entsprechen, oder Methoden in OSSL_Api.cs für OSSL-Funktionen usw.

Seit OpenSimulator 0.7.4 gibt es auch einen Mechanismus, um Skriptfunktionen aus Regionsmodulen verfügbar zu machen, ohne OpenSimulator selbst zu patchen. Weitere Details finden Sie unter OSSL_Script_Library/ModInvoke.

Die Analyse des LSL-Skripts wird von CSCodeGenerator.Convert() (OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs) gestartet. Dies nimmt das LSL und verwendet einen Parser/Lexer, um es in einen abstrakten Syntaxbaum (AST) umzuwandeln, bevor es dann über den LSL2CSCodeTransformer in C# konvertiert wird.

Der Parser (lsl.parser.cs) und Lexer (lsl.lexer.cs) werden mit Malcolm Crowes Compiler-Tools in C# aus dem trunk/managed/lsl2cs-Verzeichnis im opensim-libs-Repository aus den Dateien lsl.parser und lsl.lexer generiert. Beachten Sie, dass Sie bei einer Neugenerierung dies tun müssen ändern Sie die vorletzte Zahl im Array arr in der generierten Klasse ArgumentDeclarationList_5 in lsl.parser.cs von 1 auf 0. Wir müssen herausfinden, warum dieser Fehler auftritt.

Das konvertierte C# wird dann zu einer DLL kompiliert durch die OpenSimulator Compiler-Klasse (über die Methode PerformScriptCompile(), die auch die LSL -> C#-Konvertierung ausführt, wie oben beschrieben).

Sie können das transformierte C# sehen, das kompiliert wurde, indem Sie

[XEngine]
WriteScriptSourceToDebugFile = true

in Ihrer OpenSim.ini-Datei einstellen. Dies wird im Verzeichnis bin/ScriptEngines/<region-id>/ mit dem Dateinamen CommonCompiler_source_CommonCompiler_compiled_<script-asset-id>.lsl erscheinen.

Personal tools
General
About This Wiki