diff --git a/.cargo/config.toml b/.cargo/config.toml
index f62914b032..7bce1fe226 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -135,5 +135,16 @@ opt-level = 3
debug = true
debug-assertions = false
+[profile.dev.package.image]
+opt-level = 3
+debug = true
+debug-assertions = false
+
+[profile.dev.package.gltf]
+opt-level = 3
+debug = true
+debug-assertions = false
+
+
[env]
LGN_TELEMETRY_GRPC_API_KEY = "296bb99c-6921-4233-a353-a29c1045b5f2"
diff --git a/.vscode/legionlabs.natvis b/.vscode/legionlabs.natvis
index cb22fedde1..b8621b4b22 100644
--- a/.vscode/legionlabs.natvis
+++ b/.vscode/legionlabs.natvis
@@ -29,7 +29,8 @@
offline_model({__0,x})
runtime_model({__0,x})
gltf({__0,x})
-
+ export_gltf({__0,x})
+
{__0,x}
diff --git a/Cargo.lock b/Cargo.lock
index b582b84f46..d777ed6459 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4104,35 +4104,7 @@ dependencies = [
]
[[package]]
-name = "lgn-compiler-gltf2mat"
-version = "0.1.0"
-dependencies = [
- "async-trait",
- "gltf",
- "lgn-content-store",
- "lgn-data-compiler",
- "lgn-data-offline",
- "lgn-data-runtime",
- "lgn-graphics-data",
- "tokio",
-]
-
-[[package]]
-name = "lgn-compiler-gltf2model"
-version = "0.1.0"
-dependencies = [
- "async-trait",
- "gltf",
- "lgn-content-store",
- "lgn-data-compiler",
- "lgn-data-offline",
- "lgn-data-runtime",
- "lgn-graphics-data",
- "tokio",
-]
-
-[[package]]
-name = "lgn-compiler-gltf2tex"
+name = "lgn-compiler-gltf"
version = "0.1.0"
dependencies = [
"async-trait",
@@ -4141,6 +4113,8 @@ dependencies = [
"lgn-data-offline",
"lgn-data-runtime",
"lgn-graphics-data",
+ "lgn-telemetry-sink",
+ "lgn-tracing",
"tokio",
]
@@ -4652,6 +4626,7 @@ name = "lgn-data-transaction"
version = "0.1.0"
dependencies = [
"async-trait",
+ "crossbeam-channel",
"erased-serde",
"futures-lite",
"generic-data",
@@ -5519,9 +5494,7 @@ name = "lgn-ubercompiler"
version = "0.1.0"
dependencies = [
"async-trait",
- "lgn-compiler-gltf2mat",
- "lgn-compiler-gltf2model",
- "lgn-compiler-gltf2tex",
+ "lgn-compiler-gltf",
"lgn-compiler-material",
"lgn-compiler-png2tex",
"lgn-compiler-psd2tex",
@@ -7817,6 +7790,7 @@ dependencies = [
"bincode",
"clap 3.1.18",
"generic-data",
+ "gltf",
"lgn-config",
"lgn-content-store",
"lgn-data-build",
diff --git a/crates/lgn-data-build/src/databuild.rs b/crates/lgn-data-build/src/databuild.rs
index 4eb4a1df86..fbcb836746 100644
--- a/crates/lgn-data-build/src/databuild.rs
+++ b/crates/lgn-data-build/src/databuild.rs
@@ -1,5 +1,5 @@
use std::{
- collections::{HashMap, HashSet},
+ collections::{hash_map::Entry, HashMap, HashSet},
env,
hash::{Hash, Hasher},
io,
@@ -451,18 +451,34 @@ impl DataBuild {
};
let mut compiler_details = HashMap::new();
- for t in unique_transforms {
- let (transform, res_path_id) = t;
- let (compiler, transform) = self
- .compilers
- .compilers()
- .find_compiler(transform)
- .ok_or(Error::CompilerNotFound(transform, res_path_id))?;
- let compiler_hash = compiler
- .compiler_hash(transform, env)
- .await
- .map_err(|e| Error::Io(e.into()))?;
- compiler_details.insert(transform, (compiler, compiler_hash));
+ for (transform, res_path_id) in unique_transforms {
+ // Insert a identity compiler if one exists
+ let identity_transform = transform.as_identity();
+ if let Some((identity_compiler, _transform)) =
+ self.compilers.compilers().find_compiler(identity_transform)
+ {
+ if let Entry::Vacant(e) = compiler_details.entry(identity_transform) {
+ let compiler_hash = identity_compiler
+ .compiler_hash(identity_transform, env)
+ .await
+ .map_err(|e| Error::Io(e.into()))?;
+ e.insert((identity_compiler, compiler_hash));
+ }
+ } else if let Entry::Vacant(e) = compiler_details.entry(transform) {
+ let (compiler, _transform) = self
+ .compilers
+ .compilers()
+ .find_compiler(transform)
+ .ok_or_else(|| {
+ lgn_tracing::error!("Compiler not found {}", transform);
+ Error::CompilerNotFound(transform, res_path_id)
+ })?;
+ let compiler_hash = compiler
+ .compiler_hash(transform, env)
+ .await
+ .map_err(|e| Error::Io(e.into()))?;
+ e.insert((compiler, compiler_hash));
+ }
}
compiler_details
};
@@ -477,7 +493,7 @@ impl DataBuild {
// in the future this should be improved.
//
let mut accumulated_dependencies = vec![];
- let mut node_hash = HashMap::<_, (AssetHash, AssetHash)>::new();
+ let mut node_hash = HashMap::<_, (AssetHash, AssetHash, ResourcePathId)>::new();
let mut compiled_at_node = HashMap::::new();
let mut compiled = HashSet::::new();
@@ -579,36 +595,54 @@ impl DataBuild {
let mut new_work = vec![];
let num_ready = ready.len();
for compile_node_index in ready {
- let compile_node = build_graph.node_weight(compile_node_index).unwrap();
+ let source_node = build_graph.node_weight(compile_node_index).unwrap().clone();
info!(
"Progress({:?}): {:?} is ready",
- compile_node_index, compile_node
+ compile_node_index, source_node
);
- // compile non-source dependencies.
- if let Some(direct_dependency) = compile_node.direct_dependency() {
- let mut n =
- build_graph.neighbors_directed(compile_node_index, petgraph::Incoming);
- let direct_dependency_index = n.next().unwrap();
-
- // only one direct dependency supported now. it's ok for the path
- // but it needs to be revisited for source (if this ever applies to source).
- assert!(n.next().is_none());
-
- assert_eq!(
- &direct_dependency,
- build_graph.node_weight(direct_dependency_index).unwrap()
- );
- let transform = compile_node.last_transform().unwrap();
+ let compile_node = if let Some(transform) = source_node.last_transform() {
+ // If there's no compiler for this operation but there's an Identity transform on the source, use it instead
+ if compiler_details.get(&transform).is_none()
+ && compiler_details.get(&transform.as_identity()).is_some()
+ {
+ ResourcePathId::from(source_node.source_resource())
+ .push(source_node.source_resource().kind)
+ } else {
+ source_node.clone()
+ }
+ } else {
+ // If it's a source node but there's an Identity compiler, replace with Identity transform
+ let identity_transform = ResourcePathId::from(source_node.source_resource())
+ .push(source_node.source_resource().kind);
+ if let Some((_compiler, _compiler_hash)) =
+ compiler_details.get(&identity_transform.last_transform().unwrap())
+ {
+ identity_transform
+ } else {
+ source_node.clone()
+ }
+ };
- // 'name' is dropped as we always compile input as a whole.
- let expected_name = compile_node.name();
+ // compile non-source dependencies.
+ if let Some(direct_dependency) = compile_node.direct_dependency() {
let compile_node = compile_node.to_unnamed();
// check if the unnamed ResourcePathId has been already compiled and early out.
if let Some(node_index) = compiled_at_node.get(&compile_node) {
- node_hash.insert(compile_node_index, *node_hash.get(node_index).unwrap());
+ node_hash.insert(
+ compile_node_index,
+ node_hash.get(node_index).unwrap().clone(),
+ );
+
+ let unnamed = source_node.to_unnamed();
+ info!(
+ "Source({:?}) Completed '{}' (reusing result from {:?})",
+ compile_node_index, source_node, node_index
+ );
compiled.insert(compile_node_index);
+ compiling_unnamed.remove(&unnamed);
+ compiled_unnamed.insert(unnamed);
continue;
}
@@ -629,13 +663,6 @@ impl DataBuild {
.find_dependencies(&direct_dependency)
.unwrap_or_default();
- let (compiler, compiler_hash) = *compiler_details.get(&transform).unwrap();
-
- // todo: not sure if transform is the right thing here. resource_path_id better?
- // transform is already defined by the compiler_hash so it seems redundant.
- let context_hash =
- compute_context_hash(transform, compiler_hash, Self::version());
-
let source_hash = {
if direct_dependency.is_source() {
//
@@ -654,19 +681,24 @@ impl DataBuild {
// resource should not read any other resources - but right now
// `accumulated_dependencies` allows to read much more.
//
- let (dep_context_hash, dep_source_hash) =
+ let mut n = build_graph
+ .neighbors_directed(compile_node_index, petgraph::Incoming);
+ let direct_dependency_index = n.next().unwrap();
+ let (dep_context_hash, dep_source_hash, dep_path) =
node_hash.get(&direct_dependency_index).unwrap();
// we can assume there are results of compilation of the `direct_dependency`
let compiled = self
.output_index
- .find_compiled(
- &direct_dependency.to_unnamed(),
- *dep_context_hash,
- *dep_source_hash,
- )
+ .find_compiled(dep_path, *dep_context_hash, *dep_source_hash)
.await
- .unwrap()
+ .ok_or_else(|| {
+ lgn_tracing::error!(
+ "Output not present for {}",
+ &direct_dependency
+ );
+ Error::OutputNotPresent(direct_dependency.clone(), "".into())
+ })?
.0;
// can we assume there is a result of a requested name?
// probably no, this should return a compile error.
@@ -687,7 +719,22 @@ impl DataBuild {
}
};
- node_hash.insert(compile_node_index, (context_hash, source_hash));
+ // Find the compiler and compiler_hash from the last transform
+ let transform = compile_node.last_transform().unwrap();
+ let (compiler, context_hash) =
+ if let Some((compiler, compiler_hash)) = compiler_details.get(&transform) {
+ (
+ *compiler,
+ compute_context_hash(transform, *compiler_hash, Self::version()),
+ )
+ } else {
+ return Err(Error::CompilerNotFound(transform, compile_node.clone()));
+ };
+
+ node_hash.insert(
+ compile_node_index,
+ (context_hash, source_hash, compile_node.clone()),
+ );
let output_index = &self.output_index;
let data_content_provider = Arc::clone(&self.data_content_provider);
@@ -703,7 +750,9 @@ impl DataBuild {
> = async move {
info!(
"Compiling({:?}) {} ({:?}) ...",
- compile_node_index, compile_node, expected_name
+ compile_node_index,
+ compile_node,
+ compile_node.name()
);
let start = std::time::Instant::now();
@@ -723,7 +772,10 @@ impl DataBuild {
resources.clone(),
)
.await
- .map_err(|e| (compile_node_index, e))?;
+ .map_err(|e| {
+ lgn_tracing::error!("Failed to compile: {}", e);
+ (compile_node_index, e)
+ })?;
info!(
"Compiled({:?}) {:?} ended in {:?}.",
diff --git a/crates/lgn-data-compiler/src/compiler_api.rs b/crates/lgn-data-compiler/src/compiler_api.rs
index b4a845fe86..97f7c31329 100644
--- a/crates/lgn-data-compiler/src/compiler_api.rs
+++ b/crates/lgn-data-compiler/src/compiler_api.rs
@@ -396,14 +396,15 @@ async fn get_transform_hash(
env: &CompilationEnv,
transform: Transform,
) -> Result {
- let (compiler, transform) = compilers
- .find_compiler(transform)
- .ok_or(CompilerError::CompilerNotFound(transform))?;
+ let (compiler, transform) = compilers.find_compiler(transform).ok_or_else(|| {
+ lgn_tracing::error!("Not found");
+ CompilerError::CompilerNotFound(transform)
+ })?;
- let compiler_hash = compiler
- .compiler_hash(transform, env)
- .await
- .map_err(|_e| CompilerError::CompilerNotFound(transform))?;
+ let compiler_hash = compiler.compiler_hash(transform, env).await.map_err(|e| {
+ lgn_tracing::error!("{}", e);
+ CompilerError::CompilerNotFound(transform)
+ })?;
Ok(compiler_hash)
}
@@ -508,9 +509,10 @@ async fn run(command: Commands, compilers: CompilerRegistry) -> Result<(), Compi
};
let registry = {
- let (compiler, _) = compilers
- .find_compiler(transform)
- .ok_or(CompilerError::CompilerNotFound(transform))?;
+ let (compiler, _) = compilers.find_compiler(transform).ok_or_else(|| {
+ lgn_tracing::error!("Compiler not found");
+ CompilerError::CompilerNotFound(transform)
+ })?;
let registry = AssetRegistryOptions::new()
.add_device_cas(Arc::clone(&data_provider), runtime_manifest_id.clone())
@@ -524,10 +526,10 @@ async fn run(command: Commands, compilers: CompilerRegistry) -> Result<(), Compi
let shell = CompilerNode::new(compilers, registry);
- let (compiler, _) = shell
- .compilers()
- .find_compiler(transform)
- .ok_or(CompilerError::CompilerNotFound(transform))?;
+ let (compiler, _) = shell.compilers().find_compiler(transform).ok_or_else(|| {
+ lgn_tracing::error!("Compiler not found");
+ CompilerError::CompilerNotFound(transform)
+ })?;
let compilation_output = compiler
.compile(
diff --git a/crates/lgn-data-compiler/src/compiler_node/compiler_registry.rs b/crates/lgn-data-compiler/src/compiler_node/compiler_registry.rs
index 78ec88b6e7..69a0559d75 100644
--- a/crates/lgn-data-compiler/src/compiler_node/compiler_registry.rs
+++ b/crates/lgn-data-compiler/src/compiler_node/compiler_registry.rs
@@ -161,11 +161,9 @@ impl fmt::Debug for CompilerRegistry {
impl CompilerRegistry {
/// Returns a reference to the compiler
pub fn find_compiler(&self, transform: Transform) -> Option<(&dyn CompilerStub, Transform)> {
- if let Some(compiler_index) = self
- .infos
- .iter()
- .position(|info| info.transform == transform)
- {
+ if let Some(compiler_index) = self.infos.iter().position(|info| {
+ info.transform == transform || info.transform.is_wildcard_for(&transform)
+ }) {
let stub_index = self.indices[compiler_index];
return Some((self.compilers[stub_index].as_ref(), transform));
}
diff --git a/crates/lgn-data-compiler/src/compiler_node/inproc_stub.rs b/crates/lgn-data-compiler/src/compiler_node/inproc_stub.rs
index 1fe5acdbe8..e62f905923 100644
--- a/crates/lgn-data-compiler/src/compiler_node/inproc_stub.rs
+++ b/crates/lgn-data-compiler/src/compiler_node/inproc_stub.rs
@@ -33,7 +33,9 @@ impl CompilerStub for InProcessCompilerStub {
transform: Transform,
env: &CompilationEnv,
) -> io::Result {
- if transform != *self.descriptor.transform {
+ if transform != *self.descriptor.transform
+ && !self.descriptor.transform.is_wildcard_for(&transform)
+ {
return Err(io::Error::new(io::ErrorKind::Other, "Transform mismatch"));
}
let hash = self
diff --git a/crates/lgn-data-compiler/tests/compile.rs b/crates/lgn-data-compiler/tests/compile.rs
index 59506c8c74..9cc8c65b84 100644
--- a/crates/lgn-data-compiler/tests/compile.rs
+++ b/crates/lgn-data-compiler/tests/compile.rs
@@ -103,7 +103,7 @@ async fn compile_intermediate() {
kind: TextResource::TYPE,
id: ResourceId::new(),
};
- let mut resource = TextResource::new_named("test_resource");
+ let mut resource = TextResource::new_with_id("test_resource", source);
resource.content = source_magic_value.clone();
let source_manifest_id =
diff --git a/crates/lgn-data-runtime/src/asset_registry.rs b/crates/lgn-data-runtime/src/asset_registry.rs
index 9b80358844..d307cada96 100644
--- a/crates/lgn-data-runtime/src/asset_registry.rs
+++ b/crates/lgn-data-runtime/src/asset_registry.rs
@@ -255,6 +255,12 @@ pub enum AssetRegistryScheduling {
AssetRegistryCreated,
}
+/// Message to notifying `AssetRegistry` Operation
+pub enum AssetRegistryMessage {
+ /// Sent when resources changed
+ ChangedResources(Vec),
+}
+
/// Async reader type for `AssetRegistry`/`AssetLoader`
pub type AssetRegistryReader = Pin>;
@@ -264,11 +270,14 @@ impl AssetRegistry {
}
/// Trigger a reload of a given primary resource.
- pub async fn reload(&self, resource_id: ResourceTypeAndId) {
+ /// # Errors
+ /// Return `AssetRegistryError` on failure
+ pub async fn reload(
+ &self,
+ resource_id: ResourceTypeAndId,
+ ) -> Result {
let future = self.new_load_request(resource_id);
- if let Err(err) = future.await {
- lgn_tracing::error!("Reload failed: {}", err);
- }
+ future.await
}
pub(crate) fn mark_for_cleanup(&self, key: AssetRegistryHandleKey) {
@@ -291,6 +300,7 @@ impl AssetRegistry {
Some(self.lookup_untyped(resource_id)?.into())
}
+ // TODO: replace with Arc
fn arc_self(&self) -> Arc {
let registry = unsafe { Arc::from_raw(self as *const Self) };
let result = registry.clone();
diff --git a/crates/lgn-data-runtime/src/lib.rs b/crates/lgn-data-runtime/src/lib.rs
index 166a4dcd45..935382adc5 100644
--- a/crates/lgn-data-runtime/src/lib.rs
+++ b/crates/lgn-data-runtime/src/lib.rs
@@ -99,9 +99,9 @@ pub use resource_installer::*;
pub mod prelude {
#[doc(hidden)]
pub use crate::{
- AssetRegistry, AssetRegistryError, AssetRegistryOptions, AssetRegistryReader, Component,
- ComponentInstaller, EditHandle, EditHandleUntyped, Handle, HandleUntyped, LoadRequest,
- Resource, ResourceDescriptor, ResourceId, ResourceInstaller, ResourcePathId, ResourceType,
- ResourceTypeAndId, Transform,
+ AssetRegistry, AssetRegistryError, AssetRegistryMessage, AssetRegistryOptions,
+ AssetRegistryReader, Component, ComponentInstaller, EditHandle, EditHandleUntyped, Handle,
+ HandleUntyped, LoadRequest, Resource, ResourceDescriptor, ResourceId, ResourceInstaller,
+ ResourcePathId, ResourceType, ResourceTypeAndId, Transform,
};
}
diff --git a/crates/lgn-data-runtime/src/resource.rs b/crates/lgn-data-runtime/src/resource.rs
index 4441590c06..6aeabe7db8 100644
--- a/crates/lgn-data-runtime/src/resource.rs
+++ b/crates/lgn-data-runtime/src/resource.rs
@@ -41,8 +41,8 @@ pub async fn from_binary_reader<'de, T: Resource + Default + serde::Deserialize<
/// Write a Resource to a binary stream
/// # Errors
/// Return `AssetRegistryError` on failure
-pub fn to_binary_writer(
- resource: &dyn Resource,
+pub fn to_binary_writer(
+ resource: &T,
writer: &mut dyn std::io::Write,
) -> Result<(), AssetRegistryError> {
let mut bincode_ser = bincode::Serializer::new(
@@ -51,8 +51,9 @@ pub fn to_binary_writer(
.allow_trailing_bytes()
.with_fixint_encoding(),
);
- let mut serializer = ::erase(&mut bincode_ser);
- lgn_data_model::utils::serialize_property_by_name(resource.as_reflect(), "", &mut serializer)?;
+ resource
+ .serialize(&mut bincode_ser)
+ .map_err(|_err| AssetRegistryError::Generic("bincode serialize error".into()))?;
Ok(())
}
diff --git a/crates/lgn-data-runtime/src/resourcepathid.rs b/crates/lgn-data-runtime/src/resourcepathid.rs
index 3e503198e9..4f1e2fff17 100644
--- a/crates/lgn-data-runtime/src/resourcepathid.rs
+++ b/crates/lgn-data-runtime/src/resourcepathid.rs
@@ -16,6 +16,20 @@ impl Transform {
pub const fn new(from: ResourceType, to: ResourceType) -> Self {
Self { from, to }
}
+
+ /// Wildcard
+ pub fn is_wildcard_for(&self, transform: &Transform) -> bool {
+ self.from == self.to && self.from == transform.from
+ }
+
+ /// To Identity transform
+ #[must_use]
+ pub fn as_identity(&self) -> Self {
+ Self {
+ from: self.from,
+ to: self.from,
+ }
+ }
}
impl fmt::Display for Transform {
diff --git a/crates/lgn-data-transaction/Cargo.toml b/crates/lgn-data-transaction/Cargo.toml
index aae1bfbf4e..b94f13f912 100644
--- a/crates/lgn-data-transaction/Cargo.toml
+++ b/crates/lgn-data-transaction/Cargo.toml
@@ -26,6 +26,7 @@ thiserror = "1.0"
tokio = { version = "1.13", features = ["full", "tracing"] }
async-trait = "0.1"
futures-lite = "1.12"
+crossbeam-channel = "0.5.1"
[dev-dependencies]
lgn-compiler-testentity = { path = "../../tests/testentity-compiler" }
diff --git a/crates/lgn-data-transaction/src/lock_context.rs b/crates/lgn-data-transaction/src/lock_context.rs
index fa96bf3a0e..4d084abc61 100644
--- a/crates/lgn-data-transaction/src/lock_context.rs
+++ b/crates/lgn-data-transaction/src/lock_context.rs
@@ -69,20 +69,24 @@ impl<'a> LockContext<'a> {
changed.get_or_insert(Vec::new()).push(id);
}
- /*for resource_id in &self.changed_resources {
+ for resource_id in changed.iter().flatten() {
match self
.build
.build_all_derived(*resource_id, &self.project)
.await
{
- Ok((runtime_path_id, _built_resources)) => {
- self.asset_registry.reload(runtime_path_id.resource_id());
+ Ok((runtime_path_id, built_resources)) => {
+ lgn_tracing::info!(
+ "Rebuilt {} ({} deps)",
+ runtime_path_id,
+ built_resources.len()
+ );
}
Err(e) => {
- error!("Error building resource derivations {:?}", e);
+ lgn_tracing::error!("Error building resource derivations {:?}", e);
}
}
- }*/
+ }
Ok(changed)
}
diff --git a/crates/lgn-data-transaction/src/transaction.rs b/crates/lgn-data-transaction/src/transaction.rs
index 9b85988392..134c0bbb04 100644
--- a/crates/lgn-data-transaction/src/transaction.rs
+++ b/crates/lgn-data-transaction/src/transaction.rs
@@ -56,9 +56,10 @@ impl Transaction {
// All the ops complete, the the resources
let changed = context.save_changed_resources().await?;
let mut log = format!(
- "Transaction Applied: {} / {}ops",
+ "Transaction Applied: {} / {}ops ({} changed)",
&self.id,
- self.operations.len()
+ self.operations.len(),
+ changed.as_ref().map_or(0, Vec::len)
);
if lgn_config::get_or("data_transaction.log_operation", false).unwrap() {
@@ -99,9 +100,10 @@ impl Transaction {
// All the ops complete, the the resources
let changed = context.save_changed_resources().await?;
info!(
- "Transaction Rollbacked: {} / {}ops",
+ "Transaction Rollbacked: {} / {}ops ({} changed)",
&self.id,
- self.operations.len()
+ self.operations.len(),
+ changed.as_ref().map_or(0, Vec::len)
);
Ok(changed)
}
diff --git a/crates/lgn-data-transaction/src/transaction_manager.rs b/crates/lgn-data-transaction/src/transaction_manager.rs
index e447b314bd..c397f3b784 100644
--- a/crates/lgn-data-transaction/src/transaction_manager.rs
+++ b/crates/lgn-data-transaction/src/transaction_manager.rs
@@ -2,7 +2,9 @@ use std::{collections::HashSet, path::PathBuf, sync::Arc};
use lgn_content_store::indexing::SharedTreeIdentifier;
use lgn_data_offline::{Project, ResourcePathName};
-use lgn_data_runtime::{AssetRegistryError, ResourcePathId, ResourceType, ResourceTypeAndId};
+use lgn_data_runtime::{
+ AssetRegistryError, AssetRegistryMessage, ResourcePathId, ResourceType, ResourceTypeAndId,
+};
use thiserror::Error;
use tokio::sync::Mutex;
@@ -78,6 +80,8 @@ pub enum Error {
pub struct TransactionManager {
commited_transactions: Vec,
rollbacked_transactions: Vec,
+ notification_tx: crossbeam_channel::Sender,
+ notification_rx: crossbeam_channel::Receiver,
pub(crate) project: Arc>,
pub(crate) build_manager: Arc>,
@@ -92,9 +96,14 @@ impl TransactionManager {
build_manager: BuildManager,
selection_manager: Arc,
) -> Self {
+ let (notification_tx, notification_rx) =
+ crossbeam_channel::unbounded::();
+
Self {
commited_transactions: Vec::new(),
rollbacked_transactions: Vec::new(),
+ notification_tx,
+ notification_rx,
project,
build_manager: Arc::new(Mutex::new(build_manager)),
selection_manager,
@@ -102,6 +111,11 @@ impl TransactionManager {
}
}
+ /// Return a Notification receiver
+ pub fn get_notification_receiver(&self) -> crossbeam_channel::Receiver {
+ self.notification_rx.clone()
+ }
+
/// Add a scene and build it
pub async fn add_scene(
&mut self,
@@ -130,6 +144,22 @@ impl TransactionManager {
self.active_scenes.iter().copied().collect()
}
+ fn notify_changed_resources(&self, changed: Option>) {
+ if let Some(changed) = changed {
+ let runtime_changed = changed
+ .iter()
+ .map(|r| BuildManager::get_derived_id(*r).resource_id())
+ .collect::>();
+
+ if let Err(err) = self
+ .notification_tx
+ .send(AssetRegistryMessage::ChangedResources(runtime_changed))
+ {
+ lgn_tracing::warn!("Failed to TransactionMessage::ChangedResources: {}", err);
+ }
+ }
+ }
+
/// Build a resource by id
pub async fn build_by_id(
&self,
@@ -143,53 +173,42 @@ impl TransactionManager {
.await
.map_err(|err| Error::Databuild(resource_id, err))?;
- /*// Reload runtime asset (just entity for now)
- for asset_id in changed_assets {
- // Try to reload, if it doesn't exist, load normally
- if asset_id.kind.as_pretty().starts_with("runtime_")
- && !ctx.asset_registry.reload(asset_id)
- {
- ctx.asset_registry.load_untyped(asset_id);
- }
- }*/
Ok(runtime_path_id)
}
/// Commit the current pending `Transaction`
- pub async fn commit_transaction(
- &mut self,
- mut transaction: Transaction,
- ) -> Result