Skip to content
This repository has been archived by the owner on Sep 22, 2024. It is now read-only.

Commit

Permalink
Upgrade repository state
Browse files Browse the repository at this point in the history
Add workflow checks for
stylua, analysis
  • Loading branch information
metatablecat committed Aug 8, 2024
1 parent e90de90 commit 74dd2bf
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 203 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Install Aftman
uses: ok-nick/setup-aftman@v0.4.2
with:
token: ${{ github.token }}

- name: Analyze
run: sh scripts/analyse.sh

style:
name: Styling
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Check code style
uses: JohnnyMorganz/stylua-action@v4
with:
token: ${{ github.token }}
version: latest
args: --check src
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
build/**
sourcemap.json
build.project.json
build.project.json
globalTypes.d.lua
2 changes: 2 additions & 0 deletions aftman.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
lune = "lune-org/lune@0.8.6"
rojo = "rojo-rbx/rojo@7.4.1"
darklua = "seaofvoices/darklua@0.13.1"
luau-lsp = "johnnymorganz/luau-lsp@1.32.1"
stylua = "johnnymorganz/stylua@0.20.0"
11 changes: 11 additions & 0 deletions scripts/analyse.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

set -e

curl -O https://raw.githubusercontent.com/JohnnyMorganz/luau-lsp/main/scripts/globalTypes.d.lua
rojo sourcemap default.project.json -o sourcemap.json

luau-lsp analyze --definitions=globalTypes.d.lua --base-luaurc=.luaurc \
--sourcemap=sourcemap.json --settings=.vscode/settings.json \
--no-strict-dm-types --ignore src/base.luau \
src/
2 changes: 1 addition & 1 deletion src/Class.luau
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
local Catwork = require(".")
return Catwork.Class
return Catwork.Class
2 changes: 1 addition & 1 deletion src/Object.luau
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
local Catwork = require(".")
return Catwork.new
return Catwork.new
2 changes: 1 addition & 1 deletion src/Service.luau
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
local Catwork = require(".")
return Catwork.Service
return Catwork.Service
16 changes: 8 additions & 8 deletions src/init.luau
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
-- metatablecatgames 2024 - Licensed under the MIT License
--local RunService = game:GetService("RunService")
local Common = require("./lib/Common")
local Service = require("./lib/Service")
local Metakeys = require("./meta")
local Native = require("./lib/Native")
local Service = require("./lib/Service")
local Types = require("./lib/Types")
local Metakeys = require("./meta")

local REFLECTION = require("./lib/Reflection")
local ERROR = require("./lib/Error")
local REFLECTION = require("./lib/Reflection")

local Catwork
export type Object<Parameters> = Types.Object<Parameters>
Expand All @@ -25,7 +25,7 @@ Catwork = setmetatable({

return Native.Object(params)
end,

Service = function(params: Types.ServiceCtorParams): Types.Service
REFLECTION.ARG(1, "Catwork.Service", REFLECTION.TABLE, params)

Expand All @@ -37,12 +37,12 @@ Catwork = setmetatable({
REFLECTION.ARG(2, "Catwork.Class", REFLECTION.FUNCTION, createFn)

return Native.GetClassLike(name, createFn)
end
},{
__tostring = function(self) return `Module(Catwork v{self.__VERSION})` end
end,
}, {
__tostring = function(self) return `Module(Catwork v{self.__VERSION})` end,
})

table.freeze(Catwork)
type Catwork = typeof(Catwork)
if game and not Catwork.Plugin then print(Common.WelcomeMessage) end
return Catwork
return Catwork
14 changes: 5 additions & 9 deletions src/lib/Class.luau
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local Common = require("./Common")
local ERROR = require("./Error")
local Metakeys = require("../meta")
local ENABLE_CLASSES_METAKEY = Metakeys.export "EnableClasses"
local ENABLE_CLASSES_METAKEY = Metakeys.export("EnableClasses")

return function(service, name, createObject)
-- just clones the template params and pushes it to the service if its nil
Expand All @@ -11,18 +11,14 @@ return function(service, name, createObject)
params.CreateObject = createObject
params[Common.ClassHeader] = true

if not service[ENABLE_CLASSES_METAKEY] then
ERROR.SERVICE_NO_CLASSES(service.Name)
end

if not service[ENABLE_CLASSES_METAKEY] then ERROR.SERVICE_NO_CLASSES(service.Name) end

if not Common.Flags.DONT_ASSIGN_OBJECT_MT then
setmetatable(params, {
__tostring = function(self)
return `ServiceTemplate({self.Name})`
end,
__tostring = function(self) return `ServiceTemplate({self.Name})` end,
})
end

table.freeze(params)
return params
end
end
33 changes: 16 additions & 17 deletions src/lib/Common.luau
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
local Types = require("./Types")
local ERROR = require("./Error")
local Metakeys = require("../meta")
local Types = require("./Types")

local HttpService = if game then game:GetService("HttpService") else {
GenerateGUID = function(self, withBrackets)
local template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
if withBrackets then template = `\{{template}\}` end
local HttpService = if game
then game:GetService("HttpService")
else {
GenerateGUID = function(self, withBrackets)
local template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
if withBrackets then template = `\{{template}\}` end

return string.gsub(template, "[xy]", function(c)
local v = (c == "x") and math.random(0, 15) or math.random(8, 11)
return string.format("%x", v)
end)
end
}
return string.gsub(template, "[xy]", function(c)
local v = (c == "x") and math.random(0, 15) or math.random(8, 11)
return string.format("%x", v)
end)
end,
}

local VERSION = "0.5.0"
local GUID_PATTERN = "^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$"
Expand Down Expand Up @@ -43,19 +45,16 @@ local function getMetakeysAsStrings(tab)
return metakeys
end


function Common.validateTable(tab, oName, rules: {[string]: string})
function Common.validateTable(tab, oName, rules: { [string]: string })
for key, typof in rules do
local optional = string.match(typof, OPT_PAT)
typof = if optional then optional else typof
typof = if optional then optional else typof

local value = tab[key]
if not value and optional then continue end

local typeis = typeof(value)
if typeis ~= typof then
ERROR.BAD_TABLE_SHAPE(tab, oName, key, typof, typeis)
end
if typeis ~= typof then ERROR.BAD_TABLE_SHAPE(tab, oName, key, typof, typeis) end
end

return tab, getMetakeysAsStrings(tab)
Expand Down
74 changes: 27 additions & 47 deletions src/lib/Dispatcher.luau
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ local Dispatcher = {}
local objectDispatchState = {}
local OBJECT_DESTROYED_RETURN_MSG = "The object was destroyed"

local serviceStartState: {[Types.Service]: {
State: "suspended"|"running"|"finished",
HeldThreads: {thread}
}} = {}
local serviceStartState: { [Types.Service]: {
State: "suspended" | "running" | "finished",
HeldThreads: { thread },
} } =
{}

local function safeAsyncHandler(err)
ERROR.DISPATCHER_SPAWN_ERR(ERROR.traceback(err))
Expand All @@ -22,24 +23,20 @@ end

local function doServiceLoopForObject(object, service, state)
local resumptionDelay = 0

while not state.Destroyed do
local dt = if resumptionDelay and resumptionDelay < 0 then 0 else task.wait(resumptionDelay or 0)
if state.Destroyed then break end -- fixes a bug where loops continue an extra tick after destruction
resumptionDelay = service:Updating(object, dt)
end
end

function Dispatcher.getObjectState(o)
return objectDispatchState[o]
end
function Dispatcher.getObjectState(o) return objectDispatchState[o] end

local function getObjectStateError(o)
local state = Dispatcher.getObjectState(o)

if not state then
ERROR.OBJECT_DESTROYED(o)
end

if not state then ERROR.OBJECT_DESTROYED(o) end

return state
end
Expand All @@ -49,8 +46,10 @@ local function free(state, ok, err, o, service)
state.IsOK = ok
state.ErrMsg = err

local dispatchers = state.Dispatchers; state.Dispatchers = {}
local held = state.HeldThreads; state.HeldThreads = {}
local dispatchers = state.Dispatchers
state.Dispatchers = {}
local held = state.HeldThreads
state.HeldThreads = {}

for _, v in dispatchers do
task.spawn(v, ok, err)
Expand All @@ -75,7 +74,7 @@ local function serviceStartup(service)
if not serviceState then
serviceState = {
State = "suspended",
HeldThreads = {}
HeldThreads = {},
}

serviceStartState[service] = serviceState
Expand All @@ -97,12 +96,7 @@ local function serviceStartup(service)
end
end

local function runObjectAction(
o,
spawnSignal,
service,
state
)
local function runObjectAction(o, spawnSignal, service, state)
state.Spawned = true
state.Thread = coroutine.running()

Expand All @@ -117,9 +111,7 @@ local function runObjectAction(

free(state, ok, err)

if service.Updating and o.Update then
task.spawn(doServiceLoopForObject, o, service, state)
end
if service.Updating and o.Update then task.spawn(doServiceLoopForObject, o, service, state) end

return ok, err
end
Expand Down Expand Up @@ -153,15 +145,11 @@ local function spawnObject(object, service, state, asyncMode)
local spawnSignal = service.Spawning
serviceStartup(service)

if asyncMode then
object:HandleAsync(asyncMode)
end
if asyncMode then object:HandleAsync(asyncMode) end

task.spawn(runObjectAction, object, spawnSignal, service, state)

if not asyncMode then
return object:Await()
end
if not asyncMode then return object:Await() end

return nil
end
Expand All @@ -178,21 +166,15 @@ function Dispatcher.spawnObject(o, service, fPrivate, xpcallHandler, asyncHandle

-- we would handle this from the service but its safer to handle here
-- if an object is dead we just safely cancel it
if service ~= fPrivate.Service then
ERROR.SERVICE_INVALID_CLASS()
end
if service ~= fPrivate.Service then ERROR.SERVICE_INVALID_CLASS() end

state.TimeoutDisabled = fPrivate.TimeoutDisabled
state.AwaitFor = fPrivate.AwaitFor

-- basically new logic for Spawn
if state.Spawned then
ERROR.DISPATCHER_ALREADY_SPAWNED(o)
end
if state.Spawned then ERROR.DISPATCHER_ALREADY_SPAWNED(o) end

if xpcallHandler then
state.XPC = xpcallHandler
end
if xpcallHandler then state.XPC = xpcallHandler end

return spawnObject(o, fPrivate.Service, state, asyncHandler)
end
Expand Down Expand Up @@ -244,11 +226,9 @@ function Dispatcher.isSelfAsyncCall(o)
if not state then return false end -- object is destroyed, will never self-await here.

local co = coroutine.running()

if state.Spawned and co == state.Thread then
return not state.Ready
end


if state.Spawned and co == state.Thread then return not state.Ready end

return false
end

Expand All @@ -270,7 +250,7 @@ function Dispatcher.initObjectState(o)

AwaitFor = {},
HeldThreads = {},
Dispatchers = {}
Dispatchers = {},
}
objectDispatchState[o] = state

Expand All @@ -283,4 +263,4 @@ function Dispatcher.getStateString(o)
return if state.Ready then "spawned" else "pending"
end

return Dispatcher
return Dispatcher
Loading

0 comments on commit 74dd2bf

Please sign in to comment.