2016-04-26 2 views
4

Dans l'environnement lua intégré (World of Warcraft - WoW) il manque la fonction require.Lua émulant la fonction require

Je veux le port d'un code source existant (an great OO-library) pour l'utiliser dans le WoW. La bibliothèque elle-même est relativement petite (environ 8 petits fichiers) mais bien sûr, elle utilise beaucoup le require.

World of Warcraft charges des fichiers et des bibliothèques en définissant dans un fichier XML, comme:

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

mais je ne sais pas comment la manipulation bibliothèque de bas niveau se fait dans le WoW.

AFAIK dans le WoW est manquant même la table package. aussi. :(

La question (s):. Pour moi, la façon simplifiée serait écrire une fonction qui émuler la fonction require en utilisant l'interface disponible dans WoW La question est de savoir comment quelqu'un pourrait-il me donner quelques directions

.?

Ou comme solution de rechange, pour le portage de la source existante mentionnée à WoW, je dois remplacer les require Some.Other.Module lignes dans les sources lua à quelque chose de ce que WoW comprendra. Qu'est-ce que l'équivalent/remplacement pour un tel require Some.Module dans le WoW?

Comment le WoW gère-t-il les modules/bibliothèques de bas niveau?

Répondre

3

Vous pouvez fusionner tous les fichiers en un en utilisant l'un des divers scripts d'amalgamation, par ex. amalg. Ensuite, vous pouvez charger ce fichier et un talon qui implémente la fonction require en utilisant l'habituel WoW façon:

<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> 

Le fichier RequireStub.lua pourrait ressembler à:

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 

Cela devrait imiter assez de la bibliothèque package à vous obtenez un require de travail qui charge des modules dans le fichier amalgamé. Différents scripts d'amalgamation peuvent avoir besoin de bits différents de package, par conséquent, vous devrez probablement jeter un coup d'œil au code source Lua généré.

Et dans le cas spécifique de Coat, vous devrez peut-être implémenter des stubs pour d'autres fonctions Lua. Par exemple.J'ai vu que Coat utilise la bibliothèque debug ...

+0

Belle explication, merci pour l'exemple de code. – cajwine

+0

Ce code est vraiment difficile à comprendre pour moi. Quel est le but de toutes ces variables à l'intérieur de 'loaded'? Pouvez-vous aller plus dans les détails? – Hatefiend

+0

@Hatefiend: 'package.loaded' met en cache tous les modules chargés/requis. Ceux énumérés ci-dessus sont les modules de la bibliothèque standard de Lua. Dans Lua "normal", ils sont disponibles via 'require' de' package.loaded' et en tant que variables globales. Dans WoW, il n'y a que les variables globales, nous devons donc remplir 'package.loaded'. – siffiejoe

2

WoW environnement n'a pas dofile ou tout autre moyen de lire des fichiers externes du tout. Vous devez mentionner explicitement tous les fichiers qui doivent être chargés dans le fichier .toc ou .xml référencé par .toc.

Vous pouvez ensuite écrire votre propre implémentation de require pour maintenir la compatibilité avec votre bibliothèque, ce qui serait assez trivial car il suffirait d'analyser le nom du module et de récupérer son contenu depuis la table modules.loaded, mais vous devrez toujours modifier source originale pour que les fichiers s'inscrivent dans cette table et vous devez organiser manuellement tous les fichiers dans l'ordre correct du chargement.

Vous pouvez également réorganiser les fichiers dans des add-ons WoW distincts et utiliser ses propres fonctionnalités Dependencies/OptionalDeps intégrées ou le framework LibStub pour gérer automatiquement l'ordre de chargement.

+0

Donc, la table 'modules.loaded' est disponible? Parce que les tables 'package. *' Sont manquantes (AFAIK - il est utilisé par le 'require' dans le lua" standard "). – cajwine

+0

Non, ce n'est pas le cas. Mais c'est juste une table régulière. C'est juste une convention de framework 'require' pour l'utiliser. Vous pouvez le faire et le remplir vous-même. –

+0

Est-ce que l'environnement WoW a 'loadstring'? –