Skip to content

Commit

Permalink
Merge pull request #64 from amethyst/indirect_handles
Browse files Browse the repository at this point in the history
Added support for Indirect handles & reworked Loader APIs
  • Loading branch information
kabergstrom authored Nov 8, 2020
2 parents 3243f50 + afa9176 commit 32cf0bd
Show file tree
Hide file tree
Showing 42 changed files with 2,731 additions and 2,358 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ atelier-loader = { version = "0.1", path = "loader" }
[features]
serde-1 = ["atelier-core/serde"]
asset_uuid_macro = ["atelier-core/asset_uuid_macro"]
type_uuid = ["atelier-core/type_uuid"]
serde_importers = ["atelier-importer/serde_importers"]
parallel_hash = [ "atelier-daemon/parallel_hash" ]
pretty_log = [ "atelier-daemon/pretty_log" ]
rpc_loader = ["atelier-loader/rpc_loader"]
rpc_io = ["atelier-loader/rpc_io"]
handle = ["atelier-loader/handle"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The Daemon watches for filesystem events, imports source files to produce assets
<details><summary>&check; <b>Asset Change Log</b></summary><p>Asset metadata is maintained in LMDB, a transactional database. The database's consistency guarantees and snapshot support provides a way to synchronize external data stores with the current state of the asset metadata using the Asset Change Log of asset changes.</p></details>
<details><summary>&check; <b>Metadata Tracking & Caching</b></summary><p>When assets are imported from source files, metadata is generated and stored in `.meta` files together with source file, as well as cached in a database. Commit these to version control along with your source files.</p></details>
<details><summary>&check; <b>Move & Rename Source Files Confidently</b></summary><p>Since metadata is stored with the source file and UUIDs are used to identify individual assets, users can move, rename and share source files with others without breaking references between assets.</p></details>
<details><summary>&check; <b>Bring Your Own Asset Types</b></summary><p>Asset types are not included in this project. You define your own asset types and source file formats by implementing the `Importer` trait and registering these with a file extension. The Daemon will automatically run your `Importer` for files with the registered extension as required. All asset types must implement `serde::Serialize` + `serde::Deserialize` + `type_uuid::TypeUuidDynamic` + `Send`.</p></details>
<details><summary>&check; <b>Bring Your Own Asset Types</b></summary><p>Asset types are not included in this project. You define your own asset types and source file formats by implementing the `Importer` trait and registering these with a file extension. The Daemon will automatically run your `Importer` for files with the registered extension as required. All asset types must implement `serde::Serialize` + `serde::Deserialize` + `TypeUuidDynamic` + `Send`.</p></details>
<details><summary>&check; <b>RON Importer</b> - *OPTIONAL*</summary><p>An optional Importer and derive macro is included to simplify usage of serialized Rust types as source files using `serde`.

Type definition:
Expand Down
19 changes: 18 additions & 1 deletion cli/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ pub struct Shell<C> {
ctx: C,
}

#[derive(Debug)]
struct Exit;
impl std::error::Error for Exit {}
impl std::fmt::Display for Exit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "exit")
}
}

impl<C> Shell<C> {
pub fn new(ctx: C) -> Self {
Self {
Expand Down Expand Up @@ -107,7 +116,9 @@ impl<C> Shell<C> {
for (cmd_key, cmd) in commands {
println!(" {} {}\r", cmd_key, cmd.desc());
}
println!(" quit\r");
}
Some("exit") | Some("quit") => Err(Exit)?,
Some(_) => println!("Unknown command\r"),
None => {}
}
Expand Down Expand Up @@ -293,7 +304,13 @@ impl<C> Shell<C> {
})),
) => {
println!("\r");
self.execute_command(&line).await?;
match self.execute_command(&line).await {
Err(err) if err.downcast_ref::<Exit>().is_some() => {
break 'repl_loop
}
Err(err) => Err(err)?,
Ok(_) => {}
}
history.push(line.trim().to_owned());
line.clear();
fut_autocomplete = None;
Expand Down
3 changes: 3 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ license = "MIT OR Apache-2.0"
[features]
serde-1 = ["serde"]
asset_uuid_macro = ["asset-uuid"]
type_uuid = ["type-uuid"]

[dependencies]
uuid = { version = "0.8", features = [ "v4" ] }
asset-uuid = { path = "./asset-uuid", version = "0.1.0", optional = true }
serde = { version = "1.0", optional = true, features = ["derive"] }
futures-core = { version = "0.3", default-features = false, features = ["alloc"] }
type-uuid = { version = "0.1", optional = true, default-features = false }

[dev-dependencies]
type-uuid = "0.1"
serde_json = "1.0"
bincode = "1.3"
63 changes: 60 additions & 3 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub mod importer_context;
pub mod utils;

/// A universally unique identifier for an asset.
/// An asset can be an instance of any Rust type that implements
/// [type_uuid::TypeUuid] + [serde::Serialize] + [Send].
/// An asset can be a value of any Rust type that implements
/// [`TypeUuidDynamic`] + [serde::Serialize] + [Send].
///
/// If using a human-readable format, serializes to a hyphenated UUID format and deserializes from
/// any format supported by the `uuid` crate. Otherwise, serializes to and from a `[u8; 16]`.
Expand Down Expand Up @@ -88,7 +88,7 @@ impl<'de> Deserialize<'de> for AssetUuid {
}
}

/// UUID of an asset's Rust type. Produced by [type_uuid::TypeUuid::UUID].
/// UUID of an asset's Rust type. Produced by [`TypeUuidDynamic::uuid`].
///
/// If using a human-readable format, serializes to a hyphenated UUID format and deserializes from
/// any format supported by the `uuid` crate. Otherwise, serializes to and from a `[u8; 16]`.
Expand Down Expand Up @@ -190,3 +190,60 @@ impl Default for CompressionType {
Self::None
}
}

/// Serializable metadata for an asset.
/// Stored in .meta files and metadata DB.
#[derive(Debug, Clone, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct AssetMetadata {
/// UUID for the asset to uniquely identify it
pub id: AssetUuid,
/// Search tags are used by asset tooling to search for the imported asset
pub search_tags: Vec<(String, Option<String>)>,
/// The referenced build pipeline is invoked when a build artifact is requested for the imported asset
pub build_pipeline: Option<AssetUuid>,
/// The latest artifact produced when importing this asset
pub artifact: Option<ArtifactMetadata>,
}

/// 64-bit hash of the inputs that would produce a given asset artifact
#[derive(Debug, Copy, Clone, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ArtifactId(pub u64);

/// Serializable metadata for an artifact.
/// Stored in .meta files and metadata DB.
#[derive(Debug, Clone, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ArtifactMetadata {
/// Hash that identifies this artifact
pub id: ArtifactId,
/// UUID for this artifact's asset
pub asset_id: AssetUuid,
/// Build dependencies will be included in the Builder arguments when building an asset
pub build_deps: Vec<AssetRef>,
/// Load dependencies are guaranteed to load before this asset by the Loader
pub load_deps: Vec<AssetRef>,
/// Type of compression used to compress this artifact
pub compression: CompressionType,
/// Size of this artifact in bytes when compressed
pub compressed_size: Option<u64>,
/// Size of this artifact in bytes when serialized and uncompressed
pub uncompressed_size: Option<u64>,
/// The UUID of the artifact's Rust type
pub type_id: AssetTypeId,
}

/// Provides a unique 16-byte ID for a value's type.
pub trait TypeUuidDynamic {
fn uuid(&self) -> [u8; 16];
}

#[cfg(feature = "type_uuid")]
impl<T: type_uuid::TypeUuidDynamic> TypeUuidDynamic for T {
fn uuid(&self) -> [u8; 16] {
<Self as type_uuid::TypeUuidDynamic>::uuid(self)
}
}
#[cfg(feature = "type_uuid")]
pub use type_uuid;
6 changes: 3 additions & 3 deletions daemon/src/artifact_cache.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::capnp_db::{DBTransaction, Environment, MessageReader, RoTransaction, RwTransaction};
use crate::error::Result;
use atelier_importer::SerializedAsset;
use atelier_schema::data::artifact;
use atelier_schema::{build_artifact_metadata, data::artifact};
use std::sync::Arc;

pub struct ArtifactCache {
Expand Down Expand Up @@ -44,7 +44,7 @@ impl ArtifactCache {
) {
txn.put(
self.tables.hash_to_artifact,
&artifact.metadata.hash.to_le_bytes(),
&artifact.metadata.id.0.to_le_bytes(),
&build_artifact_message(artifact),
)
.expect("lmdb: failed to put path ref");
Expand Down Expand Up @@ -88,7 +88,7 @@ fn build_artifact_message<T: AsRef<[u8]>>(
{
let mut m = value_builder.init_root::<artifact::Builder<'_>>();
let mut metadata = m.reborrow().init_metadata();
crate::asset_hub::build_artifact_metadata(&artifact.metadata, &mut metadata);
build_artifact_metadata(&artifact.metadata, &mut metadata);
let slice: &[u8] = artifact.data.as_ref();
m.reborrow().set_data(slice);
}
Expand Down
Loading

0 comments on commit 32cf0bd

Please sign in to comment.