mirror of
https://github.com/rayaman/multi.git
synced 2026-09-05 07:27:35 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b5d10cbb6 | ||
|
|
0796788fcb | ||
|
|
ee5e3bde7f | ||
|
|
c86413351c | ||
|
|
4a52cd5e14 | ||
|
|
14beeb686a | ||
|
|
60783fdb16 | ||
|
|
b1a7e61c03 | ||
|
|
9fa0e7c2cb | ||
|
|
ef243f87d4 | ||
|
|
178283e0b4 | ||
|
|
7f35265a8e | ||
|
|
0501f068e4 | ||
|
|
ffd7ac15f6 | ||
|
|
869368af56 | ||
|
|
eeb75490dc | ||
|
|
2fec5b39b8 | ||
|
|
0a92890290 | ||
|
|
40de9a8d22 | ||
|
|
f8265fbb3b | ||
|
|
b995b1c0a7 | ||
|
|
66e922a971 | ||
|
|
92659c7eaf |
@@ -1,25 +0,0 @@
|
|||||||
name: Build & Run tests Love2d
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
runs-on: "ubuntu-latest"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Install love2d
|
|
||||||
run: |
|
|
||||||
sudo apt install fuse
|
|
||||||
wget https://github.com/love2d/love/releases/download/11.4/love-11.4-x86_64.AppImage -O love.AppImage
|
|
||||||
sudo chmod +x love.AppImage
|
|
||||||
- name: Run Tests
|
|
||||||
run: |
|
|
||||||
./love.AppImage tests
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Build & Run tests Ubuntu
|
name: Lua Unit Tests (Matrix)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -7,35 +7,26 @@ on:
|
|||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
matrix:
|
||||||
build-type: [Release] # Debug
|
luaVersion: ["5.1", "5.2", "5.3", "5.4"]
|
||||||
lua: ["lua 5.1", "lua 5.2", "lua 5.3", "lua 5.4", "luajit 2.1.0-beta3"]
|
|
||||||
os: ["ubuntu-latest"]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout repository
|
||||||
with:
|
uses: actions/checkout@v4
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- uses: actions/setup-python@v2
|
- name: Setup Lua
|
||||||
with:
|
uses: leafo/gh-actions-lua@v10
|
||||||
python-version: '3.10'
|
with:
|
||||||
|
luaVersion: ${{ matrix.luaVersion }}
|
||||||
|
|
||||||
- name: Setup env
|
- name: Verify Lua version
|
||||||
run: |
|
run: lua -v
|
||||||
pip install hererocks
|
|
||||||
hererocks lua-pkg --${{ matrix.lua }} -rlatest
|
|
||||||
|
|
||||||
- name: Install lanes and multi
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
source ${{github.workspace}}/lua-pkg/bin/activate
|
# Replace with your actual test file
|
||||||
luarocks install lanes
|
lua tests/multi_test.lua
|
||||||
luarocks install rockspecs/multi-16.0-0.rockspec
|
|
||||||
|
|
||||||
- name: Run Tests
|
|
||||||
run: |
|
|
||||||
source ${{github.workspace}}/lua-pkg/bin/activate
|
|
||||||
lua tests/runtests.lua
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# Multi Version: 16.1.0 - The Flow State
|
# Multi Version: 16.3.0 -
|
||||||
**Key Changes**
|
**Key Changes**
|
||||||
- Updated Processors to have more controlled over scheduled processes
|
- Fixed connection multiplying
|
||||||
- Forwarding connections
|
- Optimizing the library
|
||||||
- New Timeout handling
|
- Updated task management support
|
||||||
|
|
||||||
Refer to the [Change Log](https://github.com/rayaman/multi/blob/master/docs/changes.md) for more infromation
|
Refer to the [Change Log](https://github.com/rayaman/multi/blob/master/docs/changes.md) for more infromation
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ My multitasking library for lua. It is a pure lua binding, with exceptions of th
|
|||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
Progress is being made in [v16.1.0](https://github.com/rayaman/multi/tree/v16.1.0)
|
Progress is being made in [v16.3.0](https://github.com/rayaman/multi/tree/v16.3.0)
|
||||||
---
|
---
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
Table of contents
|
Table of contents
|
||||||
---
|
---
|
||||||
|
[Update 16.3.0 - Proper Priorities](#update-1620---proper-priorities)</br>
|
||||||
|
[Update 16.2.0 - TimeStamps and UUIDs](#update-1620---timestamps-and-uuids)</br>
|
||||||
[Update 16.1.0 - The Flow State](#update-1610---the-flow-state)</br>
|
[Update 16.1.0 - The Flow State](#update-1610---the-flow-state)</br>
|
||||||
[Update 16.0.1 - Bug fix](#update-1601---bug-fix)</br>
|
[Update 16.0.1 - Bug fix](#update-1601---bug-fix)</br>
|
||||||
[Update 16.0.0 - Connecting the dots](#update-1600---getting-the-priorities-straight)</br>
|
[Update 16.0.0 - Connecting the dots](#update-1600---getting-the-priorities-straight)</br>
|
||||||
@@ -60,6 +62,43 @@ Table of contents
|
|||||||
[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>
|
[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>
|
||||||
[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
|
[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
|
||||||
|
|
||||||
|
# Update 16.3.0 - Proper Priorities
|
||||||
|
|
||||||
|
Added
|
||||||
|
---
|
||||||
|
- New processor scoped to track connections that exist
|
||||||
|
- Better Destroy logic for connections
|
||||||
|
- Added UPTIME to all objects in the library via the create hook
|
||||||
|
- added `proc:isPaused()` to processors
|
||||||
|
- `multi.setClock(c)` allows you to set the internal clock used by the multi core. For example on linux os.clock doesn't give time elapsed since the program started like it does on windows. This method allows one to swap that out.
|
||||||
|
|
||||||
|
Changed
|
||||||
|
---
|
||||||
|
- `thread.kill(msg)` now accepts a message. If omitted will use default `thread killed!`
|
||||||
|
- Modified multiple locations to not create a function during a thread.hold() and reuse. Only functions containing an upvalue currently have functions being created during hold. This will eventually be fixed
|
||||||
|
- Updated `multi:getStats()` with more information
|
||||||
|
- `multi.forwardConnection()` now returns the link to the source connection so you can do cleanup
|
||||||
|
- When connecting to a connection you can unconnect using ref:Unconnect() it has an internal reference to the root connection
|
||||||
|
- Unnamed threads have a shorter postfix of only 4 random characters
|
||||||
|
|
||||||
|
Fixed
|
||||||
|
---
|
||||||
|
- [Issue](https://github.com/rayaman/multi/issues/77) with concat of connections where conn .. func did not work properly
|
||||||
|
- [Issue](https://github.com/rayaman/multi/issues/67) with connection multiplying
|
||||||
|
|
||||||
|
# Update 16.2.0 - TimeStamps and UUIDs and bugfixes
|
||||||
|
Added
|
||||||
|
---
|
||||||
|
- threadedfunctions, multiobjs and threads contain new method: `GetCreationTimestamp()` With will return a string formated date time using ISO 8601
|
||||||
|
|
||||||
|
Changed
|
||||||
|
---
|
||||||
|
- Internal uuid functions to not use bitwise operators
|
||||||
|
|
||||||
|
Fixed
|
||||||
|
---
|
||||||
|
- [Bitwise operations break lua 5.1/luajit](https://github.com/rayaman/multi/issues/73)
|
||||||
|
|
||||||
# Update 16.1.0 - The Flow State
|
# Update 16.1.0 - The Flow State
|
||||||
Added
|
Added
|
||||||
---
|
---
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -58,16 +58,20 @@ function multi:newSystemThreadedQueue(name)
|
|||||||
GLOBAL[name] = c
|
GLOBAL[name] = c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local peek = function()
|
||||||
|
return c:peek()
|
||||||
|
end
|
||||||
|
|
||||||
|
local pop = function()
|
||||||
|
return c:pop()
|
||||||
|
end
|
||||||
|
|
||||||
function c:Hold(opt)
|
function c:Hold(opt)
|
||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
if opt.peek then
|
if opt.peek then
|
||||||
return thread.hold(function()
|
return thread.hold(peek)
|
||||||
return self:peek()
|
|
||||||
end)
|
|
||||||
else
|
else
|
||||||
return thread.hold(function()
|
return thread.hold(pop)
|
||||||
return self:pop()
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ SOFTWARE.
|
|||||||
]]
|
]]
|
||||||
package.path = "?/init.lua;?.lua;" .. package.path
|
package.path = "?/init.lua;?.lua;" .. package.path
|
||||||
local multi, thread = require("multi"):init()
|
local multi, thread = require("multi"):init()
|
||||||
|
|
||||||
local pseudoProcessor = multi:newProcessor()
|
local pseudoProcessor = multi:newProcessor()
|
||||||
|
|
||||||
if multi.integration then
|
if multi.integration then
|
||||||
return {
|
return {
|
||||||
init = function()
|
init = function()
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package = "multi"
|
||||||
|
version = "16.2-0"
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/rayaman/multi.git",
|
||||||
|
tag = "v16.2.0",
|
||||||
|
}
|
||||||
|
description = {
|
||||||
|
summary = "Lua Multi tasking library",
|
||||||
|
detailed = [[
|
||||||
|
This library contains many methods for multi tasking. Features non coroutine based multi-tasking, coroutine based multi-tasking, and system threading (Requires use of an integration).
|
||||||
|
Check github for documentation.
|
||||||
|
]],
|
||||||
|
homepage = "https://github.com/rayaman/multi",
|
||||||
|
license = "MIT"
|
||||||
|
}
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1"
|
||||||
|
}
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
["multi"] = "init.lua",
|
||||||
|
["multi.integration.lanesManager"] = "integration/lanesManager/init.lua",
|
||||||
|
["multi.integration.lanesManager.extensions"] = "integration/lanesManager/extensions.lua",
|
||||||
|
["multi.integration.lanesManager.threads"] = "integration/lanesManager/threads.lua",
|
||||||
|
["multi.integration.loveManager"] = "integration/loveManager/init.lua",
|
||||||
|
["multi.integration.loveManager.extensions"] = "integration/loveManager/extensions.lua",
|
||||||
|
["multi.integration.loveManager.threads"] = "integration/loveManager/threads.lua",
|
||||||
|
["multi.integration.loveManager.utils"] = "integration/loveManager/threads.lua",
|
||||||
|
--["multi.integration.lovrManager"] = "integration/lovrManager/init.lua",
|
||||||
|
--["multi.integration.lovrManager.extensions"] = "integration/lovrManager/extensions.lua",
|
||||||
|
--["multi.integration.lovrManager.threads"] = "integration/lovrManager/threads.lua",
|
||||||
|
["multi.integration.pseudoManager"] = "integration/pseudoManager/init.lua",
|
||||||
|
["multi.integration.pseudoManager.extensions"] = "integration/pseudoManager/extensions.lua",
|
||||||
|
["multi.integration.pseudoManager.threads"] = "integration/pseudoManager/threads.lua",
|
||||||
|
["multi.integration.luvitManager"] = "integration/luvitManager.lua",
|
||||||
|
["multi.integration.threading"] = "integration/threading.lua",
|
||||||
|
["multi.integration.sharedExtensions"] = "integration/sharedExtensions/init.lua",
|
||||||
|
["multi.integration.priorityManager"] = "integration/priorityManager/init.lua",
|
||||||
|
--["multi.integration.networkManager"] = "integration/networkManager.lua",
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
function love.conf(t)
|
|
||||||
t.identity = nil -- The name of the save directory (string)
|
|
||||||
t.version = "12.0" -- The LOVE version this game was made for (string)
|
|
||||||
t.console = true -- Attach a console (boolean, Windows only)
|
|
||||||
|
|
||||||
t.window.title = "MultiThreadTest" -- The window title (string)
|
|
||||||
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
|
|
||||||
t.window.width = 1280 -- The window width (number)
|
|
||||||
t.window.height = 720 -- The window height (number)
|
|
||||||
|
|
||||||
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
|
||||||
t.window.resizable = true -- Let the window be user-resizable (boolean)
|
|
||||||
t.window.minwidth = 1 -- Minimum window width if the window is resizable (number)
|
|
||||||
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
|
|
||||||
t.window.fullscreen = false -- Enable fullscreen (boolean)
|
|
||||||
t.window.fullscreentype = "desktop" -- Standard fullscreen or desktop fullscreen mode (string)
|
|
||||||
t.window.vsync = false -- Enable vertical sync (boolean)
|
|
||||||
t.window.fsaa = 2 -- The number of samples to use with multi-sampled antialiasing (number)
|
|
||||||
t.window.display = 1 -- Index of the monitor to show the window in (number)
|
|
||||||
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
|
|
||||||
t.window.srgb = false -- Enable sRGB gamma correction when drawing to the screen (boolean)
|
|
||||||
t.window.x = nil -- The x-coordinate of the window's position in the specified display (number)
|
|
||||||
t.window.y = nil -- The y-coordinate of the window's position in the specified display (number)
|
|
||||||
|
|
||||||
t.modules.audio = false -- Enable the audio module (boolean)
|
|
||||||
t.modules.event = false -- Enable the event module (boolean)
|
|
||||||
t.modules.graphics = false -- Enable the graphics module (boolean)
|
|
||||||
t.modules.image = false -- Enable the image module (boolean)
|
|
||||||
t.modules.joystick = false -- Enable the joystick module (boolean)
|
|
||||||
t.modules.keyboard = false -- Enable the keyboard module (boolean)
|
|
||||||
t.modules.math = false -- Enable the math module (boolean)
|
|
||||||
t.modules.mouse = false -- Enable the mouse module (boolean)
|
|
||||||
t.modules.physics = false -- Enable the physics module (boolean)
|
|
||||||
t.modules.sound = false -- Enable the sound module (boolean)
|
|
||||||
t.modules.system = false -- Enable the system module (boolean)
|
|
||||||
t.modules.timer = false -- Enable the timer module (boolean)
|
|
||||||
t.modules.window = false -- Enable the window module (boolean)
|
|
||||||
t.modules.thread = true -- Enable the thread module (boolean)
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
--[[
|
||||||
|
Test suite for multi.lua
|
||||||
|
Run with: lua multi_test.lua
|
||||||
|
|
||||||
|
Requires multi.lua to be in the same directory or on the Lua path.
|
||||||
|
Compatible with Lua 5.1, 5.2, 5.3, 5.4, and LuaJIT.
|
||||||
|
]]
|
||||||
|
package.path = "../?/init.lua;../?.lua;../init.lua;../?.lua;" .. package.path
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
-- Minimal test runner
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
local passed, failed, skipped = 0, 0, 0
|
||||||
|
local failures = {}
|
||||||
|
|
||||||
|
local function test(name, fn)
|
||||||
|
local ok, err = pcall(fn)
|
||||||
|
if ok then
|
||||||
|
passed = passed + 1
|
||||||
|
io.write("\x1b[92m ✓\x1b[0m " .. name .. "\n")
|
||||||
|
else
|
||||||
|
failed = failed + 1
|
||||||
|
table.insert(failures, {name = name, err = tostring(err)})
|
||||||
|
io.write("\x1b[91m ✗\x1b[0m " .. name .. "\n")
|
||||||
|
io.write(" " .. tostring(err) .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function skip(name, reason)
|
||||||
|
skipped = skipped + 1
|
||||||
|
io.write("\x1b[93m -\x1b[0m " .. name .. " [SKIPPED: " .. (reason or "") .. "]\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function section(name)
|
||||||
|
io.write("\n\x1b[97m── " .. name .. " ──\x1b[0m\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert_eq(a, b, msg)
|
||||||
|
if a ~= b then
|
||||||
|
error((msg or "assert_eq failed") .. ": expected " .. tostring(b) .. ", got " .. tostring(a), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert_truthy(v, msg)
|
||||||
|
if not v then
|
||||||
|
error((msg or "expected truthy value, got falsy") .. ": " .. tostring(v), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert_falsy(v, msg)
|
||||||
|
if v then
|
||||||
|
error((msg or "expected falsy value, got truthy") .. ": " .. tostring(v), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function assert_type(v, t, msg)
|
||||||
|
if type(v) ~= t then
|
||||||
|
error((msg or "type mismatch") .. ": expected " .. t .. ", got " .. type(v), 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
-- Load the library
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
local multi, thread
|
||||||
|
local ok, err = pcall(function()
|
||||||
|
multi, thread = require("multi"):init()
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
io.write("\x1b[91mFATAL: Could not load multi.lua: " .. tostring(err) .. "\x1b[0m\n")
|
||||||
|
io.write("Make sure multi.lua is in the same directory or on package.path.\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper: run the scheduler for up to `max_ticks` ticks or until `done()` returns true.
|
||||||
|
local function run_until(done, max_ticks)
|
||||||
|
max_ticks = max_ticks or 10000
|
||||||
|
for _ = 1, max_ticks do
|
||||||
|
multi:uManager()
|
||||||
|
if done and done() then return true end
|
||||||
|
end
|
||||||
|
return done == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
section("Initialization")
|
||||||
|
|
||||||
|
test("lanesManager init returns GLOBAL and THREAD", function()
|
||||||
|
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
||||||
|
assert_type(GLOBAL, "table")
|
||||||
|
assert_type(THREAD, "table")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("lanesManager sets integration table", function()
|
||||||
|
assert_type(multi.integration.GLOBAL, "table")
|
||||||
|
assert_type(multi.integration.THREAD, "table")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- initialize once for rest of tests
|
||||||
|
local GLOBAL, THREAD = require("multi.integration.lanesManager"):init()
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("SystemThreadedQueue")
|
||||||
|
|
||||||
|
test("queue push/pop", function()
|
||||||
|
local q = multi:newSystemThreadedQueue("testQ1")
|
||||||
|
|
||||||
|
q:push(42)
|
||||||
|
local val = q:pop()
|
||||||
|
|
||||||
|
assert_eq(val, 42)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("queue peek does not remove", function()
|
||||||
|
local q = multi:newSystemThreadedQueue("testQ2")
|
||||||
|
|
||||||
|
q:push("hello")
|
||||||
|
|
||||||
|
assert_eq(q:peek(), "hello")
|
||||||
|
assert_eq(q:pop(), "hello")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("queue empty returns nil", function()
|
||||||
|
local q = multi:newSystemThreadedQueue("testQ3")
|
||||||
|
|
||||||
|
assert_eq(q:pop(), nil)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("SystemThreadedTable")
|
||||||
|
|
||||||
|
test("table set/get", function()
|
||||||
|
local t = multi:newSystemThreadedTable("testT1")
|
||||||
|
|
||||||
|
t.foo = "bar"
|
||||||
|
assert_eq(t.foo, "bar")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("table overwrite", function()
|
||||||
|
local t = multi:newSystemThreadedTable("testT2")
|
||||||
|
|
||||||
|
t.x = 1
|
||||||
|
t.x = 2
|
||||||
|
|
||||||
|
assert_eq(t.x, 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("THREAD API")
|
||||||
|
|
||||||
|
test("THREAD set/get", function()
|
||||||
|
THREAD.set("abc", 123)
|
||||||
|
assert_eq(THREAD.get("abc"), 123)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test("THREAD getCores > 0", function()
|
||||||
|
assert_truthy(THREAD.getCores() > 0)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("SystemThreadedConnection")
|
||||||
|
|
||||||
|
test("connection fires event", function()
|
||||||
|
local conn = multi:newSystemThreadedConnection("conn1"):init()
|
||||||
|
|
||||||
|
local received = nil
|
||||||
|
|
||||||
|
conn(function(v)
|
||||||
|
received = v
|
||||||
|
end)
|
||||||
|
|
||||||
|
conn:Fire("ping")
|
||||||
|
|
||||||
|
run_until(function()
|
||||||
|
return received ~= nil
|
||||||
|
end, 5000)
|
||||||
|
|
||||||
|
assert_eq(received, "ping")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("SystemThreadedJobQueue")
|
||||||
|
|
||||||
|
test("job queue executes function", function()
|
||||||
|
local jq = multi:newSystemThreadedJobQueue(1)
|
||||||
|
|
||||||
|
jq:registerFunction("add", function(a, b)
|
||||||
|
return a + b
|
||||||
|
end)
|
||||||
|
|
||||||
|
local result = nil
|
||||||
|
|
||||||
|
jq.OnJobCompleted(function(_, val)
|
||||||
|
result = val
|
||||||
|
end)
|
||||||
|
|
||||||
|
jq:pushJob("add", 2, 3)
|
||||||
|
|
||||||
|
run_until(function()
|
||||||
|
return result ~= nil
|
||||||
|
end, 10000)
|
||||||
|
|
||||||
|
assert_eq(result, 5)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("JobQueue newFunction")
|
||||||
|
|
||||||
|
test("newFunction returns correct result", function()
|
||||||
|
local jq = multi:newSystemThreadedJobQueue(1)
|
||||||
|
|
||||||
|
local fn = jq:newFunction(function(a, b)
|
||||||
|
return a * b
|
||||||
|
end,true)
|
||||||
|
|
||||||
|
local result = nil
|
||||||
|
|
||||||
|
result = fn(3, 4)
|
||||||
|
|
||||||
|
run_until(function()
|
||||||
|
return result ~= nil
|
||||||
|
end, 10000)
|
||||||
|
|
||||||
|
assert_eq(result, 12)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
-- Summary
|
||||||
|
-- ─────────────────────────────────────────────
|
||||||
|
section("Results")
|
||||||
|
|
||||||
|
io.write("\n")
|
||||||
|
io.write("Passed: " .. passed .. "\n")
|
||||||
|
io.write("Failed: " .. failed .. "\n")
|
||||||
|
io.write("Skipped: " .. skipped .. "\n")
|
||||||
|
|
||||||
|
if failed > 0 then
|
||||||
|
io.write("\nFailures:\n")
|
||||||
|
for _, f in ipairs(failures) do
|
||||||
|
io.write(" - " .. f.name .. "\n")
|
||||||
|
io.write(" " .. f.err .. "\n")
|
||||||
|
end
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package.path = "../?/init.lua;../?.lua;"..package.path
|
|
||||||
|
|
||||||
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
|
|
||||||
require("lldebugger").start()
|
|
||||||
end
|
|
||||||
|
|
||||||
GLOBAL, THREAD = require("multi.integration.loveManager"):init()
|
|
||||||
|
|
||||||
require("runtests")
|
|
||||||
require("threadtests")
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
|||||||
package.path = "../?/init.lua;../?.lua;./init.lua;./?.lua;"..package.path
|
|
||||||
|
|
||||||
local multi, thread = require("multi"):init{print=true,warn=true,error=true}--{priority=true}
|
|
||||||
local good = false
|
|
||||||
local proc = multi:newProcessor("Test")
|
|
||||||
|
|
||||||
print("Version: "..multi.Version)
|
|
||||||
|
|
||||||
proc.Start()
|
|
||||||
|
|
||||||
proc:newAlarm(3):OnRing(function()
|
|
||||||
good = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
runTest = thread:newFunction(function()
|
|
||||||
local alarms,tsteps,steps,loops,tloops,updaters,events=false,0,0,0,0,0,false
|
|
||||||
multi.print("Testing Basic Features. If this fails most other features will probably not work!")
|
|
||||||
proc:newAlarm(2):OnRing(function(a)
|
|
||||||
alarms = true
|
|
||||||
a:Destroy()
|
|
||||||
end)
|
|
||||||
proc:newTStep(1,10,1,.1):OnStep(function(t)
|
|
||||||
tsteps = tsteps + 1
|
|
||||||
end):OnEnd(function(step)
|
|
||||||
step:Destroy()
|
|
||||||
end)
|
|
||||||
proc:newStep(1,10):OnStep(function(s)
|
|
||||||
steps = steps + 1
|
|
||||||
end):OnEnd(function(step)
|
|
||||||
step:Destroy()
|
|
||||||
end)
|
|
||||||
local loop = proc:newLoop(function(l)
|
|
||||||
loops = loops + 1
|
|
||||||
end)
|
|
||||||
proc:newTLoop(function(t)
|
|
||||||
tloops = tloops + 1
|
|
||||||
end,.1)
|
|
||||||
local updater = proc:newUpdater(1):OnUpdate(function()
|
|
||||||
updaters = updaters + 1
|
|
||||||
end)
|
|
||||||
local event = proc:newEvent(function()
|
|
||||||
return alarms
|
|
||||||
end)
|
|
||||||
event.OnEvent(function(evnt)
|
|
||||||
evnt:Destroy()
|
|
||||||
events = true
|
|
||||||
multi.success("Alarms: Ok")
|
|
||||||
multi.success("Events: Ok")
|
|
||||||
if tsteps == 10 then multi.success("TSteps: Ok") else multi.error("TSteps: Bad!") end
|
|
||||||
if steps == 10 then multi.success("Steps: Ok") else multi.error("Steps: Bad!") end
|
|
||||||
if loops > 100 then multi.success("Loops: Ok") else multi.error("Loops: Bad!") end
|
|
||||||
if tloops > 10 then multi.success("TLoops: Ok") else multi.error("TLoops: Bad!") end
|
|
||||||
if updaters > 100 then multi.success("Updaters: Ok") else multi.error("Updaters: Bad!") end
|
|
||||||
end)
|
|
||||||
thread.hold(event.OnEvent)
|
|
||||||
multi.print("Starting Connection and Thread tests!")
|
|
||||||
func = thread:newFunction(function(count)
|
|
||||||
multi.print("Starting Status test: ",count)
|
|
||||||
local a = 0
|
|
||||||
while true do
|
|
||||||
a = a + 1
|
|
||||||
thread.sleep(.1)
|
|
||||||
thread.pushStatus(a,count)
|
|
||||||
if a == count then break end
|
|
||||||
end
|
|
||||||
return "Done", true, math.random(1,10000)
|
|
||||||
end)
|
|
||||||
local ret = func(10)
|
|
||||||
local ret2 = func(15)
|
|
||||||
local ret3 = func(20)
|
|
||||||
local s1,s2,s3 = 0,0,0
|
|
||||||
ret.OnError(function(...)
|
|
||||||
multi.error("Func 1:",...)
|
|
||||||
end)
|
|
||||||
ret2.OnError(function(...)
|
|
||||||
multi.error("Func 2:",...)
|
|
||||||
end)
|
|
||||||
ret3.OnError(function(...)
|
|
||||||
multi.error("Func 3:",...)
|
|
||||||
end)
|
|
||||||
ret.OnStatus(function(part,whole)
|
|
||||||
s1 = math.ceil((part/whole)*1000)/10
|
|
||||||
end)
|
|
||||||
ret2.OnStatus(function(part,whole)
|
|
||||||
s2 = math.ceil((part/whole)*1000)/10
|
|
||||||
end)
|
|
||||||
ret3.OnStatus(function(part,whole)
|
|
||||||
s3 = math.ceil((part/whole)*1000)/10
|
|
||||||
end)
|
|
||||||
|
|
||||||
ret.OnReturn(function(...)
|
|
||||||
multi.success("Done 1",...)
|
|
||||||
end)
|
|
||||||
ret2.OnReturn(function(...)
|
|
||||||
multi.success("Done 2",...)
|
|
||||||
end)
|
|
||||||
ret3.OnReturn(function(...)
|
|
||||||
multi.success("Done 3",...)
|
|
||||||
end)
|
|
||||||
|
|
||||||
local err, timeout = thread.hold(ret.OnReturn * ret2.OnReturn * ret3.OnReturn)
|
|
||||||
|
|
||||||
if s1 == 100 and s2 == 100 and s3 == 100 then
|
|
||||||
multi.success("Threads: All tests Ok")
|
|
||||||
else
|
|
||||||
if s1>0 and s2>0 and s3 > 0 then
|
|
||||||
multi.success("Thread OnStatus: Ok")
|
|
||||||
else
|
|
||||||
multi.error("Threads OnStatus or thread.hold(conn) Error!")
|
|
||||||
end
|
|
||||||
if timeout then
|
|
||||||
multi.error("Connection Error!")
|
|
||||||
else
|
|
||||||
multi.success("Connection Test 1: Ok")
|
|
||||||
end
|
|
||||||
multi.error("Connection holding Error!")
|
|
||||||
end
|
|
||||||
|
|
||||||
conn1 = proc:newConnection()
|
|
||||||
conn2 = proc:newConnection()
|
|
||||||
conn3 = proc:newConnection()
|
|
||||||
local c1,c2,c3,c4 = false,false,false,false
|
|
||||||
|
|
||||||
local a = conn1(function()
|
|
||||||
c1 = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
local b = conn2(function()
|
|
||||||
c2 = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
local c = conn3(function()
|
|
||||||
c3 = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
local d = conn3(function()
|
|
||||||
c4 = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
conn1:Fire()
|
|
||||||
conn2:Fire()
|
|
||||||
conn3:Fire()
|
|
||||||
|
|
||||||
if c1 and c2 and c3 and c4 then
|
|
||||||
multi.success("Connection Test 2: Ok")
|
|
||||||
else
|
|
||||||
multi.error("Connection Test 2: Error")
|
|
||||||
end
|
|
||||||
c3 = false
|
|
||||||
c4 = false
|
|
||||||
conn3:Unconnect(d)
|
|
||||||
conn3:Fire()
|
|
||||||
if c3 and not(c4) then
|
|
||||||
multi.success("Connection Test 3: Ok")
|
|
||||||
else
|
|
||||||
multi.error("Connection Test 3: Error removing connection")
|
|
||||||
end
|
|
||||||
if not love then
|
|
||||||
local ec = 0
|
|
||||||
multi.print("Testing pseudo threading")
|
|
||||||
capture = io.popen("lua tests/threadtests.lua p"):read("*a")
|
|
||||||
if capture:lower():match("error") then
|
|
||||||
ec = ec + 1
|
|
||||||
os.exit(1)
|
|
||||||
else
|
|
||||||
io.write(capture)
|
|
||||||
end
|
|
||||||
multi.print("Testing lanes threading")
|
|
||||||
capture = io.popen("lua tests/threadtests.lua l"):read("*a")
|
|
||||||
if capture:lower():match("error") then
|
|
||||||
ec = ec + 1
|
|
||||||
os.exit(1)
|
|
||||||
else
|
|
||||||
io.write(capture)
|
|
||||||
end
|
|
||||||
os.exit(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
local handle = runTest()
|
|
||||||
|
|
||||||
handle.OnError(function(...)
|
|
||||||
multi.error("Something went wrong with the test!")
|
|
||||||
print(...)
|
|
||||||
end)
|
|
||||||
|
|
||||||
if not love then
|
|
||||||
multi:mainloop()
|
|
||||||
else
|
|
||||||
local hold = thread:newFunction(function()
|
|
||||||
thread.hold(handle.OnError + handle.OnReturn)
|
|
||||||
end, true)
|
|
||||||
hold()
|
|
||||||
multi.print("Starting Threading tests!")
|
|
||||||
end
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package.path = "D:/VSCWorkspace/?/init.lua;D:/VSCWorkspace/?.lua;"..package.path
|
package.path = "../?/init.lua;../?.lua;../init.lua;../?.lua;" .. package.path
|
||||||
package.cpath = "C:/luaInstalls/lua5.4/lib/lua/5.4/?/core.dll;" .. package.cpath
|
package.cpath = "C:/luaInstalls/lua5.4/lib/lua/5.4/?/core.dll;" .. package.cpath
|
||||||
multi, thread = require("multi"):init{error=true,warning=true,print=true, priority=true}
|
multi, thread = require("multi"):init{error=true,warning=true,print=true, priority=true}
|
||||||
proc = multi:newProcessor("Thread Test",true)
|
proc = multi:newProcessor("Thread Test",true)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user