-
Notifications
You must be signed in to change notification settings - Fork 3
Home
This is a small wiki to describe how to develop for this project, instructions on how to use the widget are here: Streaming Widget Wiki
This will be updated at the same time as the develop
branch, so it might actually be ahead of the master
branch.
The project has a number of modules and states that are initiated in their respective singletons at launch: ModulesSingleton
and StatesSingleton
.
These can be accessed in other places of the code like so:
const modules = ModulesSingleton.getInstance()
const states = StatesSingleton.getInstance()
Keep in mind to not access other modules in your own module's constructor, as the order of instantiation can change. That said, the singleton is instantiated at the beginning of execution, so any access outside the constructor should in most cases be fine.
The main way to add functionality to the project is by writing a module. These are usually classes that we instantiate in the modules singleton. There are a few steps to make modules accessible to an end user.
- Add a module source file to
./src/modules/
, anything in here will get transpiled and then included at runtime. - Write your module, it's fine to have it either as a static class (only static function) or something that needs to be instantiated in the singleton.
- If the module is non-static, add a property for it in
./src/modules_singleton.ts
, e.g:class ModulesSingleton { public yourModule = new YourModule() }
This should mean your module is now ready to be interacted with by other code.
To allow for an end user to trigger things in your module, we need to add an action for it, this can then be set up in the config by the user. This is a multi-step process:
- Add a new interface for your module by appending
./src/interfaces/iactions.ts
, this is what we setup in the event to trigger this action, e.g:interface IYourAction { // Mandatory parameters setupParam1: string setupParam2: number // Optional parameters optionalSetupParam1?: boolean optionalSetupParam2?: { [key: string]: string } }
- Add the property for this action to the main event interface in
./src/interfaces/iactions.ts
, meaningIActions
, and make it optional, e.g:interface IActions { /** * Optional: My module allows for this and that to happen! */ yourConfig?: IYourConfig // or yourConfigWithIncrementalRewardSupport?: IYourConfig|IYourConfig[] }
- Create an action callback builder in
./src/actions.ts
, the builder can take a few parameters that are supplied to all actions when executed, e.g:There are a few more considerations if your action supports the incremental reward type. It's fairly specialized, but here is an example. This also shows how to use asynchronous functions inside the action callback:public static buildYourCallback( config: IYourConfig|undefined, key: string // Optional input in case you need to know the key ): ITwitchActionCallback|undefined { if(config) return { tag: '😀', description: 'What does this action do?', call: (user: IActionUser) => { // If your module needs to have an instance const modules = ModulesSingleton.getInstance() modules.yourModule.yourPublicFunction(singleConfig, user, key) // user and key are additional data that can be useful // If your module is all static functions YourModule.yourPublicStaticFunction(singleConfig) } } }
public static buildYourIncrementalCallback( config: IYourConfig|IYourConfig[]|undefined, // Note array type ): ITwitchActionCallback|undefined { if(config) return { tag: '😁', description: 'What does this action do?', call: async (user: IActionUser, index?: number) => { // Note index const singleConfig = Utils.randomOrSpecificFromArray(config, index) // Random if index is undefined if(singleConfig) { const modules = ModulesSingleton.getInstance() await modules.yourModule.yourPublicAsyncFunction(singleConfig) // or YourModule.yourPublicStaticFunction(singleConfig) } } } }
- Finally use your builder to build a callback in
Actions.buildActionCallback()
, and push your action onto the stack, e.g:// The actions come from the triggered IEvent, the key is something to use if you need it. // There are more values that can be used in the builder, check others for reference. stack.pushIfExists(this.buildYourCallback(actions?.yourConfig, key))