• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

vJass struct imitation in Lua

Status
Not open for further replies.

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
Version 1.0 an onwards can now be found here: [Lua] - vJass-style Struct


This simple library bridges a major gap in understanding of how vJass structs behave versus how Lua works with data. I'm finding myself repeating some of the same code each time I go to create a new resource, which this would help to reduce. I am writing a guide on converting from vJass to Lua, and this resource would save a lot of headache in the demo scripts that I'm writing.

Method operator overloading is definitely possible in Lua, but I don't think it's possible to "de-uglify" that kind of syntax by burying stuff within this library. I was able to do variable overloading successfully with Global Remapper, so I might be able to find a solution eventually.

As of version 0.4, vJass module-like-syntax is now supported.

Example usage of modules being used with static methods:

Code:
    s = Struct()
    m = Struct.module(function(struct)
        function struct.moduleMethod()
            struct.structMethod()
        end
    end)

    m.implement(s)
    
    function s.structMethod()
        print "structmethod"
    end
    
    m.implement(s)
    
    s.moduleMethod()

Core library:

Lua:
do Struct = {} --vJass-style Struct version 0.5.0.0 by Bribe

local mt = {__index = function(_, v) return Struct[v] end}
setmetatable(Struct, mt)
 
---Constructor: Struct([parentStruct])
---@class Struct : table
---@field allocate function
---@field deallocate function
---@field create function
---@field destroy function
---@field onDestroy function
---@field onCreate function
---@field extends function

---Constructor: Struct.module(moduleFunction)
---@class StructModule : table
---@field private init boolean
---@field public implement function

---Allocate is a static function here rather than dynamically-created per-struct.
---@param userStruct Struct
---@return Struct new_instance
local function Allocate(userStruct)
    local newInstance = {}
    setmetatable(newInstance, userStruct)
    if userStruct.onCreate then newInstance:onCreate() end
    return newInstance
end

---Deallocate is a static function here rather than dynamically-created per-struct.
---@param structInstance Struct
local function Deallocate(structInstance)
    if structInstance.onDestroy then structInstance:onDestroy() end
    for key,_ in pairs(structInstance) do structInstance[key] = nil end
end

---Acquire another struct's keys via myStruct.extends(otherStruct)
---@param struct any
---@param parentStruct any
local function Extends(struct, parentStruct)
    for key, val in pairs(parentStruct) do
        if not struct[key] then
            struct[key] = val
        end
    end
end

---Create a new "vJass"-style struct with myStruct = Struct([parentStruct]).
---@param parent? Struct
---@return Struct new_struct
function mt.__call(parent)
    local newStruct = {
        allocate    = Allocate,
        deallocate  = Deallocate,
        create      = Allocate,
        destroy     = Deallocate,
        extends     = Extends,
        super       = parent
    }
    if parent then
        setmetatable(newStruct, {__index = parent})
    else
        newStruct.__index   = newStruct
    end
    return newStruct
end

---Create a new module that can be implemented by any struct.
---@param moduleFunc StructModule
function Struct.module(moduleFunc)
    local module = {}
    module.init = {}
    module.implement = function(struct)
        if not module.init[struct] then
            module.init[struct] = true
            moduleFunc(struct)
        end
    end
    return module
end

end --end of Struct library
 
Last edited:
Status
Not open for further replies.
Top