How to determine if a value is a LÖVE object?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
chimmihc
Prole
Posts: 15
Joined: Mon Oct 19, 2015 6:32 am

How to determine if a value is a LÖVE object?

Post by chimmihc »

I am creating an API with editable properties and would like to have basic type checking in it.

For regular Lua values this is simple enough but I can't find a way to check if a value is a LÖVE object.

I thought to extract Object:typeOf for this but calling it with non LÖVE objects actually causes the process to crash silently.
User avatar
dusoft
Party member
Posts: 765
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: How to determine if a value is a LÖVE object?

Post by dusoft »

https://www.lua.org/pil/2.html

Usually: "userdata" for LÖVE.

Also:
https://love2d.org/wiki/Types
for detailed type.
qwdqwqwffqw
Prole
Posts: 40
Joined: Sat Jan 25, 2020 4:11 pm

Re: How to determine if a value is a LÖVE object?

Post by qwdqwqwffqw »

If the result of type(value) is 'userdata', then using tostring() might help? - You can check first part of returned string, probably without crashing.

Or, maybe you can use getmetatable() and compare it with metatables of love Objects.

Code: Select all

local loveTypes = {
	[getmetatable(love.graphics.newImage('img.png'))] = true,
	... -- [metatable of love Object] = true
}

function isLove(v)
	return loveTypes[getmetatable(v)]
end
chimmihc
Prole
Posts: 15
Joined: Mon Oct 19, 2015 6:32 am

Re: How to determine if a value is a LÖVE object?

Post by chimmihc »

After a bit of testing it does seem objects of a type share the same metatable so that works.
User avatar
zorg
Party member
Posts: 3477
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to determine if a value is a LÖVE object?

Post by zorg »

chimmihc wrote: Thu Mar 06, 2025 9:26 pm I am creating an API with editable properties and would like to have basic type checking in it.
For regular Lua values this is simple enough but I can't find a way to check if a value is a LÖVE object.
I thought to extract Object:typeOf for this but calling it with non LÖVE objects actually causes the process to crash silently.

Code: Select all

function isLoveObjectType(x, t)
    assert(type(t) = 'string', "Second parameter needs to be a string that's a valid Löve Type.")
    local t = t or 'Object' -- If no specific type is given, default to Object.
    if not x then return false end
    if not type(x) == 'userdata' then return false end
    if not x.typeOf then return false end
    if not type(x.typeOf) == 'function' then return false end
    return x:typeOf(t)
end
This might be the safest implementation, uses typeOf, and can be used to test for specific subtypes as well. :3
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
pgimeno
Party member
Posts: 3709
Joined: Sun Oct 18, 2015 2:58 pm

Re: How to determine if a value is a LÖVE object?

Post by pgimeno »

I was thinking something not too different from what zorg has posted. zorg's code has some bugs and some redundancy, though.

- The first two lines should be swapped, otherwise you would always need to pass a string as the second parameter and the second line would be redundant.
- The line `if not x then return false end` is redundant: the next line will return type `nil` and bail out.
- The line `if not x.typeOf then return false end` is redundant for the same reason.
- `not a == b` negates a, not the result of the comparison. Instead of adding `not`, the `==` can be replaced with `~=`.
- I'm not sure if any userdata object can be accessed like a table even if it doesn't have a metatable, but ISTR that it can't, meaning that code would crash in that case.

This was my approach:

Code: Select all

local function isLoveObject(obj)
  if type(obj) == "userdata" then
    local mt = debug.getmetatable(obj)
    if type(mt) == "table" then
      for k, v in pairs(debug.getregistry()) do
        if v == mt and type(v.type) == "function" then
          return true  -- or you could return obj:type() instead to know the exact type
        end
      end
    end
  end
  return false
end
It's not very fast though, because of the loop, and it breaks compilation due to the use of pairs().
Post Reply

Who is online

Users browsing this forum: Amazon [Bot] and 2 guests