mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-24 16:07:01 +00:00
Validate arguments in the vector API
This doesn't produce the best error messages (should "self" be argument 0 or 1?), but is better than throwing errors in vector's internals.
This commit is contained in:
parent
0f623c2cca
commit
0c1ab780bb
@ -13,6 +13,11 @@
|
||||
-- @module vector
|
||||
-- @since 1.31
|
||||
|
||||
local getmetatable = getmetatable
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local vmetatable
|
||||
|
||||
--- A 3-dimensional vector, with `x`, `y`, and `z` values.
|
||||
--
|
||||
-- This is suitable for representing both position and directional vectors.
|
||||
@ -27,6 +32,9 @@ local vector = {
|
||||
-- @usage v1:add(v2)
|
||||
-- @usage v1 + v2
|
||||
add = function(self, o)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
if getmetatable(o) ~= vmetatable then expect(2, o, "vector") end
|
||||
|
||||
return vector.new(
|
||||
self.x + o.x,
|
||||
self.y + o.y,
|
||||
@ -42,6 +50,9 @@ local vector = {
|
||||
-- @usage v1:sub(v2)
|
||||
-- @usage v1 - v2
|
||||
sub = function(self, o)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
if getmetatable(o) ~= vmetatable then expect(2, o, "vector") end
|
||||
|
||||
return vector.new(
|
||||
self.x - o.x,
|
||||
self.y - o.y,
|
||||
@ -52,30 +63,36 @@ local vector = {
|
||||
--- Multiplies a vector by a scalar value.
|
||||
--
|
||||
-- @tparam Vector self The vector to multiply.
|
||||
-- @tparam number m The scalar value to multiply with.
|
||||
-- @tparam number factor The scalar value to multiply with.
|
||||
-- @treturn Vector A vector with value `(x * m, y * m, z * m)`.
|
||||
-- @usage v:mul(3)
|
||||
-- @usage v * 3
|
||||
mul = function(self, m)
|
||||
-- @usage vector.new(1, 2, 3):mul(3)
|
||||
-- @usage vector.new(1, 2, 3) * 3
|
||||
mul = function(self, factor)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
expect(2, factor, "number")
|
||||
|
||||
return vector.new(
|
||||
self.x * m,
|
||||
self.y * m,
|
||||
self.z * m
|
||||
self.x * factor,
|
||||
self.y * factor,
|
||||
self.z * factor
|
||||
)
|
||||
end,
|
||||
|
||||
--- Divides a vector by a scalar value.
|
||||
--
|
||||
-- @tparam Vector self The vector to divide.
|
||||
-- @tparam number m The scalar value to divide by.
|
||||
-- @tparam number factor The scalar value to divide by.
|
||||
-- @treturn Vector A vector with value `(x / m, y / m, z / m)`.
|
||||
-- @usage v:div(3)
|
||||
-- @usage v / 3
|
||||
div = function(self, m)
|
||||
-- @usage vector.new(1, 2, 3):div(3)
|
||||
-- @usage vector.new(1, 2, 3) / 3
|
||||
div = function(self, factor)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
expect(2, factor, "number")
|
||||
|
||||
return vector.new(
|
||||
self.x / m,
|
||||
self.y / m,
|
||||
self.z / m
|
||||
self.x / factor,
|
||||
self.y / factor,
|
||||
self.z / factor
|
||||
)
|
||||
end,
|
||||
|
||||
@ -83,8 +100,9 @@ local vector = {
|
||||
--
|
||||
-- @tparam Vector self The vector to negate.
|
||||
-- @treturn Vector The negated vector.
|
||||
-- @usage -v
|
||||
-- @usage -vector.new(1, 2, 3)
|
||||
unm = function(self)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
return vector.new(
|
||||
-self.x,
|
||||
-self.y,
|
||||
@ -99,6 +117,9 @@ local vector = {
|
||||
-- @treturn Vector The dot product of `self` and `o`.
|
||||
-- @usage v1:dot(v2)
|
||||
dot = function(self, o)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
if getmetatable(o) ~= vmetatable then expect(2, o, "vector") end
|
||||
|
||||
return self.x * o.x + self.y * o.y + self.z * o.z
|
||||
end,
|
||||
|
||||
@ -109,6 +130,9 @@ local vector = {
|
||||
-- @treturn Vector The cross product of `self` and `o`.
|
||||
-- @usage v1:cross(v2)
|
||||
cross = function(self, o)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
if getmetatable(o) ~= vmetatable then expect(2, o, "vector") end
|
||||
|
||||
return vector.new(
|
||||
self.y * o.z - self.z * o.y,
|
||||
self.z * o.x - self.x * o.z,
|
||||
@ -120,6 +144,7 @@ local vector = {
|
||||
-- @tparam Vector self This vector.
|
||||
-- @treturn number The length of this vector.
|
||||
length = function(self)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
|
||||
end,
|
||||
|
||||
@ -141,6 +166,9 @@ local vector = {
|
||||
-- nearest 0.5.
|
||||
-- @treturn Vector The rounded vector.
|
||||
round = function(self, tolerance)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
expect(2, tolerance, "number", "nil")
|
||||
|
||||
tolerance = tolerance or 1.0
|
||||
return vector.new(
|
||||
math.floor((self.x + tolerance * 0.5) / tolerance) * tolerance,
|
||||
@ -156,6 +184,8 @@ local vector = {
|
||||
-- @usage v:tostring()
|
||||
-- @usage tostring(v)
|
||||
tostring = function(self)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
|
||||
return self.x .. "," .. self.y .. "," .. self.z
|
||||
end,
|
||||
|
||||
@ -165,11 +195,15 @@ local vector = {
|
||||
-- @tparam Vector other The second vector to compare to.
|
||||
-- @treturn boolean Whether or not the vectors are equal.
|
||||
equals = function(self, other)
|
||||
if getmetatable(self) ~= vmetatable then expect(1, self, "vector") end
|
||||
if getmetatable(other) ~= vmetatable then expect(2, other, "vector") end
|
||||
|
||||
return self.x == other.x and self.y == other.y and self.z == other.z
|
||||
end,
|
||||
}
|
||||
|
||||
local vmetatable = {
|
||||
vmetatable = {
|
||||
__name = "vector",
|
||||
__index = vector,
|
||||
__add = vector.add,
|
||||
__sub = vector.sub,
|
||||
|
@ -0,0 +1,71 @@
|
||||
-- SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
--
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
describe("The vector library", function()
|
||||
local vec = vector.new(1, 2, 3)
|
||||
|
||||
describe("vector.add", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.add, nil, vec):eq("bad argument #1 (vector expected, got nil)")
|
||||
expect.error(vec.add, vec, nil):eq("bad argument #2 (vector expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(vector.new(1, 2, 3) + vector.new(6, 4, 2)):eq(vector.new(7, 6, 5))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("vector.sub", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.sub, nil, vec):eq("bad argument #1 (vector expected, got nil)")
|
||||
expect.error(vec.sub, vec, nil):eq("bad argument #2 (vector expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(vector.new(6, 4, 2) - vector.new(1, 2, 3)):eq(vector.new(5, 2, -1))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("vector.mul", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.mul, nil, vec):eq("bad argument #1 (vector expected, got nil)")
|
||||
expect.error(vec.mul, vec, nil):eq("bad argument #2 (number expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(vector.new(1, 2, 3) * 2):eq(vector.new(2, 4, 6))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("vector.div", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.div, nil, vec):eq("bad argument #1 (vector expected, got nil)")
|
||||
expect.error(vec.div, vec, nil):eq("bad argument #2 (number expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(vector.new(1, 2, 3) / 2):eq(vector.new(0.5, 1, 1.5))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("vector.unm", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.unm, nil):eq("bad argument #1 (vector expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(-vector.new(2, 3, 6)):eq(vector.new(-2, -3, -6))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("vector.length", function()
|
||||
it("validates arguments", function()
|
||||
expect.error(vec.length, nil):eq("bad argument #1 (vector expected, got nil)")
|
||||
end)
|
||||
|
||||
it("returns the correct value", function()
|
||||
expect(vector.new(2, 3, 6):length()):eq(7)
|
||||
end)
|
||||
end)
|
||||
end)
|
Loading…
Reference in New Issue
Block a user