What's a namespace?
- Namespaces act as a modular, self-contained scope (table) to the identifiers (variables) inside of it. These identifiers can represent functions, tables, or any other value type in Lua. They are essentially modules containing all of these things packaged together, in a way that will not interfere with anything outside of them.
local Unlocker, awful, project = ...
- Example of importing the 3 common namespaces into your file. You are destructuring varargs (...) passed to your file, and declaring upvalues for each namespace within. Now you have access to all functions, tables, values, etc. made available by
awful
!note: This is just declaring local variables. You aren't restricted to what you name them. If you want to access awful API via
af
instead ofawful
for example, you can!
If you are familiar with web development, this is similar to state management often handled by libraries such as Redux, but a lot simpler to use.
What's the purpose?
The entire framework is made available within one table.
Using namespaces ensures your code will never interfere with addons or other routines.
You can organize your project however you see fit, have as many folders and files as you want, and easily maintain all of your own API / data within your namespace.
When you make a change to your namespace in one file, it is immediately reflected in all others.
Common Namespaces
Unlocker
The first namespace passed to each file by awful.
- On an unlocker like Tinkr, you'll find the unlocker's API within. On most others, like Daemonic, its only purpose is to inform you which unlocker is in use.
The unlocker name is always available as a string in camelCase under
Unlocker.type
, so if you are doing anything unlocker-specific, outside of the scope of the framework, you can follow best practices by checking the unlocker type first to ensure compatibility across all platforms.
Unlocker.type : nil | "daemonic" | "unlockerName"
-- this is kinda pseudocode fyi
local Unlocker, awful, project = ...
-- adding some api to our project to run protected funcs on either unlocker
function project.runProtected(f, ...)
-- run some protected function on tinkr
if not Unlocker.type then
local Eval = Unlocker.Util.Evaluator
return Eval:CallProtectedFunction(f, ...)
-- or do it differently on daemonic!
elseif Unlocker.type == "daemonic" then
return CallProtectedApi(f, ...)
end
end
if Unlocker.type == "daemonic" then
print("doing daemonic stuff!")
end
awful
The second namespace passed to each file by awful.
I'm sure you've already caught on by now, but all awful API referenced in these docs will be found within this namespace.
local unlocc, awful, memes = ...
print(awful.hello)
project
The third namespace passed to each file by awful.
This namespace is made available to your project, and only your project. It allows you to build your own extensive API, storing and accessing data of any type between all of your files!
local Unlocker, awful, McDonalds = ...
local colors = awful.colors
function McDonalds.Print(str)
print(colors.red .. "[McDonalds]:", colors.yellow .. str)
end
function McDonalds.CreateOrder(order)
order.append({
type = "Cheeseburger",
lettuce = true,
pickles = false,
})
McDonalds.Print("Your order is ready, sir.")
return order
end
-
Other awful projects get passed their own namespace and won't interfere with the one passed to your project if they're loaded simultaneously.
-
If you set up multiple projects (requires new file in awful/routines folder) you will receive a separate namespace for each one.