Skip to content

Instantly share code, notes, and snippets.

@DoctorGester
Created October 25, 2019 17:46
Show Gist options
  • Save DoctorGester/a3f100dd6dfd979a6ee42b027bbf2c69 to your computer and use it in GitHub Desktop.
Save DoctorGester/a3f100dd6dfd979a6ee42b027bbf2c69 to your computer and use it in GitHub Desktop.
local ffi = require "ffi"
ffi.cdef [[
void* malloc(size_t size);
typedef struct {
float x;
float y;
} vector;
]]
local storage_size = 1024 * 1024
local storage = ffi.new("vector[?]", storage_size)
local storage_pointer = 0
function vector(x, y)
if storage_pointer >= storage_size then
storage_pointer = storage_pointer + 1
return ffi.new("vector", x or 0, y or 0)
end
local v = storage[storage_pointer]
storage_pointer = storage_pointer + 1
v.x = x or 0
v.y = y or 0
return v
end
function get_storage_watermark()
return storage_pointer
end
function reset_vector_storage()
if storage_pointer >= storage_size then
print("WARNING: Storage size of", storage_size, "issued", storage_pointer - storage_size + 1, "extra elements")
end
storage_pointer = 0
end
local vector_meta = {
__add = function(v1, v2)
return vector(v1.x + v2.x, v1.y + v2.y)
end,
__sub = function(v1, v2)
return vector(v1.x - v2.x, v1.y - v2.y)
end,
__mul = function(v1, v2)
if type(v1) == "number" then -- v2 is a vector
return vector(v1 * v2.x, v1 * v2.y)
elseif type(v2) == "number" then -- v1 is a vector
return vector(v1.x * v2, v1.y * v2)
end
return vector(v1.x * v2.x, v1.y * v2.y)
end,
__div = function(v1, v2)
if type(v1) == "number" then -- v2 is a vector
return vector(v1 / v2.x, v1 / v2.y)
elseif type(v2) == "number" then -- v1 is a vector
return vector(v1.x / v2, v1.y / v2)
end
return vector(v1.x / v2.x, v1.y / v2.y)
end,
__eq = function(v1, v2)
if v2 == nil then return false end
return v1.x == v2.x and v1.y == v2.y
end,
__unm = function(v)
return vector(-v.x, -v.y)
end,
__tostring = function(v)
return string.format("(%.2f, %.2f)", v.x, v.y)
end,
__index = {
persist = function(v)
return ffi.new("vector", v.x, v.y)
end,
set = function(target, source, second_value)
if second_value ~= nil then
target.x = source
target.y = second_value
else
target.x = source.x
target.y = source.y
end
end,
length = function(v)
return math.sqrt(v.x * v.x + v.y * v.y)
end,
normalize = function(v)
return v / v:length()
end,
dot = function(a, b)
return a.x * b.x + a.y * b.y
end,
unpack = function(v)
return v.x, v.y
end
}
}
ffi.metatype("vector", vector_meta)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment