bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Reduce uuid usage

Open bjorn3 opened this issue 3 years ago • 3 comments

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.

bjorn3 avatar Apr 27 '22 12:04 bjorn3

Alternative approach to #3992.

alice-i-cecile avatar May 02 '22 15:05 alice-i-cecile

Similarly, we should consider using an atomic rather than an RNG call when generating new HandleId, as discussed in the linked PR.

alice-i-cecile avatar Jul 14 '22 15:07 alice-i-cecile

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())
    }
}

MatrixDev avatar Jul 05 '24 11:07 MatrixDev