From ba336fb0e4cb107d48a63d8fb29d82bbd8b828e2 Mon Sep 17 00:00:00 2001 From: James <119134081+2jammers@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:47:58 -0600 Subject: [PATCH] working springs --- .gitignore | 13 +- default.project.json | 6 - dev.project.json | 21 ++- pesde.toml | 23 +++ rokit.toml | 10 -- src/Animation/Spring.luau | 147 ++---------------- src/Instances/New.luau | 2 +- src/Keys/Change.luau | 4 +- src/Keys/Clean.luau | 4 +- src/Keys/Event.luau | 4 +- src/Keys/{List.luau => KeyList.luau} | 0 src/Keys/Tag.luau | 2 +- src/Runtime/Scheduler.luau | 40 ----- src/State/Compute.luau | 2 +- src/State/State.luau | 2 +- src/Types.luau | 17 +- src/Utility.luau | 9 +- src/init.luau | 2 +- tests/{Client => client}/UI.client.luau | 9 +- .../components/Background.luau | 4 +- tests/{Client => client}/useTheme.luau | 0 tests/{Server => server}/Test.server.luau | 0 tests/{Shared => shared}/Theme.luau | 0 wally.toml | 10 -- 24 files changed, 82 insertions(+), 249 deletions(-) delete mode 100644 default.project.json create mode 100644 pesde.toml delete mode 100644 rokit.toml rename src/Keys/{List.luau => KeyList.luau} (100%) delete mode 100644 src/Runtime/Scheduler.luau rename tests/{Client => client}/UI.client.luau (82%) rename tests/{Client => client}/components/Background.luau (84%) rename tests/{Client => client}/useTheme.luau (100%) rename tests/{Server => server}/Test.server.luau (100%) rename tests/{Shared => shared}/Theme.luau (100%) delete mode 100644 wally.toml diff --git a/.gitignore b/.gitignore index a04dfee..67ed5eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,9 @@ -# Mkdocs -venv - -# Wally -Packages -DevPackages -wally.lock +# Pesde +.pesde +roblox_packages +lune_packages +luau_packages +pesde.lock # Rojo sourcemap.json diff --git a/default.project.json b/default.project.json deleted file mode 100644 index a3683fd..0000000 --- a/default.project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ui-framework", - "tree": { - "$path": "src" - } -} diff --git a/dev.project.json b/dev.project.json index 2d94d48..4a382bc 100644 --- a/dev.project.json +++ b/dev.project.json @@ -4,14 +4,23 @@ "tree": { "$className": "DataModel", "ReplicatedStorage": { - "Packages": { - "$path": "Packages", - "ui-framework": { + "ui-framework": { + "$className": "Folder", + "src": { "$path": "src" - } + }, + "roblox_packages": { + "$path": "roblox_packages" + } }, - "Tests": { - "$path": "tests" + "tests": { + "$className": "Folder", + "Client": { + "$path": "tests/client" + }, + "Server": { + "$path": "tests/server" + } } } } diff --git a/pesde.toml b/pesde.toml new file mode 100644 index 0000000..cd5ec64 --- /dev/null +++ b/pesde.toml @@ -0,0 +1,23 @@ +name = "lumin/uiframework" +version = "0.1.0" +description = "A lightweight and embeddable UI framework" +authors = ["2jammers"] +repository = "https://github.com/luminlabsdev/ui-framework" +license = "MIT" + +[target] +environment = "roblox" + +[indices] +default = "https://github.com/daimond113/pesde-index" + +[scripts] +roblox_sync_config_generator = ".pesde/scripts/roblox_sync_config_generator.luau" +sourcemap_generator = ".pesde/scripts/sourcemap_generator.luau" + +[dev_dependencies] +scripts = { name = "pesde/scripts_rojo", version = "^0.1.0", target = "lune" } +rojo = { name = "pesde/rojo", version = "^7.4.4", target = "lune" } + +[dependencies] +debugger = { name = "lumin/debugger", version = "^0.5.0" } diff --git a/rokit.toml b/rokit.toml deleted file mode 100644 index 47eb615..0000000 --- a/rokit.toml +++ /dev/null @@ -1,10 +0,0 @@ -# This file lists tools managed by Rokit, a toolchain manager for Roblox projects. -# For more information, see https://github.com/rojo-rbx/rokit - -# New tools can be added by running `rokit add ` in a terminal. - -[tools] -wally = "UpliftGames/wally@0.3.2" -wally-package-types = "johnnymorganz/wally-package-types@1.3.2" -stylua = "johnnymorganz/stylua@0.20.0" -rojo = "rojo-rbx/rojo@7.4.4" diff --git a/src/Animation/Spring.luau b/src/Animation/Spring.luau index a413000..df7cd5b 100644 --- a/src/Animation/Spring.luau +++ b/src/Animation/Spring.luau @@ -1,148 +1,34 @@ --- Forked from dervexdev/advancedspring -- Variables local Root = script.Parent.Parent -local Packages = script.Parent.Parent.Parent.Parent.Packages - -local RunService = game:GetService("RunService") - -local Runtime = Root.Runtime -local Scheduler = require(Runtime.Scheduler) -local Storage = require(Runtime.Storage) +local Packages = script.Parent.Parent.Parent.roblox_packages local Debugger = require(Packages.debugger) local Utils = require(Root.Utility) local Is = require(Root.Is) local Types = require(Root.Types) -local Spring = require(script.Parent.Spr) +local Spr = require(script.Parent.Spr) local Class = {} -local Epsilon = 1e-4 - -local sqrt = math.sqrt -local exp = math.exp -local cos = math.cos -local sin = math.sin -local pi = math.pi - -- Functions -local function IsSpringSettled(currentLinearPosition: { number }, targetLinearPosition: { number }): boolean - for index, value in currentLinearPosition do - if math.abs(value - targetLinearPosition[index]) > Epsilon then - -- If the difference is more than the epsilon, then return false - return false - end - end - - return true -end function Class._Bind(self: Types.Spring, prop: string, instance: Instance) - local Mode = RunService:IsClient() and "Client" or "Server" - local Connection: ((number) -> ())? - - local TargetLinearPosition = self._DataType.ToLinear((self._State :: any):Get()) - local CurrentValue = (self._State :: any):Get() - - if CurrentValue ~= nil then - (instance :: any)[prop] = CurrentValue - end - self._CurrentLinearPosition = TargetLinearPosition -; - (self._State :: any):Listen(function(newValue) - TargetLinearPosition = self._DataType.ToLinear(newValue) - - if Connection ~= nil then - return -- The value changed when the spring was playing; don't create another connection, let the new one play - end - - if not Connection then - Connection = Scheduler:Add(Mode, function(delta: number) - if self and (self :: any)._Update then - (self :: any):_Update(TargetLinearPosition, delta); - (instance :: any)[prop] = self._DataType.FromLinear(self._CurrentLinearPosition) - else - if Connection then - Scheduler:Remove(Mode, Connection) - return - end - end - - if IsSpringSettled(self._CurrentLinearPosition, TargetLinearPosition) == true and Connection then - Scheduler:Remove(Mode, Connection) - Connection = nil; - (instance :: any)[prop] = (self :: any)._State:Get() - - for index = 1, #self._Velocity do - self._Velocity[index] = 0 - end - end - end) - end - end) -end - -function Class._Update(self: Types.Spring, targetLinearPosition: { number }, delta: number) - for index = 1, #targetLinearPosition do - -- DO NOT CHANGE ANYTHING IN THE CALCULATION UNLESS YOU KNOW WHAT YOU ARE DOING - --[[ - d = damping - f = frequency - v = velocity - c = constant - i = cosine_angle - j = sine_angle - r1 = root1 - r2 = root2 - c2 = coefficient2 - c1 = coefficient1 - e1 = exp1 - e2 = exp2 - ]] - - local d = self._Damping - local f = self._Frequency * pi * 2 - local g = targetLinearPosition[index] - local p = self._CurrentLinearPosition[index] - local v = self._Velocity[index] - - local offset = p - g - local decay = exp(-delta * d * f) - - if d == 1 then - self._CurrentLinearPosition[index] = (v * delta + offset * (f * delta + 1)) * decay + g - self._Velocity[index] = (v - (offset * f + v) * (f * delta)) * decay - elseif d < 1 then - local c = sqrt(1 - d * d) - local i = cos(delta * f * c) - local j = sin(delta * f * c) - - self._CurrentLinearPosition[index] = (offset * i + (v + offset * (d * f)) * j / (f * c)) * decay + g - self._Velocity[index] = (v * (i * c) - (v * d + offset * f) * j) * (decay / c) - else - local c = sqrt(d * d - 1) - local r1 = -f * (d - c) - local r2 = -f * (d + c) - local co2 = (v - offset * r1) / (2 * f * c) - local co1 = offset - co2 - local e1 = co1 * exp(r1 * delta) - local e2 = co2 * exp(r2 * delta) - - self._CurrentLinearPosition[index] = e1 + e2 + g - self._Velocity[index] = r1 * e1 + r2 * e2 - end - end + (instance :: any)[prop] = self._Goal:Get() + self._Goal:Listen(function(new) + Spr.target(instance, self._Damping, self._Frequency, { + [prop] = new + }) + end) end --[[ - Gets the end goal of the spring object. + Gets the current value that the spring is moving. [Learn More](https://luminlabsdev.github.io/ui-framework/api/spring/#get) ]] function Class.Get(self: Types.Spring): Types.Animatable - -- Return the unpacked format for improved clarity - return self._DataType.FromLinear(self._CurrentLinearPosition) + return 1 end --[[ @@ -151,31 +37,24 @@ end [Learn More](https://luminlabsdev.github.io/ui-framework/api/spring/#destroy) ]] function Class.Destroy(self: Types.Spring) - (self :: any)._State:Destroy() + (self :: any)._Goal:Destroy() Utils.CleanMetatable(self :: any) end --[=[ - Creates a new spring with a set goal. + Creates a new spring with a set goal. Can be used in place of a tween. [Learn More](https://luminlabsdev.github.io/ui-framework/api/#spring) ]=] return function(goal: Types.State, damping: number?, frequency: number?): Types.SpringExport Debugger.Assert(Is.Constructor(goal :: any), "InvalidType", "State", type(goal)) - local Type = Storage.AnimatableDataTypes[typeof((goal :: any):Get())] - Debugger.Assert(Type, "NotAnimatable", type((goal :: any):Get())) local self = setmetatable({}, { __index = Class }) self._Type = "spring" self._Damping = damping or 1 self._Frequency = frequency or 1 - self._State = goal - - self._DataType = Type - self._CurrentLinearPosition = Type.ToLinear((goal :: any):Get()) - - self._Velocity = table.create(#self._CurrentLinearPosition, 0) + self._Goal = goal return self :: any end diff --git a/src/Instances/New.luau b/src/Instances/New.luau index ffa45cd..f4dde44 100644 --- a/src/Instances/New.luau +++ b/src/Instances/New.luau @@ -3,7 +3,7 @@ local Root = script.Parent.Parent local Utility = require(Root.Utility) local Types = require(Root.Types) -local Debugger = require(Root.Parent.debugger) +local Debugger = require(Root.Parent.roblox_packages.debugger) local Default = require(Root.Instances.Default) -- Module diff --git a/src/Keys/Change.luau b/src/Keys/Change.luau index 0502444..7ece6ee 100644 --- a/src/Keys/Change.luau +++ b/src/Keys/Change.luau @@ -1,7 +1,7 @@ -- Variables local Root = script.Parent.Parent -local Keys = require(script.Parent.List) -local Debugger = require(Root.Parent.debugger) +local Keys = require(script.Parent.KeyList) +local Debugger = require(Root.Parent.roblox_packages.debugger) -- Module diff --git a/src/Keys/Clean.luau b/src/Keys/Clean.luau index 61298d2..a4226f5 100644 --- a/src/Keys/Clean.luau +++ b/src/Keys/Clean.luau @@ -1,8 +1,8 @@ -- Variables local Root = script.Parent.Parent -local Keys = require(script.Parent.List) +local Keys = require(script.Parent.KeyList) local Is = require(Root.Is) -local Debugger = require(Root.Parent.debugger) +local Debugger = require(Root.Parent.roblox_packages.debugger) -- Module diff --git a/src/Keys/Event.luau b/src/Keys/Event.luau index 994590a..2afb784 100644 --- a/src/Keys/Event.luau +++ b/src/Keys/Event.luau @@ -1,7 +1,7 @@ -- Variables local Root = script.Parent.Parent -local Keys = require(script.Parent.List) -local Debugger = require(Root.Parent.debugger) +local Keys = require(script.Parent.KeyList) +local Debugger = require(Root.Parent.roblox_packages.debugger) -- Functions local function Find(instance: Instance, property: string) diff --git a/src/Keys/List.luau b/src/Keys/KeyList.luau similarity index 100% rename from src/Keys/List.luau rename to src/Keys/KeyList.luau diff --git a/src/Keys/Tag.luau b/src/Keys/Tag.luau index 79c9f5d..f240427 100644 --- a/src/Keys/Tag.luau +++ b/src/Keys/Tag.luau @@ -1,5 +1,5 @@ -- Variables -local Keys = require(script.Parent.List) +local Keys = require(script.Parent.KeyList) -- Module diff --git a/src/Runtime/Scheduler.luau b/src/Runtime/Scheduler.luau deleted file mode 100644 index 3796d6c..0000000 --- a/src/Runtime/Scheduler.luau +++ /dev/null @@ -1,40 +0,0 @@ --- Variables -local RunService = game:GetService("RunService") -local Storage = require(script.Parent.Storage) -local Scheduler = {} - --- Functions -function Scheduler:Add(to: string, taskFn: (deltaTime: number) -> ()) - local Tab = Storage.Scheduler[to] - - table.insert(Tab.Active, taskFn) - - if not Tab.Connection then - Tab.Connection = (RunService[if to == "Client" then "RenderStepped" else "Heartbeat"] :: RBXScriptSignal):Connect( - function(deltaTime) - for _, taskFunc in Tab.Active do - taskFunc(deltaTime) - end - end - ) - end - - return taskFn -end - -function Scheduler:Remove(from: string, taskFn: (deltaTime: number) -> ()) - local Tab = Storage.Scheduler[from] - local index = table.find(Tab.Active, taskFn) - - if index then - table.remove(Tab.Active, index) - - if #Tab.Active == 0 and Tab.Connection then - Tab.Connection:Disconnect() - Tab.Connection = nil - end - end -end - --- Module -return Scheduler diff --git a/src/State/Compute.luau b/src/State/Compute.luau index e0d7f86..990db52 100644 --- a/src/State/Compute.luau +++ b/src/State/Compute.luau @@ -1,6 +1,6 @@ -- Variables local Root = script.Parent.Parent -local Debugger = require(Root.Parent.debugger) +local Debugger = require(Root.Parent.roblox_packages.debugger) local Utility = require(Root.Utility) local Is = require(Root.Is) local Types = require(Root.Types) diff --git a/src/State/State.luau b/src/State/State.luau index a4c9bc4..19a26f0 100644 --- a/src/State/State.luau +++ b/src/State/State.luau @@ -2,7 +2,7 @@ local Root = script.Parent.Parent local Types = require(Root.Types) local Utility = require(Root.Utility) -local Debugger = require(Root.Parent.debugger) +local Debugger = require(Root.Parent.roblox_packages.debugger) local Class = {} diff --git a/src/Types.luau b/src/Types.luau index 3c8bf79..8597c02 100644 --- a/src/Types.luau +++ b/src/Types.luau @@ -53,28 +53,13 @@ export type SpringExport = { export type Spring = typeof(setmetatable( {} :: { _Type: "spring", - _State: State, + _Goal: StateExport, _Damping: number, _Frequency: number, - _Velocity: { number }, - _CurrentLinearPosition: { number }, - _DataType: { - ToLinear: (value: Animatable) -> { number }, - FromLinear: (value: { number }) -> Animatable, - }, }, {} :: { __index: SpringExport } )) -export type TweenExport = {} & Constructor - -export type Tween = typeof(setmetatable( - {} :: { - _Type: "tween", - }, - {} :: { __index: TweenExport } -)) - export type ComputeExport = Constructor export type Compute = typeof(setmetatable( diff --git a/src/Utility.luau b/src/Utility.luau index f2edd2a..f1b7b56 100644 --- a/src/Utility.luau +++ b/src/Utility.luau @@ -1,6 +1,6 @@ -- Variables local Root = script.Parent -local Debugger = require(Root.Parent.debugger) +local Debugger = require(Root.Parent.roblox_packages.debugger) local Storage = require(Root.Runtime.Storage) local Types = require(Root.Types) local Is = require(Root.Is) @@ -35,9 +35,10 @@ local function ApplyConstructorProperty(instance: Instance, prop: string, value: local Property = (instance :: any)[prop] -- Call the _bind method of the Service. - CheckTypeAndCall(Property, value:Get(), function() - (value :: Types.Constructor):_Bind(prop, instance) - end) + ;(value :: Types.Constructor):_Bind(prop, instance) + -- CheckTypeAndCall(Property, value:Get(), function() + -- (value :: Types.Constructor):_Bind(prop, instance) + -- end) end local function ApplyNormalProperty(instance: Instance, prop: string, value: any) diff --git a/src/init.luau b/src/init.luau index 44257a1..23b9b54 100644 --- a/src/init.luau +++ b/src/init.luau @@ -1,5 +1,5 @@ -- Variables -local Packages = script.Parent +local Packages = script.Parent.roblox_packages local Instances = script.Instances local Animation = script.Animation local State = script.State diff --git a/tests/Client/UI.client.luau b/tests/client/UI.client.luau similarity index 82% rename from tests/Client/UI.client.luau rename to tests/client/UI.client.luau index 557be5a..33a9d21 100644 --- a/tests/Client/UI.client.luau +++ b/tests/client/UI.client.luau @@ -3,16 +3,18 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") -- FOLDERS > -local Packages = ReplicatedStorage.Packages +local Package = ReplicatedStorage["ui-framework"] -- DEPENDENCIES > -local Framework = require(Packages["ui-framework"]) +local Framework = require(Package.src) local MyComponent = require(script.Parent.components.Background) -- VARIABLES > local Player = Players.LocalPlayer local New = Framework.New local State = Framework.State("Hello") +local Goal = Framework.State(UDim2.fromScale(0.5, 1)) +local Spring = Framework.Spring(Goal :: any, 0.5, 5) local c = 1 -- UI @@ -29,7 +31,7 @@ New("ScreenGui", { }), ComponentBackgroundChildren = New(MyComponent, { Color = Color3.fromRGB(151, 71, 71), - Position = UDim2.fromScale(0.5, 0.9), + Position = Spring :: any, }, { New("TextLabel", { Text = State, @@ -46,6 +48,7 @@ New("ScreenGui", { [Framework.Event "Activated"] = function() c+=1 State:Set(`Hello {c}`) + Goal:Set(UDim2.fromScale(0.5, if c%2 == 0 then 1 else 1.5)) end, [Framework.Change "Name"] = function(new_name: any) diff --git a/tests/Client/components/Background.luau b/tests/client/components/Background.luau similarity index 84% rename from tests/Client/components/Background.luau rename to tests/client/components/Background.luau index 7150bf8..295c15f 100644 --- a/tests/Client/components/Background.luau +++ b/tests/client/components/Background.luau @@ -2,10 +2,10 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") -- FOLDERS > -local Packages = ReplicatedStorage.Packages +local Package = ReplicatedStorage["ui-framework"] -- DEPENDENCIES > -local Framework = require(Packages["ui-framework"]) +local Framework = require(Package.src) -- VARIABLES > local New = Framework.New diff --git a/tests/Client/useTheme.luau b/tests/client/useTheme.luau similarity index 100% rename from tests/Client/useTheme.luau rename to tests/client/useTheme.luau diff --git a/tests/Server/Test.server.luau b/tests/server/Test.server.luau similarity index 100% rename from tests/Server/Test.server.luau rename to tests/server/Test.server.luau diff --git a/tests/Shared/Theme.luau b/tests/shared/Theme.luau similarity index 100% rename from tests/Shared/Theme.luau rename to tests/shared/Theme.luau diff --git a/wally.toml b/wally.toml deleted file mode 100644 index 1a99e74..0000000 --- a/wally.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "lumin/ui-framework" -description = "A lightweight and embeddable UI framework" -version = "0.3.0" -license = "MIT" -realm = "shared" -registry = "https://github.com/UpliftGames/wally-index" - -[dependencies] -debugger = "lumin/debugger@^0.4.0"