I'm trying to create an abstract GUI library in Rust for building GUI applications.
The library has the types and concepts of Components, Actions, Focus, Text/Mouse Input.
To make components abstract and reusable, I'm using Capabilities (Box<dyn Any + Send + Sync>) + downcasting.
Along with that, to manage state, I'm using the same downcasting approach to be able to store the states in a generic way.
Here is the current structure:
UIState
├── Components
│ ├── TextInput
│ │ └── Capabilities<TextInput>
│ └── CheckBox
│ └── Capabilities<CheckBox>
└── ComponentStates
├── State<TextInput>
└── State<CheckBox>
The problem I'm facing is that some of the components have Capabilities, which contain callbacks that need to access the component's state.
For example, a Checkbox component has a MouseInputCapability with a callback that toggles the checked state of the checkbox.
The same can be naturally said about other things like TextInput where the KeyboardInputCapability needs to modify the text state.
The issue I'm breaking my head around is if I should somehow change my object model completely to accommodate this, because I'm not the biggest fan of having to wrap every state in an Arc<Mutex<>> to be able to share it with the capability callbacks, mainly due to performance concerns.
Just in case it's relevant, I'm using ratatui as a test for my abstractions.