mlib icon indicating copy to clipboard operation
mlib copied to clipboard

Adding utility classes/objects like Vector and Point

Open camchenry opened this issue 9 years ago • 15 comments

I came here by way of the post about Hacktober on love2d forums. I have never used this library before, but it looks quite interesting. You said you were thinking about adding vectors, so I am making this issue to start some discussion on if/how they should be implemented.

camchenry avatar Oct 07 '15 03:10 camchenry

Great! Thanks for the interest!

If objects are used, I think they would have to be accepted as arguments by all functions. There might be some conflict of when when you're passing objects vs when you're passing variables to the function, which may cause some trouble.

My idea is that there would be a simple Lua class that creates all these objects. Something like:

local function isObject( obj ) 
    return obj.__type and obj.__isMlibObject
end

local function typeOfObject( obc, expected )
    return obj.__type == expected
end

local classes = {
    point = function( x, y ) -- Name of class = func (creation function )
        -- You could also add type checking here, etc.
        return { 
            x = x, y = y, __type = 'point', __isMlibObject = true, 
            checkCircle = function( self, ... )
                local input = checkInput( ... )
                local x, y, radius
                if #input == 1 and isObject( input ) and typeOfObject( input, 'circle' ) then
                    x, y, radius = point.x, point.y, point.radius
                elseif #input == 3 then
                    x, y, radius = unpack( input )
                end, 
                return circleCheckPoint( self.x, self.y, x, y, radius )
            end, 
        }
    end, 
    -- segment = function ...
}

local function createClass( type, ... )
    return classes[type]( ... )
end

This isn't tested, but should be a good baseline.

One potential problem with this implementation is that it would use a lot of memory. Another way you could do this (that would use less memory) would be to use metatables to reference back to the table. In other words, each new object doesn't have every single function

davisdude avatar Oct 07 '15 10:10 davisdude

I agree, it seems really clunky to have all of the functions check if the first argument is an object or a number. That code does seem like it would use a lot of memory, but I haven't thoroughly used metatables enough to know if that's a solution. So, I might mess around with that and see if I could get it working.

camchenry avatar Oct 07 '15 18:10 camchenry

Metatables don't use any extra memory. Tables are passed by reference, not copied, so using a single table as the meta table for 1000 other tables only gives you the footprint of 1001 tables, not 2000.

karai17 avatar Oct 09 '15 03:10 karai17

Metatables definitely seem like the way to go. What I was doing (above) doesn't really seem suited for this.

davisdude avatar Oct 09 '15 09:10 davisdude

Looking at #10, should the point code match the vector code? If that's so, the tables should be tagged with some sort of type property. Otherwise, these functions would be identical:

local function isVector(a)
    return type(a.x) == "number" and type(a.y) == "number"
end

local function isPoint(p)
    return type(p.x) == "number" and type(p.y) == "number"
end

camchenry avatar Oct 10 '15 16:10 camchenry

What exactly do you mean by point? A vector can easily be described as a point already.

karai17 avatar Oct 10 '15 16:10 karai17

Fair enough, that's sort of what I was thinking anyway. Unless there are other specific objects that should be added I think this issue can be closed.

camchenry avatar Oct 10 '15 16:10 camchenry

Well, the current vector implementation isn't really an object, so it's actually going more for "duck typing" on that one.

davisdude avatar Oct 10 '15 16:10 davisdude

Depending on the scope of this library, there are lots of potential objects that could be added such as matrices of varying sizes, vec3s, etc. mlib has a very different structure to it than my own math library, CPML, which contains many of the same features and isolates modules in a very intuitive and friendly way.

karai17 avatar Oct 10 '15 16:10 karai17

Yeah, due to the way I implemented some functions it was impossible to make it so that files were separated (i.e polygon.lua, etc.) without some weirdness occurring.

davisdude avatar Oct 10 '15 16:10 davisdude

Well you don't necessarily need to separate files the same way that we do. It is helpful, though, since our library references other modules within, but one large file can do the same thing.

Requiring cpml gives you a table with access to all modules, but you can require only the modules you need instead

local cpml = require "cpml"
local vector = cpml.vec3(0, 0, 0)
local vec3 = require "cpml.modules.vec3"
local vector = vec3(0, 0, 0)

karai17 avatar Oct 10 '15 16:10 karai17

God dammit GitHub.

local cpml = require "cpml"
local vector = cpml.vec3(0, 0, 0)
local vec3 = require "cpml.modules.vec3"
local vector = vec3(0, 0, 0)

karai17 avatar Oct 10 '15 16:10 karai17

I think it needs to be Lua, not lua

davisdude avatar Oct 10 '15 16:10 davisdude

Nah, it's an issue with email responses.

karai17 avatar Oct 10 '15 16:10 karai17

Oh, okay.

davisdude avatar Oct 10 '15 16:10 davisdude