Short: External modules in LPC
From: Andy <Andreas.Klauer@epost.de>
Date: Tue, 4 Jun 2002 20:52:11 +0200
Type: Feature
State: New

Hi Lars,

immer, wenn ich mich langweile, komme ich auf dumme Gedanken. So hat es sich 
auch gestern zugetragen, bei einer trdeligen Bahnfahrt *schnarch*.

Wie wre es, Fremdkrper in LPC integrierbar zu machen.

Mit "Fremdkrper" meine ich:

- Fremdsprachen, z.B. Perl, UDL, ...
- Externe Programme, z.B. diff/patch, Tiny Fugue, ... ;-)
- Interne Programme, z.B. Pfadfinder :-)
- Alles mgliche andere sonst auch noch


Wie ich mir das ungefhr vorstelle:

Jeder Fremdkrper ist im Grunde ein Modul, das zur Compile-Zeit in den Driver 
eingebunden wird. (Meinetwegen auch dynamisch, aber das wre wohl zu 
kompliziert).

Jedes Modul besitzt einen Grundstock von Funktionen, die vom LPC-Objekt aus 
direkt oder indirekt aufgerufen werden.  (Mehr dazu gleich). Im Moment fallen 
mir dazu nur zwei Funktionen ein:

void modul_embedded(string text, varargs mixed * options) (Indirekter Aufruf)
mixed modul_exec(string type, varargs mixed * data) (Direkter Aufruf)

Der Driver selbst muss den Modulen ausserdem Service-Funktionen anbieten:

  - Von welchem Objekt wird das Modul gerade reprsentiert?
  - Aufruf von LFuns (im eigenen und anderen Objekten), SEFuns, EFuns
  - Zugriff auf lokale & private Variablen & Funktionen des eigenen Objektes
  - berprfung & Modifikation des Eval-Verbrauchs etc.


Desweiteren brauchts noch ein paar Hooks, bzw. Funktionen die im Master 
aufgerufen werden, damit dort z.B. das Zugriffsrecht auf Fremdkrper geregelt 
werden kann.

Dann natrlich muss die generelle Verwendung von Modulen in LPC mglich 
gemacht werden. Wie das aussehen knnte, k.A., ich mache mal ein Beispiel als 
Prprozessoranweisungen:

#use modulname[, modulname2[, ..., modulnameN]

(Lars says: inherit "modulname" would be more LPC like)

#embed [modulname]
#endembed


#use Gibt an, welche Module dieses Objekt verwenden mchte. Das Objekt 
reprsentiert also ab diesem Zeitpunkt die Module. Bei den Modulen handelt es 
sich also um so etwas hnliches wie Inherits.
Mit der Einbindung der Module stehen dem Objekt die Grundfunktionen zur 
Verfgung, also z.B. modulname_exec. (Oder wenn es einfacher ist, auch 
modul_exec(name, ...)).

Zwischen #embed [modulname] und #endembed kann man Text einbinden, der nicht 
von LPC / Prprozessor geparsed wird, sondern der Funktion modul_embedded 
unmodifiziert bergeben wird. (Oder evtl. besser, vom Modul abgefragt werden 
kann.) Dabei knnte es sich z.B. um Perl-Sourcecode handeln.  


Der MUD-Wizard knnte dann solchen LPC-Code schreiben:

------ Beispiel 1 -------
// Ein Raum mit der Langbeschreibung "Hello World."

#use perl

#embed
print "Hello World.\n"
#endembed

inherit "room";

void create()
{
    string str = modul_exec("perl", M_EMBEDDED_ARG);
    // M_EMBEDDED_ARG ist einfach ein Flag, das dem Modul sagt, dass der 
embedded text verwendet werden soll
    

    set_long(str);
}

----- Ende Beispiel 1 -----

----- Beispiel 2 -----
// Ein diff/patch in LPC :-)

#use diff,patch

string diff(string file1, string file2, varargs mixed * options)
{
    return apply(#'modul_exec, "diff", file1, file2, options);
    // Leserechte etc. checkt das Modul selbst.     
}

int patch(string file, string patch, varargs mixed * options)
{
    return apply(#'modul_exec, "patch", file1, patch, options);
}
---- Ende Beispiel 2 ----

---- Beispiel 3 ----
// Ein Pfadfinder.

#use pfadfinder

string suche_pfad(mixed start, mixed ziel, mixed * real_big_room_info_matrix)
{
    return modul_exec("pfadfinder", start, ziel, real_big_room_info_matrix);  
}
---- Ende Beispeil 3 ----


Natrlich gibts schon sowas wie ERQ. Im Gegensatz dazu wren solche Module 
jedoch keine Schnittstellen im herkmmlichen Sinn (auch wenn z.B. ein 
Perl-Modul eine Schnittstelle zu einem externen Perl-Interpreter darstellen 
knnte).

Der Vorteil wre, da eben die Module teil des LPC-Objektes wren; die Module 
werden also durch LPC-Objekte reprsentiert. Als Teil des Drivers kann man 
den Modulen Daten bergeben, wie jeder anderen LPC-Funktion auch, in Form von 
Referenzen, komplexen Datentypen etc, was ber den ERQ nicht mglich wre.

Wenn Module andere EFuns aufrufen, sollte die EFun dabei denken, das Objekt 
selbst htte diese Funktion aufgerufen. Schreibrechte und sonstige 
MUD-Internas lieen sich so besser abhandeln als ber die ERQ-Schnittstelle.

Man kann damit eine Ecke verrcktere Sachen machen als mit ERQ.

z.B. ein #use tinyfugue im Player. Immer wird darber gewitzelt, TinyFugue in 
LPC zu bersetzen und das den Telnet-Spielern als Client vorzusetzen. Als 
Fremdkrpereinbindung wre es relativ einfach zu lsen, indem man den Output 
vom MUD an den Player dem TinyFugue-Modul als Input vorsetzt und den Output 
vom TinyFugue wiederum an den Player schickt... 

Zumindest theoretisch.


Danke soweit schonmal frs Lesen meiner wirren Gedanken..

*duck-und-unters-sofa-kriech* ;-)

Gruss
Dumling Menaures

