mirror of
https://github.com/bevyengine/bevy
synced 2025-01-02 08:18:59 +00:00
Small optimization for ArgumentSignature from ArgList
This commit is contained in:
parent
a6121d62f9
commit
f93aadd0dd
2 changed files with 78 additions and 6 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::func::signature::ArgumentSignature;
|
||||
use crate::func::signature::{ArgListSignature, ArgumentSignature};
|
||||
use crate::func::{ArgList, FunctionError, FunctionInfo, FunctionOverloadError};
|
||||
use alloc::borrow::Cow;
|
||||
use bevy_utils::hashbrown::HashMap;
|
||||
|
@ -62,13 +62,13 @@ impl<F> DynamicFunctionInternal<F> {
|
|||
return Ok(&self.functions[0]);
|
||||
}
|
||||
|
||||
let signature = ArgumentSignature::from(args);
|
||||
let signature = ArgListSignature::from(args);
|
||||
self.arg_map
|
||||
.get(&signature)
|
||||
.map(|index| &self.functions[*index])
|
||||
.ok_or_else(|| FunctionError::NoOverload {
|
||||
expected: self.arg_map.keys().cloned().collect(),
|
||||
received: signature,
|
||||
received: ArgumentSignature::from(args),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -83,13 +83,13 @@ impl<F> DynamicFunctionInternal<F> {
|
|||
return Ok(&mut self.functions[0]);
|
||||
}
|
||||
|
||||
let signature = ArgumentSignature::from(args);
|
||||
let signature = ArgListSignature::from(args);
|
||||
self.arg_map
|
||||
.get(&signature)
|
||||
.map(|index| &mut self.functions[*index])
|
||||
.ok_or_else(|| FunctionError::NoOverload {
|
||||
expected: self.arg_map.keys().cloned().collect(),
|
||||
received: signature,
|
||||
received: ArgumentSignature::from(args),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
use crate::func::args::ArgInfo;
|
||||
use crate::func::{ArgList, SignatureInfo};
|
||||
use crate::Type;
|
||||
use bevy_utils::hashbrown::Equivalent;
|
||||
use core::borrow::Borrow;
|
||||
use core::fmt::{Debug, Formatter};
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
/// The signature of a function.
|
||||
|
@ -57,13 +59,69 @@ impl<T: Borrow<SignatureInfo>> From<T> for Signature {
|
|||
}
|
||||
}
|
||||
|
||||
/// A wrapper around a borrowed [`ArgList`] that can be used as an
|
||||
/// [equivalent] of an [`ArgumentSignature`].
|
||||
///
|
||||
/// [equivalent]: Equivalent
|
||||
pub(super) struct ArgListSignature<'a, 'b>(&'a ArgList<'b>);
|
||||
|
||||
impl Equivalent<ArgumentSignature> for ArgListSignature<'_, '_> {
|
||||
fn equivalent(&self, key: &ArgumentSignature) -> bool {
|
||||
self.len() == key.len() && self.iter().eq(key.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> ArgListSignature<'a, 'b> {
|
||||
pub fn iter(&self) -> impl ExactSizeIterator<Item = &Type> {
|
||||
self.0.iter().map(|arg| {
|
||||
arg.value()
|
||||
.get_represented_type_info()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("no `TypeInfo` found for argument: {:?}", arg);
|
||||
})
|
||||
.ty()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ArgListSignature<'_, '_> {}
|
||||
impl PartialEq for ArgListSignature<'_, '_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.len() == other.len() && self.iter().eq(other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for ArgListSignature<'_, '_> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.iter().for_each(|arg| {
|
||||
arg.value()
|
||||
.get_represented_type_info()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("no `TypeInfo` found for argument: {:?}", arg);
|
||||
})
|
||||
.ty()
|
||||
.hash(state);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> From<&'a ArgList<'b>> for ArgListSignature<'a, 'b> {
|
||||
fn from(args: &'a ArgList<'b>) -> Self {
|
||||
Self(args)
|
||||
}
|
||||
}
|
||||
|
||||
/// The argument-portion of a function signature.
|
||||
///
|
||||
/// For example, given a function signature `(a: i32, b: f32) -> u32`,
|
||||
/// the argument signature would be `(i32, f32)`.
|
||||
///
|
||||
/// This can be used as a way to compare or hash functions based on their arguments.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone)]
|
||||
pub struct ArgumentSignature(Box<[Type]>);
|
||||
|
||||
impl Debug for ArgumentSignature {
|
||||
|
@ -90,6 +148,20 @@ impl DerefMut for ArgumentSignature {
|
|||
}
|
||||
}
|
||||
|
||||
impl Eq for ArgumentSignature {}
|
||||
|
||||
impl PartialEq for ArgumentSignature {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.len() == other.0.len() && self.0.iter().eq(other.0.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for ArgumentSignature {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.0.iter().for_each(|ty| ty.hash(state));
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Type> for ArgumentSignature {
|
||||
fn from_iter<T: IntoIterator<Item = Type>>(iter: T) -> Self {
|
||||
Self(iter.into_iter().collect())
|
||||
|
|
Loading…
Reference in a new issue