Pascal plugins for the mobile engine
This implementation is split across two packages:
packages/nexus-packages/luaprovides the generic Lua 5.1 ABI and RTTI bridge.packages/nexus-packages/solar2dprovides the Solar2D integration and depends on the Lua package.
The bridge separates generic Lua integration from Solar2D-specific integration:
TLuaPlugin
|
TSolarPlugin
|
TUserPlugin
A user plugin can remain ordinary Pascal:
type
TAddLink = function(A, B: Integer): Integer of object;
TSamplePlugin = class(TSolarPlugin)
private
FAdd: TAddLink;
FName: string;
function LinkAdd(A, B: Integer): Integer;
published
property Add: TAddLink read FAdd;
property Name: string read FName write FName;
end;
Read-only published method-pointer properties are Lua links. Writable published method-pointer properties remain ordinary Pascal events and are not exposed by the Lua bridge. Direct published methods are not part of the bridge contract.
Lua sees an object-like surface:
local sample = require("plugin.sample")
local obj = sample.new()
obj.Name = "Nexus"
print(obj:Add(20, 22))
Event surface
The Solar2D layer adds familiar local event methods:
obj:addEventListener("pulse", onPulse)
obj:removeEventListener("pulse", onPulse)
obj:dispatchEvent({ name = "setVolume", value = 0.25 })
Pascal descendants can receive Lua events by overriding HandleEvent() and can send local or global events with DispatchEvent() and DispatchRuntimeEvent().
See Sample.Plugin.pas and main.lua for the complete small example.
Runtime boundary
The bridge uses Lua 5.1; the separate Lua 5.5 binding does not change this ABI. The final plugin link resolves Lua 5.1 and Solar2D Native exports. Published-link invocation also needs native libffi on targets other than x86-64 Windows. Select the matching target libraries through the project's dependencies.
CoronaLuaDispatchRuntimeEvent(L, nresults) consumes the event table on top of
the stack. It is the active API; CoronaLuaRuntimeDispatchEvent(L, index) is the
deprecated helper. Lua/Solar2D calls belong on the engine's Lua thread.
Current limitations
- A listener retained through
CoronaLuaRefcan capture its owning plugin userdata and create a cross-runtime ownership cycle. Remove local listeners explicitly when their lifetime ends. - The fixed
Nexus.Lua.Plugin.Objectmetatable is shared within a Lua state. Independently built plugin binaries embedding separate bridge copies can collide and reuse callback addresses from another binary. - Lua 5.1 numbers are doubles; not every Pascal
Int64/QWordvalue is exactly representable. Input conversion uses a signed intermediate and pointer-sizedlua_Integer. Narrower ordinal and numeric-enumeration input lacks explicit domain validation. Restrict inputs to the representable, valid domain of the published type.
Build the example
From the Nexus source checkout, with the target's engine libraries available:
nxbuild /action=build /project=../nexus-lab/examples/mobile/pascal-plugin/plugin_sample.nxproject
The sample exports luaopen_plugin_sample; run its main.lua through the
matching engine to exercise properties, links and events. Test each supported
CPU/ABI with its matching libraries; a host build does not verify phone execution.