Framework Agnostic

INFO

Uno script “framework agnostic” funziona su più framework. È la scelta migliore per risorse da distribuire o per progetti che vogliono essere flessibili.

ObiettivoDettagli
Cosa imparerai• Cos’è framework agnostic
• Pattern con bridge/strato di astrazione
• Quando conviene (e quando no)
Prerequisiti• Confronto API (16/02)

1. Perché Framework Agnostic

  • La tua risorsa gira su ESX e QBCore senza riscritture
  • Più installazioni = più utenti
  • Meno lock-in su un framework specifico

2. Come Si Fa: Bridge

Si crea un bridge (strato di astrazione) che espone funzioni comuni, e l’implementazione si sceglie in base al framework rilevato.

-- bridge.lua
Bridge = {}
 
if GetResourceState('es_extended') == 'started' then
    Bridge.GetPlayerMoney = function(source)
        local xPlayer = ESX.GetPlayerFromId(source)
        return xPlayer.getMoney()
    end
elseif GetResourceState('qb-core') == 'started' then
    Bridge.GetPlayerMoney = function(source)
        local Player = QBCore.Functions.GetPlayer(source)
        return Player.Functions.GetMoney('cash')
    end
end

Poi usi solo Bridge.GetPlayerMoney(source) nel resto della risorsa.


3. Rilevare il Framework

-- client + server
local function detectFramework()
    if GetResourceState('es_extended') == 'started' then return 'esx' end
    if GetResourceState('qb-core') == 'started' then return 'qbcore' end
    if GetResourceState('ox_core') == 'started' then return 'ox' end
    return nil  -- standalone
end

4. Bridge Completo (esempio minimo)

-- bridge.lua
local framework = detectFramework()
 
Bridge = {
    framework = framework,
}
 
if framework == 'esx' then
    Bridge.PlayerExists = function(source)
        return ESX.GetPlayerFromId(source) ~= nil
    end
    Bridge.GetMoney = function(source)
        return ESX.GetPlayerFromId(source).getMoney()
    end
    Bridge.AddMoney = function(source, amount)
        ESX.GetPlayerFromId(source).addMoney(amount)
    end
elseif framework == 'qbcore' then
    Bridge.PlayerExists = function(source)
        return QBCore.Functions.GetPlayer(source) ~= nil
    end
    Bridge.GetMoney = function(source)
        return QBCore.Functions.GetPlayer(source).Functions.GetMoney('cash')
    end
    Bridge.AddMoney = function(source, amount)
        QBCore.Functions.GetPlayer(source).Functions.AddMoney('cash', amount)
    end
end

5. Quando NON Conviene

SituazioneMotivo
Risorsa piccola usata solo da teIl bridge aggiunge complessità inutile
Hai bisogno di funzionalità molto specifiche di un frameworkL’astrazione diventa rigida
Framework cambia spesso APIIl bridge va aggiornato comunque

6. Best Practice

  • Esponi solo le funzioni di cui hai davvero bisogno
  • Documenta le funzioni del bridge
  • Testa su almeno 2 framework se distribuisci
  • Se usi ox_lib, molto è già agnostico (lib.notify, lib.callback)

TIP

Prossimo passo: Modulo 17 — Pubblicazione per distribuire risorse.


Torna alla: Indice Generale