Skip to content

Commit 1067140

Browse files
Plugins can now be a folder with a Main.luau file, Added @plugin alias for plugin folders, Added fs.removealias
1 parent 433a0f2 commit 1067140

17 files changed

Lines changed: 138 additions & 124 deletions

File tree

apidump.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@
430430
"promptsave": "function",
431431
"read": "function",
432432
"remove": "function",
433+
"removealias": "function",
433434
"rename": "function",
434435
"resolvepath": "function",
435436
"resolvepathabsolute": "function",

lsp/api-docs.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,9 @@
816816
"@phoenix/global/fs.remove": {
817817
"documentation": "* Removes everything at the given path\n* Throws an error upon failure"
818818
},
819+
"@phoenix/global/fs.removealias": {
820+
"documentation": "* Removes an alias previously defined with `fs.definealias`"
821+
},
819822
"@phoenix/global/fs.rename": {
820823
"documentation": "* Renames the file at the given `Path` to have the `NewName`\n* Throws an error upon failure"
821824
},

lsp/api.d.luau

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ declare fs: {
732732
promptsave: (( DefaultLocation: string?, Filter: ( { string } | string)?, FilterName: string? ) -> (string?)),
733733
read: (( Path: string ) -> (string?, string?)),
734734
remove: (( Path: string ) -> ()),
735+
removealias: (( Alias: string ) -> ()),
735736
rename: (( Path: string, NewName: string ) -> ()),
736737
resolvepath: (Path: string) -> string,
737738
resolvepathabsolute: (Path: string) -> string,

plugins/niko.luau

Lines changed: 0 additions & 52 deletions
This file was deleted.

resources/scripts/ed/PluginManager.luau

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ type ToolbarButton = Types.ToolbarButton
99
local PluginManager = {}
1010
PluginManager.Plugins = {} :: { Plugin }
1111
local IsPluginManagementWindowOpen = false
12-
local PluginSettings: { [string]: { Enabled: boolean } } = {}
12+
local PluginSettings: { [string]: { Enabled: boolean }? } = {}
1313

1414
local PLUGIN_SETTINGS_PATH = "./editor/plugin-settings.json"
1515

16-
local function getPluginSettings(plugin: Plugin): index<typeof(PluginSettings), string>
16+
local function getPluginSettings(plugin: Plugin)
1717
local settings = PluginSettings[plugin.Path]
1818
if not settings then
1919
settings = { Enabled = true }
2020
PluginSettings[plugin.Path] = settings
2121
end
2222

23-
return settings
23+
return assert(settings)
2424
end
2525

2626
local function renderPluginManagement()
@@ -80,32 +80,56 @@ local function renderPluginManagement()
8080
end
8181
end
8282

83-
local function loadPluginsRecursive(ParentPath)
83+
local function setPluginAlias(ParentPath: string?)
84+
if ParentPath then
85+
fs.definealias("plugin", ParentPath)
86+
end
87+
end
88+
89+
local function loadPlugin(Path, ParentPath: string?)
90+
local co, err = task.loadfile(Path)
91+
92+
if co then
93+
local success, data: Plugin = coroutine.resume(co)
94+
95+
if success then
96+
data.Path = Path:sub(assert((Path:find("/plugins"))) + 1, #Path)
97+
data.ParentPath = ParentPath
98+
--table.freeze(data)
99+
100+
if typeof(data.Icon) == "string" then
101+
setPluginAlias(ParentPath)
102+
data.Icon = fs.resolvepath(data.Icon)
103+
fs.removealias("plugin")
104+
end
105+
106+
table.insert(PluginManager.Plugins, data)
107+
108+
if getPluginSettings(data).Enabled and data.OnLoad then
109+
data:OnLoad()
110+
end
111+
else
112+
warn(`PluginManager: Failed to load-execute plugin { Path }: { data }`)
113+
end
114+
else
115+
warn(`PluginManager: Failed to load plugin { Path }: { err }`)
116+
end
117+
end
118+
119+
local function loadPlugins(ParentPath)
84120
for path, type in fs.listdir(ParentPath) do
85121
if type == "f" then
86122
if path:sub(#path - 4, #path) == ".luau" then
87-
local co, err = task.loadfile(path)
88-
89-
if co then
90-
local success, data: Plugin = coroutine.resume(co)
91-
92-
if success then
93-
data.Path = path:sub(assert((path:find("/plugins"))) + 1, #path)
94-
--table.freeze(data)
95-
table.insert(PluginManager.Plugins, data)
96-
97-
if getPluginSettings(data).Enabled and data.OnLoad then
98-
data:OnLoad()
99-
end
100-
else
101-
print(`Failed to load-execute plugin {path}: {data}`)
102-
end
103-
else
104-
print(`Failed to load plugin {path}: {err}`)
105-
end
123+
loadPlugin(path)
106124
end
107125
else
108-
loadPluginsRecursive(path)
126+
local mainScriptPath = path .. "/Main.luau"
127+
128+
if fs.isfile(mainScriptPath) then
129+
loadPlugin(mainScriptPath, path)
130+
else
131+
warn(`PluginManager: Expected { mainScriptPath } to be valid`)
132+
end
109133
end
110134
end
111135
end
@@ -116,16 +140,24 @@ function PluginManager.Load()
116140
end
117141

118142
if fs.isfile(PLUGIN_SETTINGS_PATH) then
119-
PluginSettings = json.parse(fs.read(PLUGIN_SETTINGS_PATH) or "") or {}
143+
local settings = json.parse(fs.read(PLUGIN_SETTINGS_PATH) or "")
144+
145+
if typeof(settings) == "table" then
146+
PluginSettings = settings :: { [string]: { Enabled: boolean }? }
147+
else
148+
warn(`PluginManager: Settings file corrupt: '{ settings }' ({ typeof(settings) })`)
149+
end
120150
end
121151

122-
loadPluginsRecursive("./plugins")
152+
loadPlugins("./plugins")
123153
end
124154

125155
function PluginManager.Shutdown()
126156
for _, plugin in PluginManager.Plugins do
127157
if plugin.OnShutdown then
158+
setPluginAlias(plugin.ParentPath)
128159
plugin:OnShutdown()
160+
fs.removealias("plugin")
129161
end
130162
end
131163

@@ -135,15 +167,19 @@ end
135167
function PluginManager.OnEditorStageChanged(OldStage: EditorStage, NewStage: EditorStage)
136168
for _, plugin in PluginManager.Plugins do
137169
if getPluginSettings(plugin).Enabled and plugin.OnEditorStageChanged and table.find(plugin.ActiveStages, NewStage) then
170+
setPluginAlias(plugin.ParentPath)
138171
plugin:OnEditorStageChanged(OldStage, NewStage)
172+
fs.removealias("plugin")
139173
end
140174
end
141175
end
142176

143177
function PluginManager.OnUpdate(DeltaTime: number, CurrentStage: EditorStage)
144178
for _, plugin in PluginManager.Plugins do
145179
if getPluginSettings(plugin).Enabled and plugin.OnUpdate and table.find(plugin.ActiveStages, CurrentStage) then
180+
setPluginAlias(plugin.ParentPath)
146181
plugin:OnUpdate(DeltaTime)
182+
fs.removealias("plugin")
147183
end
148184
end
149185

@@ -180,6 +216,12 @@ function PluginManager.GetToolbarButtons(CurrentStage: EditorStage): { ToolbarBu
180216
for _, plugin in PluginManager.Plugins do
181217
if getPluginSettings(plugin).Enabled and table.find(plugin.ActiveStages, CurrentStage) then
182218
for _, t in plugin.ToolbarButtons do
219+
if t.Icon and t.Icon:find("@") then
220+
setPluginAlias(plugin.ParentPath)
221+
t.Icon = fs.resolvepath(t.Icon)
222+
fs.removealias("plugin")
223+
end
224+
183225
table.insert(buttons, t)
184226
end
185227
end

resources/scripts/ed/Types.luau

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type Plugin = {
1515
Description: string?,
1616
Icon: string?,
1717
Path: string,
18+
ParentPath: string?,
1819
ActiveStages: { Stage },
1920
ToolbarButtons: { ToolbarButton },
2021

resources/textures/niko.png

-53.7 KB
Binary file not shown.

src/decl/FileRW.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ namespace FileRW
3030
// E.x.: with `::DefineAlias("modules", "scripts/modules")` the path
3131
// "@modules/MyModule.luau" resolves to "scripts/modules/MyModule.luau"
3232
void DefineAlias(const std::string& Alias, const std::string& Path);
33+
void RemoveAlias(const std::string& Alias);
3334
// When the path given begins with a `.` to indicate CWD, set the alias
3435
void MakeCwdAliasOf(const std::string&);
3536

36-
std::string MakePathCwdRelative(std::string);
37-
std::string MakePathAbsolute(std::string);
37+
std::string ResolvePathNormalized(std::string);
38+
std::string ResolvePathAbsolute(std::string);
3839
};

src/impl/FileRW.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ std::string FileRW::ReadFile(const std::string& ShortPath, bool* Success)
3636
{
3737
ZoneScoped;
3838

39-
const std::string actualPath = FileRW::MakePathCwdRelative(ShortPath);
39+
const std::string actualPath = FileRW::ResolvePathNormalized(ShortPath);
4040
ZoneText(ShortPath.data(), ShortPath.size());
4141
ZoneText(actualPath.data(), actualPath.size());
4242

@@ -86,7 +86,7 @@ bool FileRW::WriteFile(
8686
{
8787
ZoneScoped;
8888

89-
std::string path = FileRW::MakePathCwdRelative(ShortPath);
89+
std::string path = FileRW::ResolvePathNormalized(ShortPath);
9090
ZoneText(ShortPath.data(), ShortPath.size());
9191
ZoneText(path.data(), path.size());
9292

@@ -120,7 +120,7 @@ bool FileRW::WriteFileCreateDirectories(
120120
{
121121
ZoneScoped;
122122

123-
std::string path = FileRW::MakePathCwdRelative(ShortPath);
123+
std::string path = FileRW::ResolvePathNormalized(ShortPath);
124124
ZoneText(ShortPath.data(), ShortPath.size());
125125
ZoneText(path.data(), path.size());
126126

@@ -147,6 +147,12 @@ void FileRW::DefineAlias(const std::string& Alias, const std::string& Path)
147147
s_AliasMap[Alias] = Path;
148148
}
149149

150+
void FileRW::RemoveAlias(const std::string& Alias)
151+
{
152+
if (const auto& it = s_AliasMap.find(Alias); it != s_AliasMap.end())
153+
s_AliasMap.erase(it);
154+
}
155+
150156
void FileRW::MakeCwdAliasOf(const std::string& Alias)
151157
{
152158
s_CwdAliasing = Alias;
@@ -162,10 +168,7 @@ static std::string resolveAliasRecursive(std::string Path)
162168
const auto& aliasIt = s_AliasMap.find(alias);
163169

164170
if (aliasIt == s_AliasMap.end())
165-
{
166-
Log.ErrorF("Invalid alias '{}' in path '{}'", alias, Path);
167-
return Path;
168-
}
171+
RAISE_RTF("Invalid alias '{}' in path '{}'", alias, Path);
169172
else
170173
Path = aliasIt->second + Path.substr(aliasEnd, Path.size() - aliasEnd);
171174

@@ -175,11 +178,11 @@ static std::string resolveAliasRecursive(std::string Path)
175178
return Path;
176179
}
177180

178-
std::string FileRW::MakePathCwdRelative(std::string Path)
181+
std::string FileRW::ResolvePathNormalized(std::string Path)
179182
{
180183
if (Path.size() == 0)
181184
{
182-
Log.Warning("`MakePathCwdRelative` given a path 0 bytes in length!");
185+
Log.Warning("`ResolvePathNormalized` given a path 0 bytes in length!");
183186
return Path;
184187
}
185188

@@ -225,15 +228,15 @@ std::string FileRW::MakePathCwdRelative(std::string Path)
225228
return Path;
226229
}
227230

228-
std::string FileRW::MakePathAbsolute(std::string Path)
231+
std::string FileRW::ResolvePathAbsolute(std::string Path)
229232
{
230233
if (Path.size() == 0)
231234
{
232-
Log.Warning("`MakePathAbsolute` given a path 0 bytes in length!");
235+
Log.Warning("`ResolvePathAbsolute` given a path 0 bytes in length!");
233236
return Path;
234237
}
235238

236-
std::string cwd = MakePathCwdRelative(Path);
239+
std::string cwd = ResolvePathNormalized(Path);
237240
std::string abs = cwd;
238241

239242
if (abs[0] != '/' && abs[0] != '~' && (abs.size() < 2 || abs[1] != ':'))

0 commit comments

Comments
 (0)