Closed RPGHacker closed 1 year ago
I unfortunately can't make the pair type fully customizable. It doesn't just depend on std::is_empty
, the underlying storage also needs to be able to derive the type from the two component ids. The current approach only works because the function that derives the type from a pair can be implemented both in a type-erased storage as well as with C++ templates.
I agree that the dummy member is not super clean, but it's a simple solution that doesn't require significantly complicating the API. One thing you could consider is making your state types inherit from a State_base
type, like:
struct State_base {
private:
bool dummy;
};
struct PlayerState_Idle : State_base
{
static void enter(flecs::entity e, PlayerState_Idle& state);
static void exit(flecs::entity e, PlayerState_Idle& state);
};
which would ensure the state targets are never empty.
Describe the problem you are trying to solve. I'm currently trying to build a player state machine directly in flecs. The samples show one or two ways to do this, but they are a bit too limited for my lking. I'm trying to take things a step further. Each of my state structs contains data needed by the state, as well as enter and exit functions, and simulatenously acts as the target of an exclusive relationship. Here's my current code:
Now this example generally works the way I want it to: When I put breakpoints in each state function, the application calls
PlayerState_Idle::enter()
,PlayerState_Idle::exit()
andPlayerState_Walking::enter()
in that order, and then callsPlayerState_Walking::exit()
upon closing the app.However, there is one small problem with this solution: As you can see, both of the PlayerState structs contain a
dummy
data member. This member isn't there for no reason, it's actually required to make this solution work, which is a bit annoying, since you might want to create player states that don't need any data. The reason for this is the wayflecs::pair
detects the component type. When both structs are empty, it choose the first one as the component.Now you might think this problem had an easy solution: Just swap the order of types in the pair. It's something I immediately tried. However, doing so quickly reveals another problem: The
flecs::Exclusive
above no longer does what I want it to do. It seems this tag assumes the first type of a pair to always be the relationship. This causes my player states to no longer be mutually exclusive, andPlayerState_Idle::exit()
is no longer called upon adding thePlayerState_Walking
component.Describe the solution you'd like Some means of manually specifying the relationship/component types of a pair could solve this issue. Currently, the mechanism in place relies solely on
std::is_empty
, and when both types are empty, it always favors the first type as the component type, which actually seems rather impractical in regards to howflecs::Exclusive
works.