This allows for capsules to be created at runtime instead of requiring them to be known at compile time.
This addition will allow for all traditional IC applications (think a spreadsheet with a varying number of in-use cells) to be built with ReArch, top to bottom.
Since I may forget: this is already possible in the Dart implementation since we aren't using function types as keys there; we are using the function's hash + eq directly. Thus, you could do Map<SomeKey, Capsule<SomeType>> dynamicCapsules(CapsuleHandle use) {...} already over there and have it work just fine.
We will also need another type to use as the internal key (instead of just the current TypeId), which will be a composite key of:
TypeId of the dynamic capsule struct (reasoning: if DynCapsule1 and DynCapsule2 structs both use the same type of key, we don't want conflicts between the two dynamic capsule types whenever they share keys)
Way to hash provided dynamic capsule key (probably function pointer taking &Box<dyn Any> input
Way to eq check provided dynamic capsule key (probably function pointer taking old: &Box<dyn Any>, new: &Box<dyn Any> input
Box<dyn Any> of the provided dynamic capsule key
This will likely look something like: enum InternalKey { Static(TypeId), Dynamic{key: Box<dyn Any>, capsule_type: TypeId, hash_key: fn(&Box<dyn Any>)-> usize, check_key_eq: fn(&Box<dyn Any>, &Box<dyn Any>) -> bool }} and will require a handrolled Hash/Eq using the provided fn pointers. Derive will not be possible since we will have to manually invoke the custom fn pointers.
Capsule trait has a new function with default impl, fn key() -> CapsuleKey { CapsuleKey::Static(TypeId::of::<Self>())} that will return this new key
Users can then make a struct for each type of dynamic capsule they have and impl Capsule for those structs.
This allows for capsules to be created at runtime instead of requiring them to be known at compile time. This addition will allow for all traditional IC applications (think a spreadsheet with a varying number of in-use cells) to be built with ReArch, top to bottom.
Since I may forget: this is already possible in the Dart implementation since we aren't using function types as keys there; we are using the function's hash + eq directly. Thus, you could do
Map<SomeKey, Capsule<SomeType>> dynamicCapsules(CapsuleHandle use) {...}
already over there and have it work just fine.Projected changes:
pub enum CapsuleKey { Static(TypeId), Dynamic{key: Box<dyn Any>, hash_key: fn(&Box<dyn Any>)-> usize, check_key_eq: fn(&Box<dyn Any>, &Box<dyn Any>) -> bool }}
(variants are private)TypeId
), which will be a composite key of:TypeId
of the dynamic capsule struct (reasoning: ifDynCapsule1
andDynCapsule2
structs both use the same type of key, we don't want conflicts between the two dynamic capsule types whenever they share keys)&Box<dyn Any>
inputold: &Box<dyn Any>, new: &Box<dyn Any>
inputBox<dyn Any>
of the provided dynamic capsule keyenum InternalKey { Static(TypeId), Dynamic{key: Box<dyn Any>, capsule_type: TypeId, hash_key: fn(&Box<dyn Any>)-> usize, check_key_eq: fn(&Box<dyn Any>, &Box<dyn Any>) -> bool }}
and will require a handrolled Hash/Eq using the provided fn pointers. Derive will not be possible since we will have to manually invoke the custom fn pointers.fn key() -> CapsuleKey { CapsuleKey::Static(TypeId::of::<Self>())}
that will return this new keyUsers can then make a struct for each type of dynamic capsule they have and
impl Capsule
for those structs.