You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've listed out a few options here - currently leaning towards (3) as the most likely ideal approach
Solution 1 (Association Enums)
Each enum variant is its own class and the enum type is a union of the variants. We can "associate" these distinct classes as enums by setting a custom static property and reading it to determine component type (as opposed to just looking at object.constructor).
// DefiningclassPending{}classResolved{value: any;}classRejected{error: any;}typePromiseish=Pending|Resolved|Rejected;// This function mutates these classes to make them associatedconstPromiseish=Enum({ Pending, Resolved, Rejected });constinstance=newPromiseish.Pending();// In usefunctionmySystem(query: Query<Promiseish>){for(constpromiseishofquery){console.log(typeofpromiseish);// Could be Promiseish or any subtype!}}
Pros:
Localizes enum definition to one place
Pretty small API
Enums look like normal components mostly
Direct handling of enum instances
Cons:
Must define enums twice (once as a type, once as an object)
Enum() mutates the classes given to it
Columns will store objects of variable shape, queries could deopt because promiseish is multiple kinds of object
Solution 2 (Wrapper Enums)
Enums as wrappers with a type and data field:
classPromiseishextendsEnum({ Pending, Resolved, Rejected }){}constinstance=newPromiseish(newPending());instance.type;// Pendinginstance.data;// new Pending() created above
Pros:
Pretty straightforward
Cons:
Twice as many objects
Don't get to handle enum objects directly (i.e. always thru .data)
Kind of curious how VMs handle objects with references to other objects with different shapes - no idea on what this looks like for perf, if it even matters.
Solution 3 (Extension Enums)
This isn't exactly enums but it achieves a similar result. Rework how archetypes are modeled (we probably have to do this anyway) and allow filters/modifiers to define a matching function. Expose an Extended<T> type (would come up with a better name) that matches subclasses and not just the exact class. This could have uses beyond just enum-like behavior or the Extended<T> type
// DefiningclassPromiseish{}classPendingextendsPromiseish{}classResolvedextendsPromiseish{data: any;}classRejectedextendsPromiseish{error: string;}// In usefunctionmySystem(query: Query<Extended<Promiseish>>){for(constpromiseishofquery){console.log(promiseish.constructor);// Could be Promiseish or any subtype!}}
Pros:
Direct object handling
Single definition of "union" type
Table columns are single-shape
Extensible enums! e.g. a physics library could provide a Collider type and just require consumers to extend the class with an onCollide() method. Library systems can then query for consumer components
Cons:
Changing enum type is a table move (does this happen much?)
Always have to specify Extended<T> in queries (we'd make this shorter, but still)
Queries still have de-opt potential
Extensible enums (hah)
The text was updated successfully, but these errors were encountered:
Describe the problem this feature solves
Rust-like enum components would be a nice win.
Potential Solutions
I've listed out a few options here - currently leaning towards (3) as the most likely ideal approach
Solution 1 (Association Enums)
Each enum variant is its own class and the enum type is a union of the variants. We can "associate" these distinct classes as enums by setting a custom static property and reading it to determine component type (as opposed to just looking at
object.constructor
).Pros:
Cons:
Enum()
mutates the classes given to itSolution 2 (Wrapper Enums)
Enums as wrappers with a
type
anddata
field:Pros:
Cons:
.data
)Solution 3 (Extension Enums)
This isn't exactly enums but it achieves a similar result. Rework how archetypes are modeled (we probably have to do this anyway) and allow filters/modifiers to define a matching function. Expose an
Extended<T>
type (would come up with a better name) that matches subclasses and not just the exact class. This could have uses beyond just enum-like behavior or theExtended<T>
typePros:
Collider
type and just require consumers to extend the class with anonCollide()
method. Library systems can then query for consumer componentsCons:
Extended<T>
in queries (we'd make this shorter, but still)The text was updated successfully, but these errors were encountered: