Roam
Roam follows a design pattern similar to Knit, but is more lightweight (Shoutout to Stephen Leitnick [Sleitnick]). It removes all networking and replication functionality, and instead focuses on providing a simple method to easily initialize Services given to it and provide global accessors.
Roam gathers a collection of specified services and initializes 'syncronously'. Once all services have been fully initialized, it then starts them 'asyncronously' by spawning their 'RoamStart' method in a new thread.
Roam enforces contracts to ensure that only the Services that you intend are initialized. By following the contracts of service construction/registration, Roam is able to ensure that nothing that isnt intended to be initialized doesnt cause any issues during the loading or start process.
[CONTRACTS]
- Services must be created/registered before Roam is started.
- Services must be created/registered with a unique name.
-
Services with
RoamInit
andRoamStart
methods will have those methods called when Roam is started at the appropriate time. (Names are configurable) - All Services are guaranteed safe to access in RoamStart.
- Only StaticMethods are safe to call prior to RoamStart.
[EXAMPLE USAGE]
local Roam = require(ReplicatedStorage.Roam)
-- Just iterates through all the children of the given parents
-- and requires any module scripts that match the given predicate
Roam.requireModules({
ReplicatedStorage.Shared;
ServerScriptService.Server;
})
-- Start Roam
Roam.start()
:andThenCall(print, "Roam started!")
:catch(warn)
-- Accessing a potential Service
Roam.getService("MyService"):DoSomething()
Types
ServiceConfig
interface
ServiceConfig {
Name:
string
--
Name of the Service. Must be unique. Used when accessing via .getService
RequiredServices:
{
Service
}
?
--
The Services that this Service depends on. Roam will ensure that these Services are initialized before this Service.
StartMethodName:
string?
--
Overrides default StartMethodName of "RoamStart"
InitMethodName:
string?
--
Overrides default InitMethodName of "RoamInit"
}
local myOtherService = require(ReplicatedStorage.MyOtherService)
local MyService = Roam.createService {
Name = "MyService",
RequiredServices = {myOtherService},
}
Automatic Service Dependency Resolution (RequiredServices)
If you require services to a global
variable then ROAM will automatically add the service to the RequiredServices table.
This will NOT work if it is required to a local
variable. If it is localized then you must manually add it to the RequiredServices table
if you want it marked as a dependency.
myOtherService = require(ReplicatedStorage.MyOtherService) -- services required to global variables are automatically added to RequiredServices
local MyService = Roam.createService { Name = "MyService" }
Deffering RequiredServices
Do NOT add services to the RequiredServices after you have created or registered the service. This will cause undefined behavior.
Properties
ClassName
Roam.ClassName:
"Roam"
The ClassName of the Roam module.
Debug
Roam.Debug:
boolean
Whether or not to print debug messages. Default is false.
Bootstrappers
A table of generic bootstrappers for Roam / Orion.
Functions
createService
Creates a Service/Table with Roam to be Initialized and Started when Roam starts. Cannot be called after Roam has been started. This is the advised method of creating services over registering them.
local Roam = require(ReplicatedStorage.Roam)
local MyService = Roam.createService { Name = "MyService" }
function MyService:DoSomething()
print("yeee haw!")
end
-- Default StartMethodName is "RoamStart" (Can be overriden in service creation config)
function MyService:RoamStart()
print("MyService started!")
self:DoSomething()
end
-- Default InitMethodName is "RoamInit" (Can be overriden in service creation config)
function MyService:RoamInit()
print("MyService initialized!")
end
return MyService
registerService
Registers a Service/Table with Roam to be Initialized and Started when Roam starts. Cannot be called after Roam has been started. This method was added to allow for easy backporting of existing services to Roam.
local MyRegisteredService = {}
function MyRegisteredService:Start()
print("MyRegisteredService started!")
end
function MyRegisteredService:Init()
print("MyRegisteredService initialized!")
end
local Roam = require(ReplicatedStorage.Roam)
Roam.registerService(MyRegisteredService, {
Name = "MyRegisteredService";
StartMethodName = "Start"; -- Overrides default StartMethodName of "RoamStart" [Optional]
InitMethodName = "Init"; -- Overrides default InitMethodName of "RoamInit" [Optional]
})
return MyRegisteredService
requireModules
Roam.
requireModules
(
config:
{
DeepSearch:
boolean?
,
}
?
) →
{
Service
}
Requires all the modules that are children of the given parent. This is an easy way to quickly load all services that might be in a folder. Takes an optional predicate function to filter which modules are loaded. Services collected this way must not yield.
DeepSearch
-> whether it checks descendants or just childrenRequirePredicate
-> a predicate function that determines whether a module should be requiredIgnoreDescendantsPredicate
-> A Predicate for whether the Descendants of the Module should be Searched (Only matters if DeepSearch is true)
local pred = function(obj: ModuleScript): boolean
return obj.Name:match("Service$") ~= nil
end
Roam.requireModules(ReplicatedStorage.Shared, {
DeepSearch = true,
RequirePredicate = pred,
IgnoreDescendantsPredicate = function(obj: Instance): boolean
return obj.Name == "Ignore"
end,
})
getNameFromService
Roam.
getNameFromService
(
service:
Service
) →
string
Fetches the name of a registered Service.
getService
Roam.
getService
(
serviceName:
string
) →
Service
Fetches a registered Service by name. Cannot be called until Roam has been started.
start
Starts Roam. Should only be called once.
Optional argument postInitPreStart
is a function that is called
after all services have been initialized, but before they are started.
caution
Be sure that all services have been created before
calling Start
. Services cannot be added later.
Roam.start()
:andThenCall(print, "Roam started!")
:catch(warn)
onStart
Returns a promise that is resolved once Roam has started. This is useful
for any code that needs to tie into Roam services but is not the script
that called Start
.
Roam.onStart():andThen(function()
local MyService = Roam.Services.MyService
MyService:DoSomething()
end):catch(warn)
isReady
Roam.
isReady
(
) →
boolean
Returns whether or not Roam has been successfully started and is ready for external access.