Rework ScriptOwners to be a little easier to use
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
use crate::app_interface::list::ImmutableList;
|
||||
use crate::app_interface::{
|
||||
Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic,
|
||||
TurnChoice, TypeIdentifier,
|
||||
Battle, BattleSide, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item,
|
||||
Pokemon, Statistic, TurnChoice, TypeIdentifier,
|
||||
};
|
||||
use crate::handling::ScriptCapabilities;
|
||||
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
||||
use alloc::rc::Rc;
|
||||
use core::any::Any;
|
||||
use core::fmt::Debug;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use core::panicking::panic;
|
||||
|
||||
pub trait Script {
|
||||
fn new() -> Self
|
||||
@@ -346,25 +347,11 @@ pub trait Script {
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn get_owner<T>(&self) -> Option<T>
|
||||
where
|
||||
T: ExternalReferenceType,
|
||||
Self: Sized,
|
||||
{
|
||||
unsafe {
|
||||
script_get_owner(crate::implementation::ScriptPtr::from_existing(self))
|
||||
.cast::<T>()
|
||||
.get_value()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mock_data")]
|
||||
fn get_owner<T>(&self) -> Option<T>
|
||||
fn get_owner(&self) -> Option<ScriptOwner>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
unimplemented!()
|
||||
ScriptOwner::from_script(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,5 +363,91 @@ impl Debug for dyn Script {
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn script_get_owner_kind(pointer: crate::implementation::ScriptPtr) -> u8;
|
||||
fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> ExternRef<u8>;
|
||||
}
|
||||
|
||||
pub enum ScriptOwner {
|
||||
Pokemon(Pokemon),
|
||||
BattleSide(BattleSide),
|
||||
Battle(Battle),
|
||||
None,
|
||||
}
|
||||
|
||||
impl ScriptOwner {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
fn from_script(script: &dyn Script) -> Option<ScriptOwner> {
|
||||
let script_ptr = crate::implementation::ScriptPtr::from_existing(script);
|
||||
unsafe {
|
||||
let kind = script_get_owner_kind(script_ptr);
|
||||
match kind {
|
||||
0 => {
|
||||
let r = script_get_owner(script_ptr)
|
||||
.cast::<crate::app_interface::PokemonImpl>()
|
||||
.get_value();
|
||||
if r.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(ScriptOwner::Pokemon(Rc::new(r.unwrap())))
|
||||
}
|
||||
}
|
||||
1 => {
|
||||
let r = script_get_owner(script_ptr)
|
||||
.cast::<crate::app_interface::BattleSideImpl>()
|
||||
.get_value();
|
||||
if r.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(ScriptOwner::BattleSide(Rc::new(r.unwrap())))
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
let r = script_get_owner(script_ptr)
|
||||
.cast::<crate::app_interface::BattleImpl>()
|
||||
.get_value();
|
||||
if r.is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(ScriptOwner::Battle(Rc::new(r.unwrap())))
|
||||
}
|
||||
}
|
||||
_ => panic!("Unknown script owner kind: {}", kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "mock_data")]
|
||||
fn from_script(script: &dyn Script) -> Option<ScriptOwner> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn as_pokemon(&self) -> Pokemon {
|
||||
if let ScriptOwner::Pokemon(p) = self {
|
||||
return p.clone();
|
||||
}
|
||||
panic!("ScriptOwner was not a Pokemon, but a {self}");
|
||||
}
|
||||
pub fn as_side(&self) -> BattleSide {
|
||||
if let ScriptOwner::BattleSide(p) = self {
|
||||
return p.clone();
|
||||
}
|
||||
panic!("ScriptOwner was not a BattleSide, but a {self}");
|
||||
}
|
||||
pub fn as_battle(&self) -> Battle {
|
||||
if let ScriptOwner::Battle(p) = self {
|
||||
return p.clone();
|
||||
}
|
||||
panic!("ScriptOwner was not a Battle, but a {self}");
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ScriptOwner {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
ScriptOwner::Pokemon(_) => f.write_str("Pokemon"),
|
||||
ScriptOwner::BattleSide(_) => f.write_str("BattleSide"),
|
||||
ScriptOwner::Battle(_) => f.write_str("Battle"),
|
||||
ScriptOwner::None => f.write_str("None"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ mod implementation {
|
||||
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ScriptPtr {
|
||||
index: u32,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user