• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Get Handle Type

I'm using this as a dependency in my resources, but it might have some uses on its own, so I might as well upload it separately. Thanks to Wrda for telling me about the non-hashtable approach in Lua used by Eikonium in his DebugUtils library.

Returns the exact type of a handle, such as "unit", "player", or "abilitybooleanlevelarrayfield". You can add additional functions for specific types, such as "IsItem" from the IsUnit template.

I believe this is the most optimized implementation, although for IsHandle, you could just use type(var) == "userdata". IsHandle looks nicer though :prazz:. And you compute the handle type in one go.

Note: IsUnit overwrites the native with the same name. Since that is arguably the most useless native there is, I think that shouldn't be a problem.

Lua:
if Debug then Debug.beginFile("HandleType") end
do
    --[[
    ===============================================================================================================================================================
                                                                        Handle Type
                                                                        by Antares
    ===============================================================================================================================================================
    
    Determine the type of a Wacraft 3 object (handle). The result is stored in a table on the first execution to increase performance.

    HandleType[whichHandle]     -> string           Returns an empty string if variable is not a handle.
    IsHandle[whichHandle]       -> boolean
    IsWidget[whichHandle]       -> boolean
    IsUnit[whichHandle]         -> boolean

    These can also be called as a function, which has a nil-check, but is slower than the table-lookup

    ===============================================================================================================================================================
    ]]

    local widgetTypes = {
        unit = true,
        destructable = true,
        item = true
    }

    HandleType = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            if type(key) == "userdata" then
                local str = tostring(key)
                self[key] = str:sub(1, (str:find(":", nil, true) or 0) - 1)
                return self[key]
            else
                self[key] = ""
                return ""
            end
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return ""
            end
        end
    })

    IsHandle = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = HandleType[key] ~= ""
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })

    IsWidget = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = widgetTypes[HandleType[key]] == true
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })

    IsUnit = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = HandleType[key] == "unit"
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })
end
if Debug then Debug.endFile() end
Contents

Get Handle Type (Binary)

Reviews
Wrda
Works as expected, useful for debugging and for conditional code. OnInit.global("HandleType", function() end) What's up with this line at the bottom? It seems either something leftover or you wanted to make a library out of it. Nonetheless, Approved
I always like to see this kind of stuff. Eikonium's DebugUtils has a nice WarCraft3Type Lua function, which covers the functional utility of a resource like this. But it is a cool idea.
Yea, I got the string approach from the DebugUtils library. I just added the caching part and the IsWidget etc. specific functions.
 

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
1,993
There's several ways, usually from what I understand can be like this:
You have a scope of do .... end engulf everything you want to initialize into a local function, and then use OnInit at the end, with that function as 2nd parameter.
Lua:
if Debug then Debug.beginFile("HandleType") end
    --[[
    ===============================================================================================================================================================
                                                                        Handle Type
                                                                        by Antares
    ===============================================================================================================================================================
    
    Determine the type of a Wacraft 3 object (handle). The result is stored in a table on the first execution to increase performance.
    HandleType[whichHandle]     -> string           Returns an empty string if variable is not a handle.
    IsHandle[whichHandle]       -> boolean
    IsWidget[whichHandle]       -> boolean
    IsUnit[whichHandle]         -> boolean
    These can also be called as a function, which has a nil-check, but is slower than the table-lookup
    ===============================================================================================================================================================
    ]]
do
    local function init()
        local widgetTypes = {
            unit = true,
            destructable = true,
            item = true
        }
        HandleType = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                if type(key) == "userdata" then
                    local str = tostring(key)
                    self[key] = str:sub(1, (str:find(":", nil, true) or 0) - 1)
                    return self[key]
                else
                    self[key] = ""
                    return ""
                end
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return ""
                end
            end
        })
        IsHandle = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = HandleType[key] ~= ""
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })
        IsWidget = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = widgetTypes[HandleType[key]] == true
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })
        IsUnit = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = HandleType[key] == "unit"
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })
    end
    OnInit.global("HandleType", init)
end
if Debug then Debug.endFile() end

This one has no do ... end scope, but the rest is similar
Lua:
if Debug then Debug.beginFile("HandleType") end
    --[[
    ===============================================================================================================================================================
                                                                        Handle Type
                                                                        by Antares
    ===============================================================================================================================================================
    
    Determine the type of a Wacraft 3 object (handle). The result is stored in a table on the first execution to increase performance.

    HandleType[whichHandle]     -> string           Returns an empty string if variable is not a handle.
    IsHandle[whichHandle]       -> boolean
    IsWidget[whichHandle]       -> boolean
    IsUnit[whichHandle]         -> boolean

    These can also be called as a function, which has a nil-check, but is slower than the table-lookup

    ===============================================================================================================================================================
    ]]
    function HandleTypesInit()
        local widgetTypes = {
            unit = true,
            destructable = true,
            item = true
        }

        HandleType = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                if type(key) == "userdata" then
                    local str = tostring(key)
                    self[key] = str:sub(1, (str:find(":", nil, true) or 0) - 1)
                    return self[key]
                else
                    self[key] = ""
                    return ""
                end
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return ""
                end
            end
        })

        IsHandle = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = HandleType[key] ~= ""
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })

        IsWidget = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = widgetTypes[HandleType[key]] == true
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })

        IsUnit = setmetatable({}, {
            __mode = "k",
            __index = function(self, key)
                self[key] = HandleType[key] == "unit"
                return self[key]
            end,
            __call = function(self, key)
                if key then
                    return self[key]
                else
                    return false
                end
            end
        })
    end
    OnInit.global("HandleType", HandleTypesInit)
if Debug then Debug.endFile() end

3rd method involves you engulfing everything inside your OnInit function call, with an anonymous function
Lua:
if Debug then Debug.beginFile("HandleType") end
    --[[
    ===============================================================================================================================================================
                                                                        Handle Type
                                                                        by Antares
    ===============================================================================================================================================================
    
    Determine the type of a Wacraft 3 object (handle). The result is stored in a table on the first execution to increase performance.

    HandleType[whichHandle]     -> string           Returns an empty string if variable is not a handle.
    IsHandle[whichHandle]       -> boolean
    IsWidget[whichHandle]       -> boolean
    IsUnit[whichHandle]         -> boolean

    These can also be called as a function, which has a nil-check, but is slower than the table-lookup

    ===============================================================================================================================================================
    ]]
OnInit.global("HandleType", function()
    local widgetTypes = {
        unit = true,
        destructable = true,
        item = true
    }

    HandleType = setmetatable({}, {
         __mode = "k",
        __index = function(self, key)
            if type(key) == "userdata" then
                local str = tostring(key)
                self[key] = str:sub(1, (str:find(":", nil, true) or 0) - 1)
                return self[key]
            else
                self[key] = ""
                return ""
            end
        end,
         __call = function(self, key)
            if key then
                return self[key]
            else
                return ""
            end
        end
    })

    IsHandle = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = HandleType[key] ~= ""
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })

    IsWidget = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = widgetTypes[HandleType[key]] == true
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })

    IsUnit = setmetatable({}, {
        __mode = "k",
        __index = function(self, key)
            self[key] = HandleType[key] == "unit"
            return self[key]
        end,
        __call = function(self, key)
            if key then
                return self[key]
            else
                return false
            end
        end
    })
end)
if Debug then Debug.endFile() end

Also, I realised you forgot to put if Debug then Debug.endFile() end at the end of the script :D so Debug Utils wouldn't behave very well.
 
Top