Reduce uuid usage
The fast majority of the cases only need a locally unique id and not a universally unique id as they are never serialized or imported. Using a counter in those cases would likely be faster than generating a random number. It may also allow reducing the size from 128bit to 64bit. There are a couple of user facing uuid's like type uuid's that actually need to be universally unique. For them we should keep using uuid's or consider switching to random 128bit integers that are not necessarily valid uuid's.
Alternative approach to #3992.
Similarly, we should consider using an atomic rather than an RNG call when generating new HandleId, as discussed in the linked PR.
Just in case someone come here for the same reason.
I don't like this "random big number" thing as well and genereting it for every shader is just PITA. So I wrote a helper on my project, maybe someone will find it useful:
pub struct GlobalHandle<T: Asset> {
cell: OnceLock<Handle<T>>,
}
impl<T: Asset> GlobalHandle<T> {
pub const fn new() -> Self {
Self { cell: OnceLock::new() }
}
pub fn get(&self) -> Handle<T> {
static COUNTER: AtomicU64 = AtomicU64::new(0);
let handle = self.cell.get_or_init(|| {
let base = <<random project wise big number>>;
let diff = COUNTER.fetch_add(1, Ordering::Relaxed);
Handle::<T>::weak_from_u128(base + u128::from(diff))
});
handle.clone()
}
#[inline(always)]
fn assets_mut<'a>(&self, app: &'a mut App) -> Mut<'a, Assets<T>> {
app.world_mut().resource_mut()
}
}
impl GlobalHandle<Shader> {
#[track_caller]
pub fn set_shader(&self, app: &mut App, code: &'static str) {
let shader = Shader::from_wgsl(code, Location::caller().to_string());
let handle = self.get();
self.assets_mut(app).insert(handle.id(), shader);
}
}
And than it is very easy to use in all other places:
static SHADER: GlobalHandle<Shader> = GlobalHandle::new();
impl Plugin for XxxPlugin {
fn build(&self, app: &mut App) {
SHADER.set_shader(app, include_str!("shader.wgsl"));
}
}
impl Material for XxxMaterial {
fn fragment_shader() -> ShaderRef {
ShaderRef::Handle(SHADER.get())
}
}