2016-04-26 9 views
4

In der eingebetteten Lua-Umgebung (World of Warcraft - WoW) fehlt die require Funktion.Lua emuliert die Funktion require

Ich möchte einen vorhandenen lua Quellcode (an great OO-library) für den Einsatz in der WoW. Die Bibliothek selbst ist relativ klein (ca. 8 kleine Dateien), aber natürlich verwendet sie stark die require.

World of Warcraft lädt Dateien und Bibliotheken, indem sie in einer XML-Datei definiert, wie:

<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/"> 
    <Script file="LibOne.lua"/> 
    <Script file="LibTwo.lua"/> 
</Ui> 

, aber ich weiß nicht, wie die geringe Bibliothek Manipulation in der WoW erfolgt.

AFAIK in der WoW fehlt auch die package. Tabelle zu. :(

So ist die Frage (n):. Für mich ist die unkomplizierte Möglichkeit eine Funktion schreiben würde, die die require Funktion mit Hilfe der Schnittstelle in WoW verfügbar emulieren wird die Frage, wie Könnte jemand einige Richtungen geben Sie mir

.?

Oder als Alternative für die Portierung der genannten bestehenden Quelle zu WoW, ich brauche ersetzen die require Some.Other.Module Linien in den lua Quellen zu etwas, was WoW wird es verstehen. Was das entspricht/Ersatz für solche require Some.Module in WoW?

Wie das WoW behandelt Module/Bibliotheken auf niedrigem Niveau?

Antwort

3

Sie könnten alle Dateien mit einem der verschiedenen Verschmelzungsskripte, z. amalg. Dann können Sie diese Datei und einen Stub laden, die die require Funktion implementiert die üblichen WoW Art und Weise:

<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/"> 
    <Script file="RequireStub.lua"/> 
    <Script file="AllModules.lua"/><!-- amalgamated Lua modules --> 
    <Script file="YourCode.lua"/> 
</Ui> 

Die Datei RequireStub.lua könnte wie folgt aussehen:

package = {} 
local preload, loaded = {}, { 
    string = string, 
    debug = debug, 
    package = package, 
    _G = _G, 
    io = io, 
    os = os, 
    table = table, 
    math = math, 
    coroutine = coroutine, 
} 
package.preload, package.loaded = preload, loaded 


function require(mod) 
    if not loaded[ mod ] then 
    local f = preload[ mod ] 
    if f == nil then 
     error("module '"..mod..[[' not found: 
     no field package.preload[']]..mod.."']", 1) 
    end 
    local v = f(mod) 
    if v ~= nil then 
     loaded[ mod ] = v 
    elseif loaded[ mod ] == nil then 
     loaded[ mod ] = true 
    end 
    end 
    return loaded[ mod ] 
end 

Dies sollte genug von der package Bibliothek emulieren erhalten Sie eine funktionierende require, die Module in der zusammengefassten Datei lädt. Verschiedene Verschmelzungsskripte benötigen möglicherweise andere Bits von package, so dass Sie wahrscheinlich den generierten Lua-Quellcode betrachten müssen.

Und im spezifischen Fall von Coat müssen Sie möglicherweise auch Stubs für andere Lua-Funktionen implementieren. Z.B.Ich habe gesehen, Coat verwendet die debug Bibliothek ...

+0

Schöne Erklärung, danke für das Codebeispiel. – cajwine

+0

Dieser Code ist wirklich schwer für mich zu verstehen. Was ist der Zweck all dieser Variablen innerhalb von 'loaded'? Kannst du mehr ins Detail gehen? – Hatefiend

+0

@Hatefiend: 'package.loaded' speichert alle geladenen/benötigten Module zwischen. Die oben aufgeführten sind die Module aus der Standardbibliothek von Lua. In "normalem" Lua sind sie über 'require' von' package.loaded' und als globale Variablen verfügbar. In WoW gibt es nur die globalen Variablen, also müssen wir 'package.loaded' selbst füllen. – siffiejoe

2

WoW-Umgebung hat keine dofile oder andere Mittel, um überhaupt externe Dateien zu lesen. Sie müssen explizit alle Dateien angeben, die in .toc Datei geladen werden müssen oder .xml referenziert von .toc.

Anschließend können Sie Ihre eigene Implementierung von require schreiben Kompatibilität mit Ihrer Bibliothek zu erhalten, die ziemlich trivial sein würde, wie es nur Modulnamen benötigen würde analysieren und abrufen es aus modules.loaded Tabelleninhalt ist, aber Sie müssen noch ändern Originalquelle, um Dateien in dieser Tabelle zu registrieren, und Sie müssen alle Dateien manuell in der richtigen Reihenfolge des Ladens arrangieren.

Alternativ können Sie Dateien in separate WoW-Addons neu anordnen und verwenden Sie seine eigenen eingebauten Dependencies/OptionalDeps Einrichtungen oder beliebte LibStub-Framework, um die Ladeauftrag automatisch zu behandeln.

+0

Also, die 'modules.loaded' Tabelle ist verfügbar? Weil die 'package. * '-Tabellen fehlen (AFAIK - wird von' require' im "Standard" lua verwendet). – cajwine

+0

Nein, ist es nicht. Aber es ist nur ein normaler Tisch. Es ist nur eine Konvention von "erfordern" Rahmen, um es zu verwenden. Sie können es selbst machen und füllen. –

+0

Hat WoW-Umgebung 'loadstring'? –