@rbxts/app-forge 0.7.1 → 0.7.2-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -13
- package/out/react/hooks/usePx.d.ts +15 -0
- package/out/react/hooks/usePx.luau +117 -0
- package/out/vide/classes/renders.d.ts +4 -0
- package/out/vide/classes/renders.luau +49 -45
- package/out/vide/classes/rules/exclusiveGroup.luau +22 -15
- package/out/vide/classes/rules/init.luau +17 -13
- package/out/vide/classes/rules/parent.luau +9 -4
- package/out/vide/context.d.ts +1 -1
- package/out/vide/debug/debugger.d.ts +18 -0
- package/out/vide/debug/debugger.luau +89 -0
- package/out/vide/debug/index.d.ts +3 -0
- package/out/vide/debug/init.luau +8 -0
- package/out/vide/debug/logger.d.ts +5 -0
- package/out/vide/debug/logger.luau +37 -0
- package/out/vide/decorator.d.ts +8 -0
- package/out/vide/decorator.luau +35 -4
- package/out/vide/hooks/useAppContext.d.ts +1 -1
- package/out/vide/hooks/useAppContext.luau +5 -1
- package/out/vide/hooks/useEventListener.d.ts +17 -0
- package/out/vide/hooks/useEventListener.luau +61 -0
- package/out/vide/hooks/usePx.d.ts +11 -0
- package/out/vide/hooks/usePx.luau +98 -0
- package/out/vide/index.d.ts +5 -2
- package/out/vide/init.luau +102 -25
- package/out/vide/types.d.ts +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
-- debug/logger.ts
|
|
4
|
+
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
5
|
+
local Logger
|
|
6
|
+
do
|
|
7
|
+
Logger = setmetatable({}, {
|
|
8
|
+
__tostring = function()
|
|
9
|
+
return "Logger"
|
|
10
|
+
end,
|
|
11
|
+
})
|
|
12
|
+
Logger.__index = Logger
|
|
13
|
+
function Logger.new(...)
|
|
14
|
+
local self = setmetatable({}, Logger)
|
|
15
|
+
return self:constructor(...) or self
|
|
16
|
+
end
|
|
17
|
+
function Logger:constructor(scope)
|
|
18
|
+
self.scope = scope
|
|
19
|
+
end
|
|
20
|
+
function Logger:log(level, message, data, traceback)
|
|
21
|
+
if not RunService:IsStudio() then
|
|
22
|
+
return nil
|
|
23
|
+
end
|
|
24
|
+
local prefix = `[{self.scope}][{level}]`
|
|
25
|
+
if data ~= nil then
|
|
26
|
+
print(prefix, message, data)
|
|
27
|
+
else
|
|
28
|
+
print(prefix, message)
|
|
29
|
+
end
|
|
30
|
+
if traceback ~= "" and traceback then
|
|
31
|
+
print(traceback)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
return {
|
|
36
|
+
default = Logger,
|
|
37
|
+
}
|
package/out/vide/decorator.d.ts
CHANGED
|
@@ -2,7 +2,15 @@ import Vide from "@rbxts/vide";
|
|
|
2
2
|
import type Types from "./types";
|
|
3
3
|
import type AppForge from ".";
|
|
4
4
|
export declare const AppRegistry: Map<string, Types.AppRegistry.Static>;
|
|
5
|
+
/**
|
|
6
|
+
* Registers a Vide App with AppForge.
|
|
7
|
+
*
|
|
8
|
+
* This runs at definition time and validates static configuration.
|
|
9
|
+
*/
|
|
5
10
|
export declare function App<N extends AppNames>(props: Types.AppRegistry.Props<N>): <T extends new (props: Types.Props.Main, name: AppNames) => Args>(constructor: T) => T;
|
|
11
|
+
/**
|
|
12
|
+
* Base class for all AppForge Apps.
|
|
13
|
+
*/
|
|
6
14
|
export declare abstract class Args {
|
|
7
15
|
readonly forge: AppForge;
|
|
8
16
|
readonly props: Types.Props.Class;
|
package/out/vide/decorator.luau
CHANGED
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v3.0.0
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
-- Packages
|
|
4
|
-
local px = TS.import(script, TS.getModule(script, "@rbxts", "loners-pretty-vide-utils").out).px
|
|
5
4
|
-- Types
|
|
5
|
+
-- Hooks
|
|
6
|
+
local px = TS.import(script, script.Parent, "hooks", "usePx").px
|
|
7
|
+
-- Debug
|
|
8
|
+
local Logger = TS.import(script, script.Parent, "debug", "logger").default
|
|
9
|
+
local logger = Logger.new("AppRegistry")
|
|
6
10
|
local AppRegistry = {}
|
|
11
|
+
--[[
|
|
12
|
+
*
|
|
13
|
+
* Registers a Vide App with AppForge.
|
|
14
|
+
*
|
|
15
|
+
* This runs at definition time and validates static configuration.
|
|
16
|
+
|
|
17
|
+
]]
|
|
7
18
|
local function App(props)
|
|
8
19
|
return function(constructor)
|
|
9
20
|
local _name = props.name
|
|
10
21
|
if AppRegistry[_name] ~= nil then
|
|
11
|
-
|
|
22
|
+
logger:log("ERROR", "Duplicate App name detected", {
|
|
23
|
+
name = props.name,
|
|
24
|
+
})
|
|
25
|
+
error(`Duplicate registered App name "{props.name}". ` .. `App names must be globally unique.`, 2)
|
|
26
|
+
end
|
|
27
|
+
local _value = props.name
|
|
28
|
+
if not (_value ~= "" and _value) then
|
|
29
|
+
logger:log("ERROR", "Attempted to register App without a name", props)
|
|
30
|
+
error("App registration failed: missing app name", 2)
|
|
12
31
|
end
|
|
13
32
|
local _name_1 = props.name
|
|
14
33
|
local _arg1 = {
|
|
@@ -21,6 +40,11 @@ local function App(props)
|
|
|
21
40
|
return constructor
|
|
22
41
|
end
|
|
23
42
|
end
|
|
43
|
+
--[[
|
|
44
|
+
*
|
|
45
|
+
* Base class for all AppForge Apps.
|
|
46
|
+
|
|
47
|
+
]]
|
|
24
48
|
local Args
|
|
25
49
|
do
|
|
26
50
|
Args = {}
|
|
@@ -28,13 +52,20 @@ do
|
|
|
28
52
|
local _binding = props
|
|
29
53
|
local forge = _binding.forge
|
|
30
54
|
self.forge = forge
|
|
55
|
+
self.name = name
|
|
31
56
|
local _object = table.clone(props.props)
|
|
32
57
|
setmetatable(_object, nil)
|
|
33
58
|
_object.px = px
|
|
34
59
|
_object.forge = forge
|
|
35
60
|
self.props = _object
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
local src = forge:getSource(name)
|
|
62
|
+
if not src then
|
|
63
|
+
logger:log("ERROR", "Missing visibility source for App", {
|
|
64
|
+
name = name,
|
|
65
|
+
})
|
|
66
|
+
error(`Failed to retrieve visibility source for app "{name}"`, 2)
|
|
67
|
+
end
|
|
68
|
+
self.source = src
|
|
38
69
|
end
|
|
39
70
|
end
|
|
40
71
|
return {
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
local TS = _G[script]
|
|
3
3
|
-- Components
|
|
4
4
|
local Contexts = TS.import(script, script.Parent.Parent, "context").default
|
|
5
|
+
-- Debug
|
|
6
|
+
local Logger = TS.import(script, script.Parent.Parent, "debug", "logger").default
|
|
7
|
+
local logger = Logger.new("useAppContext")
|
|
5
8
|
local default = function()
|
|
6
9
|
local context = Contexts.App()
|
|
7
10
|
if not context then
|
|
8
|
-
|
|
11
|
+
logger:log("ERROR", "Failed to retrieve App context")
|
|
12
|
+
error(`Failed to retrieve App Props for Vide\n{debug.traceback()}`, 2)
|
|
9
13
|
end
|
|
10
14
|
return context
|
|
11
15
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type EventLike<T extends Callback = Callback> = {
|
|
2
|
+
Connect(callback: T): ConnectionLike;
|
|
3
|
+
} | {
|
|
4
|
+
connect(callback: T): ConnectionLike;
|
|
5
|
+
} | {
|
|
6
|
+
subscribe(callback: T): ConnectionLike;
|
|
7
|
+
};
|
|
8
|
+
type ConnectionLike = {
|
|
9
|
+
Disconnect(): void;
|
|
10
|
+
} | {
|
|
11
|
+
disconnect(): void;
|
|
12
|
+
} | (() => void);
|
|
13
|
+
/**
|
|
14
|
+
* Subscribes to an event-like object and auto-cleans up.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useEventListener<T extends EventLike>(event: T, listener: T extends EventLike<infer U> ? U : never): ReturnType<T>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local cleanup = TS.import(script, TS.getModule(script, "@rbxts", "vide").src).cleanup
|
|
4
|
+
-- Debug
|
|
5
|
+
local Logger = TS.import(script, script.Parent.Parent, "debug", "logger").default
|
|
6
|
+
local logger = Logger.new("useEventListener")
|
|
7
|
+
local connect = function(event, callback)
|
|
8
|
+
local _event = event
|
|
9
|
+
if typeof(_event) == "RBXScriptSignal" then
|
|
10
|
+
local connection
|
|
11
|
+
connection = event:Connect(function(...)
|
|
12
|
+
local args = { ... }
|
|
13
|
+
if connection.Connected then
|
|
14
|
+
return callback(unpack(args))
|
|
15
|
+
end
|
|
16
|
+
end)
|
|
17
|
+
return connection
|
|
18
|
+
elseif event.Connect ~= nil then
|
|
19
|
+
return event:Connect(callback)
|
|
20
|
+
elseif event.connect ~= nil then
|
|
21
|
+
return event:connect(callback)
|
|
22
|
+
elseif event.subscribe ~= nil then
|
|
23
|
+
return event:subscribe(callback)
|
|
24
|
+
end
|
|
25
|
+
logger:log("ERROR", "Unsupported event-like object", event)
|
|
26
|
+
error("Event-like object does not have a supported connect method.", 2)
|
|
27
|
+
end
|
|
28
|
+
local disconnect = function(connection)
|
|
29
|
+
local _connection = connection
|
|
30
|
+
if type(_connection) == "function" then
|
|
31
|
+
connection()
|
|
32
|
+
else
|
|
33
|
+
local _connection_1 = connection
|
|
34
|
+
local _condition = typeof(_connection_1) == "RBXScriptConnection"
|
|
35
|
+
if not _condition then
|
|
36
|
+
_condition = connection.Disconnect ~= nil
|
|
37
|
+
end
|
|
38
|
+
if _condition then
|
|
39
|
+
connection:Disconnect()
|
|
40
|
+
elseif connection.disconnect ~= nil then
|
|
41
|
+
connection:disconnect()
|
|
42
|
+
else
|
|
43
|
+
logger:log("WARN", "Unsupported connection-like object during cleanup", connection)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
--[[
|
|
48
|
+
*
|
|
49
|
+
* Subscribes to an event-like object and auto-cleans up.
|
|
50
|
+
|
|
51
|
+
]]
|
|
52
|
+
local function useEventListener(event, listener)
|
|
53
|
+
local connection = connect(event, listener)
|
|
54
|
+
cleanup(function()
|
|
55
|
+
return disconnect(connection)
|
|
56
|
+
end)
|
|
57
|
+
return connection
|
|
58
|
+
end
|
|
59
|
+
return {
|
|
60
|
+
useEventListener = useEventListener,
|
|
61
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const px: ((value: number) => number) & {
|
|
2
|
+
scale: (value: number) => number;
|
|
3
|
+
even: (value: number) => number;
|
|
4
|
+
floor: (value: number) => number;
|
|
5
|
+
ceil: (value: number) => number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Initializes global px scaling.
|
|
9
|
+
* Must be called exactly once.
|
|
10
|
+
*/
|
|
11
|
+
export declare function usePx(target?: GuiObject | Camera, baseResolution?: Vector2, minScale?: number): void;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
-- Services
|
|
4
|
+
local Workspace = TS.import(script, TS.getModule(script, "@rbxts", "services")).Workspace
|
|
5
|
+
-- Packages
|
|
6
|
+
local source = TS.import(script, TS.getModule(script, "@rbxts", "vide").src).source
|
|
7
|
+
-- Helpers
|
|
8
|
+
local useEventListener = TS.import(script, script.Parent, "useEventListener").useEventListener
|
|
9
|
+
-- Debug
|
|
10
|
+
local Logger = TS.import(script, script.Parent.Parent, "debug", "logger").default
|
|
11
|
+
local logger = Logger.new("usePx")
|
|
12
|
+
--* Default reference resolution for px calculations
|
|
13
|
+
local BASE_RESOLUTION = source(Vector2.new(1920, 1080))
|
|
14
|
+
--* Minimum allowed scale to prevent unreadable UI
|
|
15
|
+
local MIN_SCALE = source(0.5)
|
|
16
|
+
--* 0 = width-based, 1 = height-based
|
|
17
|
+
local DOMINANT_AXIS = 0.5
|
|
18
|
+
local TARGET = source(Workspace.CurrentCamera)
|
|
19
|
+
local SCALE = source(1)
|
|
20
|
+
local INITIALIZED = false
|
|
21
|
+
local function callable(callback, object)
|
|
22
|
+
return setmetatable(object, {
|
|
23
|
+
__call = function(_, ...)
|
|
24
|
+
local args = { ... }
|
|
25
|
+
return callback(unpack(args))
|
|
26
|
+
end,
|
|
27
|
+
})
|
|
28
|
+
end
|
|
29
|
+
local px = callable(function(value)
|
|
30
|
+
return math.round(value * SCALE())
|
|
31
|
+
end, {
|
|
32
|
+
scale = function(value)
|
|
33
|
+
return value * SCALE()
|
|
34
|
+
end,
|
|
35
|
+
even = function(value)
|
|
36
|
+
return math.round(value * SCALE() * 0.5) * 2
|
|
37
|
+
end,
|
|
38
|
+
floor = function(value)
|
|
39
|
+
return math.floor(value * SCALE())
|
|
40
|
+
end,
|
|
41
|
+
ceil = function(value)
|
|
42
|
+
return math.ceil(value * SCALE())
|
|
43
|
+
end,
|
|
44
|
+
})
|
|
45
|
+
local function calculateScale()
|
|
46
|
+
local target = TARGET()
|
|
47
|
+
if not target then
|
|
48
|
+
return nil
|
|
49
|
+
end
|
|
50
|
+
local size = if target:IsA("Camera") then target.ViewportSize elseif target:IsA("GuiObject") then target.AbsoluteSize else nil
|
|
51
|
+
if not size then
|
|
52
|
+
return nil
|
|
53
|
+
end
|
|
54
|
+
local res = BASE_RESOLUTION()
|
|
55
|
+
if res.X <= 0 or res.Y <= 0 then
|
|
56
|
+
return nil
|
|
57
|
+
end
|
|
58
|
+
local min = MIN_SCALE()
|
|
59
|
+
local width = math.log(size.X / res.X, 2)
|
|
60
|
+
local height = math.log(size.Y / res.Y, 2)
|
|
61
|
+
local centered = width + (height - width) * DOMINANT_AXIS
|
|
62
|
+
local scale = 2 ^ centered
|
|
63
|
+
SCALE(math.max(scale, min))
|
|
64
|
+
end
|
|
65
|
+
--[[
|
|
66
|
+
*
|
|
67
|
+
* Initializes global px scaling.
|
|
68
|
+
* Must be called exactly once.
|
|
69
|
+
|
|
70
|
+
]]
|
|
71
|
+
local function usePx(target, baseResolution, minScale)
|
|
72
|
+
if INITIALIZED then
|
|
73
|
+
logger:log("WARN", "usePx() called more than once")
|
|
74
|
+
return nil
|
|
75
|
+
end
|
|
76
|
+
INITIALIZED = true
|
|
77
|
+
if baseResolution then
|
|
78
|
+
BASE_RESOLUTION(baseResolution)
|
|
79
|
+
end
|
|
80
|
+
if minScale ~= nil then
|
|
81
|
+
MIN_SCALE(minScale)
|
|
82
|
+
end
|
|
83
|
+
if target then
|
|
84
|
+
TARGET(target)
|
|
85
|
+
end
|
|
86
|
+
local resolvedTarget = TARGET()
|
|
87
|
+
if not resolvedTarget then
|
|
88
|
+
logger:log("WARN", "usePx(): no valid target to observe")
|
|
89
|
+
return nil
|
|
90
|
+
end
|
|
91
|
+
local signal = if resolvedTarget:IsA("Camera") then resolvedTarget:GetPropertyChangedSignal("ViewportSize") else resolvedTarget:GetPropertyChangedSignal("AbsoluteSize")
|
|
92
|
+
useEventListener(signal, calculateScale)
|
|
93
|
+
calculateScale()
|
|
94
|
+
end
|
|
95
|
+
return {
|
|
96
|
+
usePx = usePx,
|
|
97
|
+
px = px,
|
|
98
|
+
}
|
package/out/vide/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Vide from "@rbxts/vide";
|
|
2
2
|
import Renders from "./classes/renders";
|
|
3
3
|
import Types from "./types";
|
|
4
|
+
import { Logger, Debugger } from "./debug";
|
|
4
5
|
type Destructor = () => void;
|
|
5
6
|
type Loaded = {
|
|
6
7
|
container: Vide.Node;
|
|
@@ -8,17 +9,19 @@ type Loaded = {
|
|
|
8
9
|
anchor?: Vide.Node;
|
|
9
10
|
};
|
|
10
11
|
export default class AppForge extends Renders {
|
|
12
|
+
readonly logger: Logger;
|
|
13
|
+
readonly debug: Debugger;
|
|
11
14
|
protected sources: Map<string, Vide.Source<boolean>>;
|
|
12
15
|
protected loaded: Map<string, Loaded>;
|
|
13
16
|
protected innerMount?: Destructor;
|
|
14
17
|
protected __px: boolean;
|
|
15
18
|
constructor();
|
|
16
|
-
protected createSource(name: AppNames):
|
|
19
|
+
protected createSource(name: AppNames): void;
|
|
20
|
+
getSource(name: AppNames): Vide.Source<boolean>;
|
|
17
21
|
isLoaded(name: AppNames): boolean;
|
|
18
22
|
bind(name: AppNames, value: Vide.Source<boolean>): void;
|
|
19
23
|
anchor(name: AppNames, anchorName: AppNames, props: Types.Props.Main): void;
|
|
20
24
|
index(name: AppNames, index: number): void;
|
|
21
|
-
getSource(name: AppNames): Vide.Source<boolean>;
|
|
22
25
|
set(name: AppNames, value: boolean, rules?: boolean): void;
|
|
23
26
|
open(name: AppNames, rules?: boolean): void;
|
|
24
27
|
close(name: AppNames, rules?: boolean): void;
|
package/out/vide/init.luau
CHANGED
|
@@ -4,6 +4,7 @@ local TS = _G[script]
|
|
|
4
4
|
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
5
5
|
-- Packages
|
|
6
6
|
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
7
|
+
local Vide = _vide
|
|
7
8
|
local apply = _vide.apply
|
|
8
9
|
local create = _vide.create
|
|
9
10
|
local effect = _vide.effect
|
|
@@ -14,6 +15,10 @@ local untrack = _vide.untrack
|
|
|
14
15
|
local Renders = TS.import(script, script, "classes", "renders").default
|
|
15
16
|
-- Helpers
|
|
16
17
|
local AppRegistry = TS.import(script, script, "decorator").AppRegistry
|
|
18
|
+
-- Debug
|
|
19
|
+
local _debug = TS.import(script, script, "debug")
|
|
20
|
+
local Logger = _debug.Logger
|
|
21
|
+
local Debugger = _debug.Debugger
|
|
17
22
|
local AppForge
|
|
18
23
|
do
|
|
19
24
|
local super = Renders
|
|
@@ -30,6 +35,10 @@ do
|
|
|
30
35
|
end
|
|
31
36
|
function AppForge:constructor()
|
|
32
37
|
super.constructor(self)
|
|
38
|
+
self.logger = Logger.new("AppForge")
|
|
39
|
+
self.debug = Debugger.new(function(level, msg, data, trace)
|
|
40
|
+
return self.logger:log(level, msg, data, trace)
|
|
41
|
+
end)
|
|
33
42
|
self.sources = {}
|
|
34
43
|
self.loaded = {}
|
|
35
44
|
self.__px = false
|
|
@@ -46,22 +55,48 @@ do
|
|
|
46
55
|
local _name = name
|
|
47
56
|
local app = AppRegistry[_name]
|
|
48
57
|
if not app then
|
|
49
|
-
|
|
58
|
+
self.logger:log("ERROR", "App not registered while creating source", {
|
|
59
|
+
name = name,
|
|
60
|
+
})
|
|
61
|
+
return nil
|
|
50
62
|
end
|
|
51
63
|
local _sources = self.sources
|
|
52
64
|
local _name_1 = name
|
|
53
65
|
if _sources[_name_1] ~= nil then
|
|
54
66
|
return nil
|
|
55
67
|
end
|
|
56
|
-
local
|
|
68
|
+
local _debug_1 = self.debug
|
|
57
69
|
local _exp = name
|
|
70
|
+
local _object = {}
|
|
71
|
+
local _left = "default"
|
|
58
72
|
local _condition = app.visible
|
|
59
73
|
if _condition == nil then
|
|
60
74
|
_condition = false
|
|
61
75
|
end
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
76
|
+
_object[_left] = _condition
|
|
77
|
+
_debug_1:logTag("state", _exp, "Creating visibility source", _object)
|
|
78
|
+
local _sources_1 = self.sources
|
|
79
|
+
local _exp_1 = name
|
|
80
|
+
local _condition_1 = app.visible
|
|
81
|
+
if _condition_1 == nil then
|
|
82
|
+
_condition_1 = false
|
|
83
|
+
end
|
|
84
|
+
local _arg1 = source(_condition_1)
|
|
85
|
+
_sources_1[_exp_1] = _arg1
|
|
86
|
+
end
|
|
87
|
+
function AppForge:getSource(name)
|
|
88
|
+
local _sources = self.sources
|
|
89
|
+
local _name = name
|
|
90
|
+
if not (_sources[_name] ~= nil) then
|
|
91
|
+
self:createSource(name)
|
|
92
|
+
end
|
|
93
|
+
local _sources_1 = self.sources
|
|
94
|
+
local _name_1 = name
|
|
95
|
+
local src = _sources_1[_name_1]
|
|
96
|
+
if not src then
|
|
97
|
+
error(`AppForge invariant broken: missing visibility source for {name}`, 2)
|
|
98
|
+
end
|
|
99
|
+
return src
|
|
65
100
|
end
|
|
66
101
|
function AppForge:isLoaded(name)
|
|
67
102
|
local _loaded = self.loaded
|
|
@@ -70,28 +105,53 @@ do
|
|
|
70
105
|
end
|
|
71
106
|
function AppForge:bind(name, value)
|
|
72
107
|
if not RunService:IsRunning() then
|
|
108
|
+
self.debug:logTag("state", name, "Binding external visibility source")
|
|
73
109
|
local _sources = self.sources
|
|
74
110
|
local _name = name
|
|
75
111
|
local _value = value
|
|
76
112
|
_sources[_name] = _value
|
|
113
|
+
local prev
|
|
114
|
+
local log = function()
|
|
115
|
+
return self.debug:logTag("state", name, "Visibility changed", {
|
|
116
|
+
from = prev,
|
|
117
|
+
to = value,
|
|
118
|
+
})
|
|
119
|
+
end
|
|
120
|
+
local count = 0
|
|
77
121
|
effect(function()
|
|
78
|
-
|
|
122
|
+
count += 1
|
|
123
|
+
prev = value
|
|
79
124
|
untrack(function()
|
|
80
125
|
return self:checkRules(name)
|
|
81
126
|
end)
|
|
127
|
+
if Vide.strict and count == 1 then
|
|
128
|
+
log()
|
|
129
|
+
count = 0
|
|
130
|
+
else
|
|
131
|
+
log()
|
|
132
|
+
end
|
|
82
133
|
end)
|
|
83
134
|
else
|
|
84
|
-
|
|
135
|
+
self.logger:log("WARN", "forge.bind called while game is running", {
|
|
136
|
+
name = name,
|
|
137
|
+
})
|
|
85
138
|
end
|
|
86
139
|
end
|
|
87
140
|
function AppForge:anchor(name, anchorName, props)
|
|
88
141
|
if name == anchorName then
|
|
89
|
-
|
|
142
|
+
self.logger:log("ERROR", "Attempted to anchor app to itself", {
|
|
143
|
+
name = name,
|
|
144
|
+
})
|
|
145
|
+
return nil
|
|
90
146
|
end
|
|
91
147
|
local _anchorName = anchorName
|
|
92
148
|
local anchorApp = AppRegistry[_anchorName]
|
|
93
149
|
if not anchorApp then
|
|
94
|
-
|
|
150
|
+
self.logger:log("ERROR", "Anchor parent not registered", {
|
|
151
|
+
child = name,
|
|
152
|
+
parent = anchorName,
|
|
153
|
+
})
|
|
154
|
+
return nil
|
|
95
155
|
end
|
|
96
156
|
local _loaded = self.loaded
|
|
97
157
|
local _name = name
|
|
@@ -101,11 +161,17 @@ do
|
|
|
101
161
|
end
|
|
102
162
|
local render = _render
|
|
103
163
|
if not render then
|
|
104
|
-
|
|
164
|
+
self.debug:logTag("rules", name, "Anchor skipped (child not rendered yet)", {
|
|
165
|
+
parent = anchorName,
|
|
166
|
+
})
|
|
167
|
+
return nil
|
|
105
168
|
end
|
|
169
|
+
self.debug:logTag("rules", name, "Anchoring to parent", {
|
|
170
|
+
parent = anchorName,
|
|
171
|
+
})
|
|
106
172
|
local anchor = anchorApp.constructor.new(props, anchorName):render()
|
|
107
|
-
for _,
|
|
108
|
-
|
|
173
|
+
for _, child in anchor:GetDescendants() do
|
|
174
|
+
child:Destroy()
|
|
109
175
|
end
|
|
110
176
|
apply(anchor)({
|
|
111
177
|
Name = "Anchor",
|
|
@@ -116,7 +182,7 @@ do
|
|
|
116
182
|
local _name_1 = name
|
|
117
183
|
local prev = _loaded_1[_name_1]
|
|
118
184
|
if not prev then
|
|
119
|
-
error(`
|
|
185
|
+
error(`AppForge invariant broken: missing loaded app for {name}`, 2)
|
|
120
186
|
end
|
|
121
187
|
apply(prev.container)({
|
|
122
188
|
[0] = anchor,
|
|
@@ -133,22 +199,19 @@ do
|
|
|
133
199
|
local _name = name
|
|
134
200
|
local loaded = _loaded[_name]
|
|
135
201
|
if not loaded then
|
|
136
|
-
|
|
202
|
+
self.logger:log("WARN", "ZIndex skipped (app not loaded)", {
|
|
203
|
+
name = name,
|
|
204
|
+
index = index,
|
|
205
|
+
})
|
|
206
|
+
return nil
|
|
137
207
|
end
|
|
208
|
+
self.debug:logTag("rules", name, "Applying ZIndex", {
|
|
209
|
+
index = index,
|
|
210
|
+
})
|
|
138
211
|
apply(loaded.container)({
|
|
139
212
|
ZIndex = index,
|
|
140
213
|
})
|
|
141
214
|
end
|
|
142
|
-
function AppForge:getSource(name)
|
|
143
|
-
local _sources = self.sources
|
|
144
|
-
local _name = name
|
|
145
|
-
if not (_sources[_name] ~= nil) then
|
|
146
|
-
self:createSource(name)
|
|
147
|
-
end
|
|
148
|
-
local _sources_1 = self.sources
|
|
149
|
-
local _name_1 = name
|
|
150
|
-
return _sources_1[_name_1]
|
|
151
|
-
end
|
|
152
215
|
function AppForge:set(name, value, rules)
|
|
153
216
|
if rules == nil then
|
|
154
217
|
rules = true
|
|
@@ -162,10 +225,21 @@ do
|
|
|
162
225
|
local _name_1 = name
|
|
163
226
|
src = _sources_1[_name_1]
|
|
164
227
|
end
|
|
165
|
-
if src
|
|
228
|
+
if not src then
|
|
229
|
+
self.logger:log("ERROR", "Failed to set visibility (missing source)", {
|
|
230
|
+
name = name,
|
|
231
|
+
})
|
|
232
|
+
return nil
|
|
233
|
+
end
|
|
234
|
+
local prev = src()
|
|
235
|
+
if prev == value then
|
|
166
236
|
return nil
|
|
167
237
|
end
|
|
168
238
|
src(value)
|
|
239
|
+
self.debug:logTag("state", name, "Visibility changed", {
|
|
240
|
+
from = prev,
|
|
241
|
+
to = value,
|
|
242
|
+
})
|
|
169
243
|
if rules then
|
|
170
244
|
self:checkRules(name)
|
|
171
245
|
end
|
|
@@ -189,6 +263,7 @@ do
|
|
|
189
263
|
self:set(name, not self:getSource(name)(), rules)
|
|
190
264
|
end
|
|
191
265
|
function AppForge:story(props)
|
|
266
|
+
self.debug:logTag("lifecycle", "story", "Creating story mount")
|
|
192
267
|
local Container = create("Frame")({
|
|
193
268
|
Name = "Story Container",
|
|
194
269
|
BackgroundTransparency = 1,
|
|
@@ -202,6 +277,7 @@ do
|
|
|
202
277
|
return Container
|
|
203
278
|
end
|
|
204
279
|
function AppForge:mount(callback, props, target)
|
|
280
|
+
self.debug:logTag("lifecycle", "mount", "Mounting AppForge")
|
|
205
281
|
local Container = callback()
|
|
206
282
|
self.innerMount = mount(function()
|
|
207
283
|
apply(Container)({
|
|
@@ -212,6 +288,7 @@ do
|
|
|
212
288
|
return self.innerMount
|
|
213
289
|
end
|
|
214
290
|
function AppForge:unMount()
|
|
291
|
+
self.debug:logTag("lifecycle", "unmount", "Unmounting AppForge")
|
|
215
292
|
local _result = self.innerMount
|
|
216
293
|
if _result ~= nil then
|
|
217
294
|
_result()
|
package/out/vide/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rbxts/app-forge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2-alpha.10",
|
|
4
4
|
"description": "An App Manager for Vide",
|
|
5
5
|
"main": "out/init.lua",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
@@ -38,11 +38,17 @@
|
|
|
38
38
|
"@rbxts/set-timeout": "^1.1.2"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@rbxts/loners-pretty-react-hooks": "^0.2.9",
|
|
42
|
-
"@rbxts/loners-pretty-vide-utils": "^0.1.7",
|
|
43
41
|
"@rbxts/react": "^17.3.7-ts.1",
|
|
44
42
|
"@rbxts/vide": "^0.5.7"
|
|
45
43
|
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@rbxts/react": {
|
|
46
|
+
"optional": true
|
|
47
|
+
},
|
|
48
|
+
"@rbxts/vide": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
46
52
|
"devDependencies": {
|
|
47
53
|
"@biomejs/biome": "^2.3.7",
|
|
48
54
|
"@rbxts/compiler-types": "3.0.0-types.0",
|