feat: contracts for all features combinations

This commit is contained in:
2024-01-11 16:53:19 +01:00
parent 2f7bb64147
commit 726763eb64
3 changed files with 78 additions and 68 deletions
+74 -62
View File
@@ -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 {
+2 -2
View File
@@ -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>>();
}
}
+2 -4
View File
@@ -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)]