feat: contracts for all features combinations
This commit is contained in:
@@ -1,72 +1,18 @@
|
||||
use std::hash::Hash;
|
||||
|
||||
use bevy_ecs::{system::Resource, schedule::States};
|
||||
use serde::de;
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
#[cfg(feature = "inspector-egui")]
|
||||
use bevy_inspector_egui::prelude::*;
|
||||
#[cfg(all(feature = "reflect", feature = "serialize"))]
|
||||
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||
use bevy_inspector_egui::inspector_options::InspectorOptionsType;
|
||||
// #[cfg(all(feature = "reflect", feature = "serialize"))]
|
||||
// use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{Serialize, Deserialize, de::DeserializeOwned};
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
#[cfg(feature = "reflect")]
|
||||
use {bevy_ecs::prelude::ReflectResource, bevy_reflect::Reflect};
|
||||
use bevy_reflect::{Reflect, TypePath, FromReflect};
|
||||
|
||||
use crate::resource::PlayerInputs;
|
||||
|
||||
macro_rules! define_common_trait {
|
||||
($trait_name:ident, $trait_inner:ident) => {
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name: $trait_inner {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name: $trait_inner + Serialize + DeserializeOwned {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name: $trait_inner + bevy_reflect::Reflect {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name: $trait_inner + bevy_reflect::Reflect + Serialize + DeserializeOwned {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), feature = "inspector-egui"))]
|
||||
pub trait $trait_name: $trait_inner + bevy_inspector_egui::Inspectable + InspectorOptions {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), feature = "inspector-egui"))]
|
||||
pub trait $trait_name: $trait_inner + bevy_inspector_egui::Inspectable + Serialize + DeserializeOwned + InspectorOptions {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", feature = "inspector-egui"))]
|
||||
pub trait $trait_name: $trait_inner + bevy_inspector_egui::Inspectable + bevy_reflect::Reflect + InspectorOptions {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", feature = "inspector-egui"))]
|
||||
pub trait $trait_name: $trait_inner + bevy_inspector_egui::Inspectable + bevy_reflect::Reflect + Serialize + DeserializeOwned + InspectorOptions {}
|
||||
};
|
||||
($trait_name:ident<$generic:ident : $bound:path>, $trait_inner:ident<$trait_inner_generic:ident>) => {
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + Serialize + DeserializeOwned {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_reflect::Reflect {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_reflect::Reflect + Serialize + DeserializeOwned {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), feature = "inspector-egui"))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_inspector_egui::Inspectable + InspectorOptions {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), feature = "inspector-egui"))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_inspector_egui::Inspectable + Serialize + DeserializeOwned + InspectorOptions {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", feature = "inspector-egui"))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_inspector_egui::Inspectable + bevy_reflect::Reflect + InspectorOptions {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", feature = "inspector-egui"))]
|
||||
pub trait $trait_name<$generic: $bound>: $trait_inner<$trait_inner_generic> + bevy_inspector_egui::Inspectable + bevy_reflect::Reflect + Serialize + DeserializeOwned + InspectorOptions {}
|
||||
};
|
||||
}
|
||||
pub trait ActionInner: 'static + std::marker::Sync + std::marker::Send + PartialEq + Eq + Hash + IntoEnumIterator + Clone + Copy { }
|
||||
|
||||
pub trait GameStateInner: 'static + std::marker::Sync + std::marker::Send + States { }
|
||||
@@ -81,10 +27,76 @@ pub trait InputsContainerInner<A: Action>: 'static + std::marker::Sync + std::ma
|
||||
fn me_mut<'a>(&self) -> Option<&'a mut PlayerInputs<A>>;
|
||||
}
|
||||
|
||||
define_common_trait!(Action, ActionInner);
|
||||
define_common_trait!(GameState, GameStateInner);
|
||||
define_common_trait!(InputsContainer<A: Action>, InputsContainerInner<A>);
|
||||
#[cfg(feature = "serialize")]
|
||||
pub trait SerializeImpl: Serialize + DeserializeOwned { }
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
pub trait ReflectImpl: Reflect + TypePath + FromReflect { }
|
||||
|
||||
#[cfg(feature = "inspector-egui")]
|
||||
pub trait InspectorEguiImpl: InspectorOptionsType { }
|
||||
|
||||
// ===== Action =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait Action: ActionInner {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait Action: ActionInner + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait Action: ActionInner + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl{}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait Action: ActionInner + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait Action: ActionInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
// ===== GameState =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait GameState: GameStateInner {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait GameState: GameStateInner + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl{}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait GameState: GameStateInner + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait GameState: GameStateInner + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
|
||||
|
||||
// ===== InputsContainer =====
|
||||
// SAFATY: inspector-egui includes reflect
|
||||
#[cfg(all(not(feature = "serialize"), not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> {}
|
||||
|
||||
#[cfg(all(feature = "serialize", not(feature = "reflect"), not(feature = "inspector-egui")))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl {}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + ReflectImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "reflect", not(feature = "inspector-egui")))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl + ReflectImpl{}
|
||||
|
||||
#[cfg(all(not(feature = "serialize"), feature = "inspector-egui"))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
#[cfg(all(feature = "serialize", feature = "inspector-egui"))]
|
||||
pub trait InputsContainer<A: Action>: InputsContainerInner<A> + SerializeImpl + ReflectImpl + InspectorEguiImpl {}
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use bevy_app::{Plugin, App, Update};
|
||||
use bevy_ecs::{system::{Res, ResMut, Resource}, schedule::{State, States}};
|
||||
use bevy_ecs::{system::{Res, ResMut}, schedule::State};
|
||||
use bevy_input::{Input, keyboard::KeyCode, mouse::MouseButton};
|
||||
|
||||
use crate::{resource::*, contract::{Action, GameState, InputsContainer}};
|
||||
@@ -20,7 +20,7 @@ impl<
|
||||
.add_systems(Update, Self::save_input);
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
app.register_type::<Controls<A>>()
|
||||
app.register_type::<Controls<A, Gs>>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,14 +10,13 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
|
||||
use bevy_utils::HashMap;
|
||||
use log::warn;
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{Deserialize, de::DeserializeOwned, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::mem::discriminant;
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
#[cfg(feature = "reflect")]
|
||||
use {bevy_ecs::prelude::ReflectResource, bevy_reflect::Reflect};
|
||||
|
||||
use crate::{common_traits_conditions, hashmap, contract::{Action, GameState}};
|
||||
use crate::{common_traits_conditions, contract::{Action, GameState}};
|
||||
|
||||
/// Validate that all enum variants are in the hash map
|
||||
pub fn validate_hash_map<K, V>(hash_map: &HashMap<K, V>) -> bool
|
||||
@@ -39,7 +38,6 @@ where
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
common_traits_conditions! {
|
||||
/// Struct that contains user's inputs corresponding to actions
|
||||
#[derive(Debug, PartialEq, Clone, Deref, DerefMut)]
|
||||
|
||||
Reference in New Issue
Block a user