Commit Graph

308 Commits

Author SHA1 Message Date
Max Cahill
b6ca4c7740
Merge pull request #53 from idbrii/fix-async-lovejs
async: Skip wrapping with xpcall under lovejs
2022-03-07 10:50:36 +11:00
Max Cahill
840f4ba703
Merge pull request #54 from idbrii/capture-w-func
async: Use function to capture ...
2022-03-07 10:49:01 +11:00
Max Cahill
461c3a8131
Merge pull request #52 from idbrii/table-deep-test
tablex: Add deep & shallow for copy, overlay; remove redundant recursion; add tests
2022-03-07 10:27:35 +11:00
Max Cahill
4b0e0c7ec7
Merge pull request #51 from idbrii/lint
Add luacheck and fix bugs it found
2022-03-07 10:14:08 +11:00
David Briscoe
a030a20985 async: Assert that args is a table; add type_or_nil
If args is valid, assert it's a table.

Provides a clear and immediate error message when you convert
add_timeout() to call().

Also add type_or_nil. Very useful for optional parameters like this one.
Seems clearer than checking the arg first:
    if args then assert:type() end
2022-03-06 00:25:24 -08:00
David Briscoe
98f3630c07 async: Skip wrapping with xpcall under lovejs
See Davidobot/love.js#54.

lovejs crashes love with "attempt to yield across metamethod/C-call
boundary" when you try to yield in a coroutine, so we skip wrapping.

We lose the coroutine-local callstack, but at least it works.

Here's my repro:

    local color = {
        purple = {0.25, 0.09, 0.28, 1},
        white = {0.89, 0.91, 0.90, 1},
    }
    local ball = {
        x = 100,
        y = 100,
        r = 20,
    }
    local S = {}
    local input = {
        vanilla = 'v',
        async = 'c',
        quit = 'escape',
    }

    function love.load()
        S.coro = async()
    end

    local function coro_fn()
        S.async_running = true
        for i=1,100 do
            color.purple[4] = i / 100
            coroutine.yield()
        end
        color.purple[4] = 1
        S.async_running = false
        return true
    end

    function love.update(dt)
        S.coro:update(dt)

        if S.vanilla then
            local success, result = coroutine.resume(S.vanilla)
            if result then
                print("coroutine cleared")
                S.vanilla = nil
            end
        end

        if not S.async_running then
            if love.keyboard.isDown(input.vanilla) then
                S.vanilla = coroutine.create(coro_fn)
                print("raw coroutine started")

            elseif love.keyboard.isDown(input.async) then
                print("Starting async call coroutine from update")
                S.coro:call(coro_fn)

            elseif love.keyboard.isDown(input.quit) then
                love.event.quit()
            end
        end
    end

    function love.draw()
        love.graphics.setColor(color.purple)
        love.graphics.circle("fill", ball.x, ball.y, ball.r)

        love.graphics.setColor(color.white)
        local str = "To start a coroutine:"
        for key,val in pairs(input) do
            str = ("%s\n%s: %s"):format(str, key, val)
        end
        love.graphics.printf(str, 5,5, 200, "left")
    end
2022-03-05 23:44:08 -08:00
David Briscoe
d48d4b0e81 table: Rewrite *_copy to copy any kind of type
Allowing shallow_copy/deep_copy to accept any type makes it easier to
write generic code where you just want to copy some input without
knowing anything about it. Like an event system, save system, etc.

Add corresponding test.

Tests pass
2022-03-03 22:03:12 -08:00
David Briscoe
0c193d7901 lint: Don't assign values that will never be used
No bugs here, but giving an initial value can hide cases where we fail
to set a value. Use an assert instead so we can see errors if we change
and break this code.

Except break_next which goes out of scope after it's assigned (I guess
it used to be outside the loop).
2022-03-03 10:17:35 -08:00
David Briscoe
5118cc42bb lint: Fix mismatched arguments in circle_aabb
Fix bug where circle_aabb_overlap wouldn't have the same results as
aabb_circle_overlap.

b_hs was unused, but the function we call expects a_hs as the first
argument. Looks like this circle_aabb_overlap is just flipping
the arguments to aabb_circle_overlap (and for circle_aabb_collide), so
it should match arguments.

Not sure what hs means. Box size?
2022-03-03 10:17:35 -08:00
David Briscoe
d6af9f74c5 lint: Don't set unused locals
Not a bug, but pointless to store this variable since it's not used.
2022-03-03 10:17:35 -08:00
David Briscoe
9083ee74ca lint: Fix accessing undefined append_inplace
Fix crash when using append_inplace without batteries:export().

If you don't export batteries into the global namespace to stomp table,
then append_inplace would access a nil function because it's using table
instead of tablex.

We still use table inside init, but that's after we export to global
namespace.
2022-03-03 10:17:35 -08:00
David Briscoe
a5ebc1e501 lint: Fix shadow issues
Fix shadowing by using variables with a different name or _.

I don't think any of these warnings were actual bugs and fixed them to
maintain the same behaviour.
2022-03-03 10:17:34 -08:00
David Briscoe
8d41c6d3d1 lint: Fix whitespace issues
Remove excess whitespace and remove related ignores.
2022-03-03 10:17:34 -08:00
David Briscoe
66cb419db8 build: Add action for running luacheck
Run luacheck on CI to catch subtle errors.

Add a luacheckrc that ensures current code issues no warnings. We should
eventually try to remove many of these ignores.
2022-03-03 10:17:34 -08:00
David Briscoe
66a6c5a50e Add comments for things that surprised me
As a new user, there were things I was skeptical about and after digging
in, these were my conclusions.

Compared to the simple and obvious lua wiki solutions, batteries' string
functions are slightly faster. GC is the same.

Test
    local str = "hello world"
    local fn = function()
        local x = 0
        if stringx.ends_with(str, "h") then
            x = x + 1
        end
        if stringx.ends_with(str, "helll") then
            x = x + 1
        end
        if stringx.ends_with(str, "helicopter") then
            x = x + 1
        end
    end
    local pretty = require "inspect"
    print("stringx =", pretty({
                time_taken = {measure.time_taken(fn, 10000)},
                memory_taken = {measure.memory_taken(fn, 10000)}
        }))
    local function starts_with(str, prefix)
        return str:find(prefix, 1, true) == 1
    end
    local function ends_with(str, ending)
        return ending == "" or str:sub(-#ending) == ending
    end
    local fn = function()
        local x = 0
        if ends_with(str, "h") then
            x = x + 1
        end
        if ends_with(str, "helll") then
            x = x + 1
        end
        if ends_with(str, "helicopter") then
            x = x + 1
        end
    end
    print("find =", pretty({
                time_taken = {measure.time_taken(fn, 10000)},
                memory_taken = {measure.memory_taken(fn, 10000)}
        }))

starts_with
===========

stringx =       {
  memory_taken = { 0, 0, 0 },
  time_taken = { 1.5098012518138e-007, 9.988434612751e-008, 2.1699932403862e-005 }
}
find =  {
  memory_taken = { 0, 0, 0 },
  time_taken = { 2.7349997544661e-007, 1.9988510757685e-007, 9.1999536380172e-006 }
}

ends_with
=========

stringx =       {
  memory_taken = { 0, 0, 0 },
  time_taken = { 9.0479978825897e-008, 0, 2.5199959054589e-005 }
}
find =  {
  memory_taken = { 0, 0, 0 },
  time_taken = { 2.1833006758243e-007, 1.9988510757685e-007, 6.1000464484096e-006 }
}
2022-03-03 10:17:34 -08:00
David Briscoe
c038546ae1 build: Add github action for running tests
Run tests on CI so they're useful for catching errors in PRs.
2022-03-03 10:04:28 -08:00
David Briscoe
5fa80ca97c tablex: Add deep & shallow for copy, overlay
Replace copy with shallow_copy, deep_copy.
Replace overlay with shallow_overlay, deep_overlay.

Significant rewrite of these functions and their semantics to update to
the note above them.

Add corresponding tests.
2022-03-03 10:04:28 -08:00
David Briscoe
5b4d1c16c5 tablex: Skip equality comparison in equal fn
The second loop doesn't care if the values are equal. It only checks if
the keys are there. The first loop already checked for equality.

Add tests to prove correctness using testy.lua.
2022-03-03 10:04:28 -08:00
David Briscoe
585ba82e57 async: Use function to capture ...
Instead of only capturing 8 temps, pass resume to a function so we can
capture all returned values as ...

I might be missing a reason why you wouldn't do it like this.

Test
    -- coro is an async() updated in love.update
    coro:call(
        function()
            coro.wait(1)

            print("jump")
            self.gravity.y = -900
            coro.wait(1)

            print("fall")
            self.gravity.y = 900
            coroutine.yield "hello"

            return "done"
        end,
        nil,
        function(...)
            print("complete", ...)
        end)
2022-03-03 00:08:19 -08:00
Max Cahill
f6a18380d4
Merge pull request #50 from Sheepolution/patch-3
Return table in foreach for chaining
2022-03-01 13:02:27 +11:00
Sheepolution
f36946ace4
Add comment to foreach regarding new behaviour 2022-03-01 03:01:39 +01:00
Sheepolution
3c6aaf1a76
Return table in foreach for chaining 2022-03-01 02:03:33 +01:00
Max Cahill
0fdddab5b9
Merge pull request #49 from Sheepolution/patch-2
Don't have inplace methods return a new sequence
2022-02-24 11:05:22 +11:00
Sheepolution
6df4b4bddd
Don't have inplace methods return a new sequence 2022-02-22 05:01:27 +01:00
Max Cahill
8fd402b125 Merge #48 - functional.splat 2022-01-25 10:23:07 +11:00
Max Cahill
aec62d92ec moved functional.splat below functional.map_inplace, reformatted a little 2022-01-25 10:22:28 +11:00
Jeremy S. Postelnek
fd998c8525
Update functional.lua 2022-01-24 16:40:46 -05:00
Jeremy S. Postelnek
a9b699afdd
Update functional.lua 2022-01-24 16:27:49 -05:00
Jeremy S. Postelnek
120c9658fc
Update functional.lua 2022-01-23 13:20:02 -05:00
Max Cahill
c0847e1955 fixed intersect.bounce_off bouncing if the velocity was already going away from the normal 2022-01-20 17:37:40 +11:00
Max Cahill
658c8e7117 fixed mathx.ease_inout 2022-01-18 13:15:54 +11:00
Max Cahill
0be82a31df fixed sequence missing a few functional methods 2022-01-17 17:05:59 +11:00
Max Cahill
18347e0b72
Merge pull request #47 from TurtleP/TurtleP/stringx_max_split
[Enhancement]: add optional `max_split` to `stringx.split`
2021-12-31 08:44:35 +11:00
TurtleP
2ef834d538 max_split -> limit, allow zero limit 2021-12-26 11:32:43 -05:00
Jeremy S. Postelnek
e5d00ef3a7
clarify the non-zero *and* positive error 2021-12-24 13:23:37 -05:00
Jeremy S. Postelnek
b01ba8e506
fix spacing 2021-12-24 13:19:38 -05:00
Jeremy S. Postelnek
23bc392b6e
check for negative max_split value 2021-12-24 13:19:12 -05:00
Jeremy S. Postelnek
660ae8ca52
add max_split to stringx.split 2021-12-24 13:03:36 -05:00
Max Cahill
2d5555400d fixed pretty print depth issues 2021-11-26 16:50:44 +11:00
Max Cahill
e731a167d8 added tablex.shallow_equal and tablex.deep_equal, slow functions for content-based (in)equality of different tables 2021-11-23 11:40:31 +11:00
Max Cahill
72cb14b8ec Merge branch feature/tablex.pick_weighted_random
minor changes to error handling and docs
2021-11-23 10:58:56 +11:00
Max Cahill
f3e299e3c9 fixed pubsub using set but not requiring it (breaks without :export())
fixes #44
2021-11-23 10:45:09 +11:00
Max Cahill
f5eda744b9 clarified declaration of h in colour.rgb_to_hsl
fixes #43
2021-11-23 10:41:09 +11:00
Max Cahill
5df717fe6d used mathx for clamp01 in intersect
fixes #45
2021-11-23 10:25:09 +11:00
Jesse Viikari
a42f1190e0 Modified weighted random pick function
- Now accepts a table from which it will pick the random value from,
  instead of an index
- Changed function name to better reflect the way it now works
2021-11-19 10:03:40 +02:00
Max Cahill
7767802433 chased down more math vs mathx usage (and actually fixed the random_lerp usage) 2021-11-19 15:35:52 +11:00
Max Cahill
4460a94933 mathx.random_lerp calls mathx.lerp instead of math.lerp so it works without exported globals
fixes #41
2021-11-19 15:28:54 +11:00
Max Cahill
6ce0dfa523 fixed wrong inequality :) 2021-11-18 15:18:58 +11:00
Max Cahill
774965a508 added async.wait for waiting for a certain period of time inside an async task 2021-11-18 15:15:48 +11:00
Max Cahill
31bfe92d37 added todo for tablex.weighted_random, removed returning the weight value as multi-return wasn't documented and could break in some circumstances 2021-11-18 10:35:26 +11:00