Skip to main content

ProjectVfs

Struct ProjectVfs 

Source
pub struct ProjectVfs {
    pub root: PathBuf,
    pub assets_root: PathBuf,
    pub asset_service: AssetService,
    pub watcher: AssetWatcher,
    file_loader: FileLoader,
    registry: AssetIdRegistry,
}
Expand description

All project I/O, in one place.

open performs a recursive scan of <root>/assets/, builds an in-memory VFS index (UUIDs derived from forward-slash relative paths via AssetUUID::new_v5), constructs the AssetService with every default decoder registered, and arms a recursive filesystem watcher for hot reload. UUIDs match what a future pack-builder would produce, so the dev/release transparency promise of the VFS is preserved.

Fields§

§root: PathBuf§assets_root: PathBuf§asset_service: AssetService§watcher: AssetWatcher§file_loader: FileLoader§registry: AssetIdRegistry

Stable-identity registry (<root>/.khora/asset-registry.ron). The editor is the sole writer: file operations freeze/rename/remove entries so an asset keeps its UUID across renames and every reference keeps resolving.

Implementations§

Source§

impl ProjectVfs

Source

pub fn open(root: PathBuf, metrics: Arc<MetricsRegistry>) -> Result<Self>

Opens (or creates) <root>/assets/, builds the VFS, and arms the watcher. Tolerates fresh projects whose assets/ directory hasn’t been populated yet — the resulting service has zero indexed assets, which is exactly what the asset browser will show.

Source

pub fn rebuild_index(&mut self) -> Result<()>

Re-walks <root>/assets/ and atomically swaps the VFS index. Called after a scene save (so the new file shows up) and from the hot-reload pump on Created/Removed events.

Source

pub fn read_project_json(&self) -> Result<Value>

Reads <root>/project.json as untyped JSON. Project metadata isn’t an asset (lives outside assets/) so it deliberately bypasses the VFS.

Source

pub fn write_asset(&self, rel_path: &Path, bytes: &[u8]) -> Result<()>

Writes bytes to <root>/assets/<rel_path>. Creates intermediate directories as needed. Caller is responsible for calling Self::rebuild_index afterwards if the new path needs to be resolvable through the VFS in the same frame.

Source

pub fn uuid_for_rel_path(rel_path_fwd_slash: &str) -> AssetUUID

Returns the UUID for a relative-path-with-forward-slashes string, regardless of whether the path currently exists on disk. Used by scene_io to look up scenes by canonical path even before a save has triggered a reindex.

This is the raw path-derived default and ignores the identity registry. Prefer Self::resolve_uuid whenever the asset may have been renamed (frozen identity); use this only for paths that cannot have a frozen entry (e.g. a file being written for the very first time).

Source

pub fn resolve_uuid(&self, rel_path_fwd_slash: &str) -> AssetUUID

Resolves a forward-slash relative path to its UUID through the identity registry: the frozen identity if the asset has been renamed, otherwise the new_v5 default. This is the registry-aware counterpart to Self::uuid_for_rel_path and must be used whenever an asset the user could have renamed is looked up by path (scene / prefab / material load).

Source

fn abs_of(&self, rel_fwd: &str) -> PathBuf

Absolute path of an asset given its forward-slash relative path.

Source

pub fn create_folder(&mut self, rel_dir: &str) -> Result<()>

Creates an (empty) folder under assets/ at rel_dir (forward-slash). Empty folders are surfaced by Self::list_dirs since the VFS itself only indexes files.

Source

pub fn rename_asset(&mut self, old_rel: &str, new_rel: &str) -> Result<()>

Renames/moves an asset from old_rel to new_rel (both forward-slash, under assets/), freezing its UUID so every existing reference keeps resolving. Fails if the destination already exists. Rebuilds the index.

Source

pub fn move_asset(&mut self, src_rel: &str, dest_dir: &str) -> Result<()>

Moves an asset into dest_dir (forward-slash folder, "" = assets root), keeping its file name. Thin wrapper over Self::rename_asset.

Source

pub fn delete_to_trash(&mut self, rel: &str) -> Result<()>

Sends an asset to the OS recycle bin (reversible), drops its registry entry, and rebuilds the index.

Source

pub fn duplicate_asset(&mut self, rel: &str) -> Result<String>

Duplicates an asset next to itself with a unique copy suffix. The copy is a new asset (no registry entry → fresh new_v5 identity). Returns the new forward-slash relative path.

Source

pub fn list_dirs(&self) -> Vec<String>

Lists every directory under assets/ as forward-slash relative paths (sorted, excluding the root). The VFS only indexes files, so empty folders — including freshly created ones — are only visible through this.

Source

pub fn poll_changes(&self) -> Vec<AssetChangeEvent>

Drains pending hot-reload events. Convenience wrapper so callers don’t need to reach through pvfs.watcher.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AppLifecycle for T
where T: ?Sized,

§

fn on_start(&mut self, ctx: &mut dyn AppContext)

Called once after the backend is up but before the first update. Apps install their theme / fonts here.
§

fn on_exit(&mut self)

Called once when the window is closing. Persist state here.
§

impl<T> AsAny for T
where T: Any,

§

fn as_any(&self) -> &(dyn Any + 'static)

Returns a reference to the inner value as &dyn Any.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(value: T, _simd: S) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,