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 crate::func::{ArgList, FunctionError, FunctionInfo, FunctionOverloadError};
|
||||||
use alloc::borrow::Cow;
|
use alloc::borrow::Cow;
|
||||||
use bevy_utils::hashbrown::HashMap;
|
use bevy_utils::hashbrown::HashMap;
|
||||||
|
@ -62,13 +62,13 @@ impl<F> DynamicFunctionInternal<F> {
|
||||||
return Ok(&self.functions[0]);
|
return Ok(&self.functions[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signature = ArgumentSignature::from(args);
|
let signature = ArgListSignature::from(args);
|
||||||
self.arg_map
|
self.arg_map
|
||||||
.get(&signature)
|
.get(&signature)
|
||||||
.map(|index| &self.functions[*index])
|
.map(|index| &self.functions[*index])
|
||||||
.ok_or_else(|| FunctionError::NoOverload {
|
.ok_or_else(|| FunctionError::NoOverload {
|
||||||
expected: self.arg_map.keys().cloned().collect(),
|
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]);
|
return Ok(&mut self.functions[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signature = ArgumentSignature::from(args);
|
let signature = ArgListSignature::from(args);
|
||||||
self.arg_map
|
self.arg_map
|
||||||
.get(&signature)
|
.get(&signature)
|
||||||
.map(|index| &mut self.functions[*index])
|
.map(|index| &mut self.functions[*index])
|
||||||
.ok_or_else(|| FunctionError::NoOverload {
|
.ok_or_else(|| FunctionError::NoOverload {
|
||||||
expected: self.arg_map.keys().cloned().collect(),
|
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::args::ArgInfo;
|
||||||
use crate::func::{ArgList, SignatureInfo};
|
use crate::func::{ArgList, SignatureInfo};
|
||||||
use crate::Type;
|
use crate::Type;
|
||||||
|
use bevy_utils::hashbrown::Equivalent;
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::fmt::{Debug, Formatter};
|
use core::fmt::{Debug, Formatter};
|
||||||
|
use core::hash::{Hash, Hasher};
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/// The signature of a function.
|
/// 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.
|
/// The argument-portion of a function signature.
|
||||||
///
|
///
|
||||||
/// For example, given a function signature `(a: i32, b: f32) -> u32`,
|
/// For example, given a function signature `(a: i32, b: f32) -> u32`,
|
||||||
/// the argument signature would be `(i32, f32)`.
|
/// the argument signature would be `(i32, f32)`.
|
||||||
///
|
///
|
||||||
/// This can be used as a way to compare or hash functions based on their arguments.
|
/// 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]>);
|
pub struct ArgumentSignature(Box<[Type]>);
|
||||||
|
|
||||||
impl Debug for ArgumentSignature {
|
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 {
|
impl FromIterator<Type> for ArgumentSignature {
|
||||||
fn from_iter<T: IntoIterator<Item = Type>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = Type>>(iter: T) -> Self {
|
||||||
Self(iter.into_iter().collect())
|
Self(iter.into_iter().collect())
|
||||||
|
|
Loading…
Reference in a new issue