# Revised per Tara
### Sources
Produce events: `InputTransformer`. 

### Sinks
Consume events

### Mapping
Translates the types

**The inheritable "Classes" are `traits`.** Keep a list of them as `Box<dyn Source>`.

Use `async` and `async_select_all` to get the next event out of any of the inputs.

### -----------------------------
### Input Modules
Structs which are initialized, and then broadcast input events. They expose their input events in some standardized way (enums + passing closures?). Some input events may have variants, i.e. Playdate input modules might have "raw crank", "crank as scroll wheel", "crank as scroll wheel with acceleration" etc.

Examples:
- Playdate Tethered Serial (will definitely be made)
- Playdate Wireless - would come eventually if we make a PD-side app

**Suggestion:** Input transformers
A secondary set of functional enums independent from modules. Can transform data from one type (served by an input module) to another (served to an output module).

### Output Modules
Structs which are initialized, and then accept output action requests for their unique endpoints. They expose their available output actions + expected parameters via enums and standardized function(s)

Examples:
- USB/IP (will definitely be made)
- AutoHotKey (no plans, just an example)

### IO Mapper
Some system that "listens for" input events from active input modules, and passes them to the mapped output actions for active output modules. The default IO mapper reads from a mapping config on disk on program start.
- There can be multiple profiles
- Each profile lets the user define details such as:
    - Profile name
    - Input module
    - Output module
    - Mappings. select 1 --> input event, select 2 --> transformers that are applicable to the given input (optional), select 3 --> output actions that accept the final data type
- Profiles can be exported and loaded. They're effectively just config files

## Important distinction: This is not AHK lol
Don't let the project scope get out of hand. Although this modular architecture will exist at the core for other devs to expand on the project in a straightforward way, **we will not define a standardized means of creating and user-loading external modules, transformers, or mappers.** The ones which exist for the user to choose from will all simply be bundled at compile time.

Maybe if some dev wants to down the line, they could create dedicated `Load External` input and output modules. Then that feature itself is a set of compiled modules, and somehow loads externally defined modules via whatever magic the theoretical 3rd party dev cooks up.