Skip to content

Non-unique resource #10789

@stepancheg

Description

@stepancheg

What problem does this solve or what need does it fill?

Consider generic code connecting two systems:

// Pseudocode
fn connect<V>(a: impl System<Out = V>, b: impl System<In = V>) -> (impl System, impl System) {
  let resource = ???
  let a = a.pipe(|v| resource.write(v));
  let b = (|| resource.read()).pipe(b);
  (a, b)
}

Currently it is not trivial to implement, because as far as I understand there's no API to allocate such resource. Such resource can be allocated outside of bevy, and some mutex can be used to make access safe.

But it would be nicer if there was some API in Bevy to implement it.

What solution would you like?

Public API:

#[derive(Clone, Copy)]
struct NonUniqueResourceRef<T> { ... }

impl World {
  fn new_non_unique_resource<T>(&mut self) -> NonUniqueResourceRef<T> { ... }
}

impl NonUniqueResourceRef<T> {
  // System that writes to the resource. Tells the schedule it requires unique access to this resource instance (not all of T)
  fn write_system(&self) -> impl System<In = T> { ... }

  fn read_system(&self) -> impl System<Out = T> { ... }
}

Internally it is implemented as:

struct NonUniqueResourceRef<T> {
  component_id: ComponentId, // Unique per NonUniqueResourceRef<T>
  index: usize, // Index in table per T
  archetype_component_id: ArchetypeComponentId, // to allow mutable access to T with different indices
}

struct Storages {
  ...
  non_unique_resources: SparseSet<ComponentId, Table>,
}

What alternative(s) have you considered?

  • Use resource Vec<T> and index, but that reduces parallelism
  • Allocate outside of bevy, use mutex for safety, synchronize access using before/after
  • pass unique type marker to each call to connect allocate regular resource

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleX-ControversialThere is active debate or serious implications around merging this PR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions