diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ee7ed26..2c82f3bb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: run: wally install - name: Generate sourcemap - run: argon sourcemap standalone.project.json --output sourcemap.json + run: rojo sourcemap standalone.project.json --output sourcemap.json - name: Generate package types run: wally-package-types --sourcemap sourcemap.json Packages @@ -72,7 +72,7 @@ jobs: run: stylua src/ - name: Build standalone - run: argon build standalone.project.json --output ./Standalone.rbxm + run: rojo build standalone.project.json --output ./Standalone.rbxm - name: Draft release uses: softprops/action-gh-release@v2.0.8 diff --git a/dev.project.json b/dev.project.json index 28ccd2c2..312eb33a 100644 --- a/dev.project.json +++ b/dev.project.json @@ -1,5 +1,5 @@ { - "legacyScripts": false, + "emitLegacyScripts": false, "name": "framework", "tree": { "$className": "DataModel", @@ -14,6 +14,7 @@ } }, "Tests": { + "$className": "Folder", "Client": { "$path": "tests/client" }, @@ -23,4 +24,4 @@ } } } -} \ No newline at end of file +} diff --git a/docs/reference/controller.md b/docs/api/controller.md similarity index 100% rename from docs/reference/controller.md rename to docs/api/controller.md diff --git a/docs/reference/worker.md b/docs/api/cycle.md similarity index 88% rename from docs/reference/worker.md rename to docs/api/cycle.md index a68fc72c..fcf82802 100644 --- a/docs/reference/worker.md +++ b/docs/api/cycle.md @@ -1,4 +1,4 @@ -# Worker +# Cycle Responsible for handling actions on different threads concurrently @@ -8,7 +8,7 @@ Responsible for handling actions on different threads concurrently ### `Connection` -The connection of the worker. +The connection of the cycle. - **RBXScriptSignal** diff --git a/docs/reference/index.md b/docs/api/index.md similarity index 67% rename from docs/reference/index.md rename to docs/api/index.md index 5275f2d0..5349b2a7 100644 --- a/docs/reference/index.md +++ b/docs/api/index.md @@ -18,13 +18,16 @@ The current version of the framework. ### `Start` -Starts the framework and prepares all of the workers/controllers. +Starts the framework and prepares all of the cycles/controllers. **Parameters** - **loaded:** `{ Controller }`
A list of already loaded controllers, should be from `.Load` +- **callback:** `(() -> ())?`
+Runs when the start process has finished + **Returns** - **void** @@ -46,17 +49,17 @@ This is where functions, properties, and methods are stored. Use this like a gen --- -### `Worker` +### `Cycle` -Creates a new worker for management of various tasks that happen continously in the background. +Creates a new cycle for management of various tasks that happen continously in the background. **Parameters** -- **type:** `WorkerType`
-A designated worker type +- **type:** `CycleType`
+A designated cycle type - **callback:** `(args: ...any) -> ()`
-The callback to run for the worker type +The callback to run for the cycle type **Returns** @@ -79,18 +82,3 @@ A function that runs for every module script, returning true will allow the modu **Returns** - **void** - ---- - -### `OnStart` - -Runs the provided callback function when the framework is completely started. - -**Parameters** - -- **callback:** `() -> ()`
-Callback function to run after the framework starts - -**Returns** - -- **void** diff --git a/docs/changelog.md b/docs/changelog.md index 5935b939..7508da8c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,10 +1,7 @@ -* * * - +--- hide: - - navigation - -* * * +--- # Changelog @@ -15,6 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Fixes `.Start` not being called in `Used` modules + +### Changed + +- Changes `Worker` to `Cycle` +- Changed docs style + ## [9.0.0-rc8] - 2024-09-13 ### Fixed diff --git a/docs/guides/controllers.md b/docs/guides/controllers.md index 3cecd3a8..000eab95 100644 --- a/docs/guides/controllers.md +++ b/docs/guides/controllers.md @@ -15,10 +15,10 @@ local function Start() print("Started!") end -return Lumin.New({ +return Lumin.New { Init = Init, Start = Start, -}) +} ``` That is an example of the most minimal controller, that includes all of the required items. With this, you include as many other functions, methods, or properties as you please. @@ -36,11 +36,9 @@ The functionality of these are explained in the [loading section.](#loading) ```mermaid flowchart LR - A(Init) --> B{Pcall} --> C(Success) & D(Error) - E(Start) - C --> E - D --x E - E --> F(Finished) + A(Init) --> B{Pcall} --> + C(Start) --> D{Pcall} --> + F(Finished) ``` Above is a diagram of how every controller loads. Dependencies of controllers will become available after `Start` is called as seen in order below: diff --git a/docs/guides/workers.md b/docs/guides/cycles.md similarity index 53% rename from docs/guides/workers.md rename to docs/guides/cycles.md index 2be3e63f..848d4c4a 100644 --- a/docs/guides/workers.md +++ b/docs/guides/cycles.md @@ -1,14 +1,14 @@ -# Workers +# Cycles -Workers are essentially lifecycle events like in any other framework. They allow for code to constantly run in the background without interupting anything that is in the main thread. Notable mentions include `PlayerAdded` and `PostSimulation`. The purpose of workers is so that we can introduce more safety while using the framework and run into less issues like race conditions or unexplainable errors. New workers cannot be created after `.Start` is finished. +Cycles are essentially lifecycle events like in any other framework. They allow for code to constantly run in the background without interupting anything that is in the main thread. Notable mentions include `PlayerAdded` and `PostSimulation`. The purpose of cycles is so that we can introduce more safety while using the framework and run into less issues like race conditions or unexplainable errors. New cycles cannot be created after `.Start` is finished. ## Usage -Usage of workers is very minimal and simple. Here's how to use one: +Usage of cycles is very minimal and simple. Here's how to use one: ```luau local Frames = 0 -Lumin.Worker("PostSimulation", function(deltaTime) +Lumin.Cycle("PostSimulation", function(deltaTime) print(deltaTime) print("Frame number", Frames += 1) end) @@ -16,9 +16,9 @@ end) The code above will print the amount of frames that have passed since the server started or the client joined entered the data model. It will also print the delta time for each frame. -## Worker Types +## Cycle Types -This is a list of all of the allowed worker types. It can be seen below. +This is a list of all of the allowed cycle types. It can be seen below. - `PostSimulation`
Fires every *frame* after the physics simulation has completed. diff --git a/docs/guides/dependencies.md b/docs/guides/dependencies.md index 6c9aa359..925f12e1 100644 --- a/docs/guides/dependencies.md +++ b/docs/guides/dependencies.md @@ -15,10 +15,10 @@ local function Init() print("Loaded second!") end -return Lumin.New({ - Uses = {MyController} +return Lumin.New { + Uses = { MyController } Init = Init -}) +} ``` #### Module 2 @@ -28,9 +28,9 @@ local function Init() print("Loaded first!") end -return Lumin.New({ +return Lumin.New { Init = Init, -}) +} ``` ## Loading @@ -39,5 +39,5 @@ The load order differs from the default but not too much. Here's a diagram of it ```mermaid flowchart TB - A(Uses MyController) -- Put module first in loading queue --> B(Init in used) -- Load dependency --> C(Init in loader) -- Dependencies are ready --> D(Finish) + A(Uses MyController) -- Put module first in loading queue --> B(Init in used) -- Load dependency --> C(Init in loader) -- Dependencies are ready --> D(Start in both) -- Loading completed --> E(Finish) ``` diff --git a/docs/guides/networking.md b/docs/guides/networking.md index 34ca6f36..b06de889 100644 --- a/docs/guides/networking.md +++ b/docs/guides/networking.md @@ -1,6 +1,6 @@ # Networking -There is no stock networking library that comes with the framework, so you can use any library you want to. For a default option, you can use [LuminNet](https://github.com/lumin-dev/LuminNet) +There is no stock networking library that comes with the framework, so you can use any library you want to. For a default option, you can use [Net](https://github.com/luminlabsdev/net) by Lumin. We also recommend: @@ -8,4 +8,4 @@ We also recommend: - **[Zap](https://github.com/red-blox/zap)** - A CLI-based library that creates static .zap files for the most optimization - **[Blink](https://github.com/1Axen/blink)** - A competitor to Zap which does similar things, but has support for studio and different API -But for basic networking, we recommend using LuminNet as the API is less bloated than libraries like BridgeNet or Red. Note that the optimizations of LuminNet are still well over default remote event benchmarks. \ No newline at end of file +But for basic networking, we recommend using LuminNet as the API is less bloated than libraries like BridgeNet or Red. Note that the optimizations of LuminNet are still well over default remote event benchmarks. diff --git a/docs/index.md b/docs/index.md index ad7e1476..436877f1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,9 +18,9 @@ local function Explode() print("KABOOM!!!") end -return Framework.New({ +return Framework.New { Explode = Explode, -}) +} ``` Efficient and not verbose controller API, is very similar to vanilla modules and does not add any bloat. @@ -36,10 +36,10 @@ local function Init() Dependency.NuclearExplosion() -- This dependency loads first and in result is usable! end -return Framework.New({ - Uses = {Dependency}, +return Framework.New { + Uses = { Dependency }, Init = Init, -}) +} ``` Organizes your dependencies in an understandable way, so you can easily keep track of what your module uses. @@ -55,9 +55,9 @@ local function Init() end) end -return Framework.New({ +return Framework.New { Init = Init, -}) +} ``` Has a simple worker/lifecycle design that is readable and accessible at a glance. diff --git a/mkdocs.yml b/mkdocs.yml index 59d6c7a7..5d522981 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,20 @@ repo_url: https://github.com/luminlabsdev/framework repo_name: luminlabsdev/framework copyright: Copyright © 2021 - 2024 Lumin Labs & Contributors edit_uri: edit/main/docs/ +nav: + - Home: index.md + - Guides: + - Setup: guides/index.md + - Controllers: guides/controllers.md + - Dependencies: guides/dependencies.md + - Cycles: guides/cycles.md + - Networking: guides/networking.md + - API: + - Framework: api/index.md + - Controller: api/controller.md + - Cycle: api/cycle.md + - Install: installation.md + - Changelog: changelog.md markdown_extensions: - attr_list - pymdownx.emoji: diff --git a/rokit.toml b/rokit.toml index 77bf1b28..50acff2b 100644 --- a/rokit.toml +++ b/rokit.toml @@ -5,7 +5,7 @@ [tools] wally = "UpliftGames/wally@0.3.2" -argon = "argon-rbx/argon@2.0.13" wally-package-types = "johnnymorganz/wally-package-types@1.3.2" stylua = "johnnymorganz/stylua@0.20.0" -lune = "lune-org/lune@0.8.6" \ No newline at end of file +lune = "lune-org/lune@0.8.8" +rojo = "rojo-rbx/rojo@7.4.4" diff --git a/src/Storage.luau b/src/Storage.luau index 5087a47a..17d85912 100644 --- a/src/Storage.luau +++ b/src/Storage.luau @@ -1,5 +1,5 @@ local Types = require(script.Parent.Types) return { Controllers = {} :: {Types.Controller}, - Workers = {} :: {Types.Worker}, + Cycles = {} :: {Types.Cycle}, } diff --git a/src/Types.luau b/src/Types.luau index 0a8eaba7..f8b23ebb 100644 --- a/src/Types.luau +++ b/src/Types.luau @@ -6,7 +6,7 @@ export type Controller = { }?, } & T -export type WorkerType = +export type CycleType = "PostSimulation" | "PreSimulation" | "PreAnimation" @@ -14,14 +14,14 @@ export type WorkerType = | "PlayerAdded" | "PlayerRemoving" -export type Worker = { +export type Cycle = { Connection: RBXScriptSignal, Callback: (...any) -> (), } export type Storage = { Controllers: {Controller}, - Workers: {Worker}, + Cycles: {Cycle}, } return {} diff --git a/src/init.luau b/src/init.luau index e23852d2..8d1b4d09 100644 --- a/src/init.luau +++ b/src/init.luau @@ -13,9 +13,8 @@ local Debugger = require(Packages.debugger) local Spawn = require(Packages.spawn) local Started = false -local StartedCallback = nil -local DefaultWorkerTypes = { +local DefaultCycleTypes = { PostSimulation = RunService.PostSimulation, PreSimulation = RunService.PreSimulation, PreAnimation = RunService.PreAnimation, @@ -28,38 +27,58 @@ local DefaultWorkerTypes = { -- Starts/inits a controller internally local function LoadController(callback: () -> (), type: "Start" | "Init") - local Success, Err = xpcall(callback :: any, Debugger.Parse) + local Success, Err: Debugger.ParsedError = xpcall(callback :: any, Debugger.Parse) if not Success then - local Message = Err :: Debugger.ParsedError - Debugger.Fatal(`Cannot{type}`, Message.Message) + Debugger.Fatal(`Cannot{type}`, Err.Message) end end -- Starts/inits a list of controllers internally local function LoadAllControllers(controllers: { Types.Controller }) + local InitiatedControllers = {} + for _, controller in controllers do if controller["Uses"] and type(controller.Uses) == "table" then + table.freeze(controller.Uses) for _, usedController in controller.Uses :: any do + Debugger.Assert( + type(usedController["Init"]) == "function", + "IncorrectType", "Init", "function" + ) if usedController["Init"] then LoadController(usedController.Init, "Init") + table.insert(InitiatedControllers, usedController) table.remove(controllers, table.find(controllers, controller)) end end end - if controller["Init"] and type(controller.Init) == "function" then + + Debugger.Assert( + type(controller["Init"]) == "function", + "IncorrectType", "Init", "function" + ) + if controller["Init"] then LoadController(controller.Init, "Init") + table.insert(InitiatedControllers, controller) end - if controller["Start"] and type(controller.Start) == "function" then + end + + for _, controller in InitiatedControllers do + Debugger.Assert( + type(controller["Start"]) == "function", + "IncorrectType", "Start", "function" + ) + if controller["Start"] then LoadController(controller.Start, "Start") end - end + end end -- Starts all the workers internally -local function StartWorkers() - for _, worker in Storage.Workers do - worker.Connection:Connect(function(...) - Spawn(worker.Callback, ...) +local function StartCycles() + for _, cycle in Storage.Cycles do + cycle.Connection:Connect(function(...) + Spawn(cycle.Callback, ...) end) end end @@ -83,24 +102,24 @@ local function Load(containers: { Instance }, filter: ((ModuleScript) -> boolean end --[=[ - Starts the framework, loading all the created controllers and starting Workers. + Starts the framework, loading all the created controllers and starting cycles. [Learn More](https://luminlabsdev.github.io/framework/api/#start) ]=] -local function Start(loaded: { Types.Controller }) +local function Start(loaded: { Types.Controller }, callback: (() -> ())?) Debugger.Assert(Started, "AlreadyStarted") - LoadAllControllers(loaded) - StartWorkers() + LoadAllControllers(loaded) -- Yields until they are loaded + StartCycles() Started = true - if StartedCallback then - StartedCallback() + if callback then + callback() end table.freeze(Storage.Controllers) - table.freeze(Storage.Workers) + table.freeze(Storage.Cycles) end --[=[ @@ -115,35 +134,25 @@ local function New(members: Types.Controller): T end --[=[ - Creates a new worker for management of various tasks that happen continously in the background. + Creates a new cycle for management of various tasks that happen continously in the background. - [Learn More](https://luminlabsdev.github.io/framework/api/#worker) + [Learn More](https://luminlabsdev.github.io/framework/api/#cycle) ]=] -local function Worker(type: Types.WorkerType, callback: (...any) -> ()) +local function Cycle(type: Types.CycleType, callback: (...any) -> ()) Debugger.Assert(Started, "AlreadyStarted") - Debugger.Assert(not DefaultWorkerTypes[type], "ItemNotFound", type) + Debugger.Assert(not DefaultCycleTypes[type], "ItemNotFound", type) if type == "PreRender" and not RunService:IsClient() then Debugger.Fatal("IncorrectContext", "WorkerType") end table.insert( - Storage.Workers, + Storage.Cycles, table.freeze({ - Connection = DefaultWorkerTypes[type], + Connection = DefaultCycleTypes[type], Callback = callback, }) ) end ---[=[ - Runs the provided callback function when the framework is completely started. - - [Learn More](https://luminlabsdev.github.io/framework/api/#onstart) -]=] -local function OnStart(callback: () -> ()) - Debugger.Assert(Started, "AlreadyStarted") - StartedCallback = callback -end - -- Debugger Debugger.SetLogs(LogList) @@ -157,7 +166,7 @@ Debugger.SetMetadata({ return table.freeze({ -- Version - version = { major = 9, minor = 0, patch = 0, rc = 8 }, + version = { major = 9, minor = 0, patch = 0, rc = 9 }, -- Loaders Start = Start, @@ -165,8 +174,5 @@ return table.freeze({ -- Constructors New = New, - Worker = Worker, - - -- Callbacks - OnStart = OnStart, + Cycle = Cycle, }) diff --git a/wally.toml b/wally.toml index 57a973bf..db418ab1 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "lumin/framework" description = "A lightning fast & amazing game framework for Roblox" -version = "9.0.0-rc8" +version = "9.0.0-rc9" license = "MIT" registry = "https://github.com/UpliftGames/wally-index" realm = "shared" @@ -11,7 +11,7 @@ debugger = "lumin/debugger@^0.3.0" spawn = "red-blox/spawn@^1.0.0" [dev-dependencies] -net = "lumin/net@0.1.0" +net = "lumin/net@0.4.1" signal = "sleitnick/signal@2.0.1" [place]