Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(project): add TrackedProjectView #99

Merged
merged 14 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions crates/project/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,31 @@ impl<M: Module> DataView<'_, M> {
}));
}

/// Plans to move this data section to another planned document.
///
/// This will not modify the [`crate::Project`], just record this change to the
/// same [`ChangeBuilder`] [`crate::PlannedDocument`] was created with.
///
/// # Arguments
///
/// * `new_owner` - The planned document to move the data to.
///
/// # Panics
/// If a [`crate::PlannedDocument`] for a different [`crate::Project`] was passed.
pub fn move_to_planned_document(&self, new_owner: &mut crate::PlannedDocument) {
assert!(
new_owner.cb.is_same_source_as(self),
"ChangeBuilder must stem from the same project"
);
new_owner
.cb
.changes
.push(PendingChange::Change(Change::MoveData {
id: self.id,
new_owner: Some(new_owner.id),
}));
}

/// Plans to make this data section an orphan (not owned by any document).
///
/// This will not modify the [`crate::Project`], just record this change to `cb`.
Expand Down
2 changes: 1 addition & 1 deletion crates/project/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl fmt::Display for DocumentId {
/// Document in a [`crate::Project`]
///
/// Defines the metadata and the identifiers of containing data sections.
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Document {
pub data: Vec<DataId>,
}
Expand Down
7 changes: 7 additions & 0 deletions crates/project/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
//! via a [`ModuleRegistry`].
//! - **[`ChangeBuilder`]:** A mechanism for recording changes to be applied to a `Project`, ensuring atomicity and enabling
//! undo/redo.
//! - **[`TrackedProjectView`]:** A tracked version of a [`ProjectView`] allowing implicit dependency tracking
//!
//! ## Usage
//!
Expand Down Expand Up @@ -158,6 +159,7 @@ mod data;
mod document;
mod module_data;
mod project;
mod tracked;
mod user;

use branch::BranchId;
Expand All @@ -184,6 +186,11 @@ pub use document::Path;
pub use document::PlannedDocument;
pub use module_data::ModuleRegistry;
pub use project::ProjectView;
pub use tracked::AccessRecorder;
pub use tracked::CacheValidator;
pub use tracked::TrackedDataView;
pub use tracked::TrackedDocumentView;
pub use tracked::TrackedProjectView;
pub use user::UserId;

/// Facilitates the deserialization of a [`Project`] from a serialized format.
Expand Down
41 changes: 39 additions & 2 deletions crates/project/src/module_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ impl fmt::Display for ModuleId {
/// - `TDeserializer` - Deserializer for type-erased data
macro_rules! define_type_erased {
($d:ty, $reg_entry:ident) => {
define_type_erased!($d, $reg_entry,);
};
($d:ty, $reg_entry:ident, $($extra_traits:path),*) => {
paste! {
#[doc = "A trait shared by all [`" $d "`] types for all [`Module`]"]
#[allow(dead_code)]
pub trait [<$d Trait>]: erased_serde::Serialize + Debug + Send + Sync + Any + DynClone {
pub trait [<$d Trait>]: erased_serde::Serialize + Debug + Send + Sync + Any + DynClone $(+ $extra_traits)* {
/// Provides read-only access to the underlying data type.
fn as_any(&self) -> &dyn Any;
/// Provides mutable access to the underlying data type.
Expand Down Expand Up @@ -301,6 +304,13 @@ macro_rules! define_type_erased {
};
}

pub trait DataCompare {
fn persistent_eq(&self, other: &dyn DataTrait) -> bool;
fn persistent_user_eq(&self, other: &dyn DataTrait) -> bool;
fn session_eq(&self, other: &dyn DataTrait) -> bool;
fn shared_eq(&self, other: &dyn DataTrait) -> bool;
}

/// Complete state of the data of a module, publicly accessible through a [`crate::DataView`].
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct Data<M: Module> {
Expand All @@ -309,7 +319,34 @@ pub struct Data<M: Module> {
pub session: M::SessionData,
pub shared: M::SharedData,
}
define_type_erased!(Data, deserialize_data);
define_type_erased!(Data, deserialize_data, DataCompare);

impl<M: Module> DataCompare for Data<M> {
fn persistent_eq(&self, other: &dyn DataTrait) -> bool {
other
.as_any()
.downcast_ref::<Self>()
.is_some_and(|other| self.persistent == other.persistent)
}
fn persistent_user_eq(&self, other: &dyn DataTrait) -> bool {
other
.as_any()
.downcast_ref::<Self>()
.is_some_and(|other| self.persistent_user == other.persistent_user)
}
fn session_eq(&self, other: &dyn DataTrait) -> bool {
other
.as_any()
.downcast_ref::<Self>()
.is_some_and(|other| self.session == other.session)
}
fn shared_eq(&self, other: &dyn DataTrait) -> bool {
other
.as_any()
.downcast_ref::<Self>()
.is_some_and(|other| self.shared == other.shared)
}
}

/// Wrapper type around [`Module::SharedData`]
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
Expand Down
6 changes: 6 additions & 0 deletions crates/project/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ impl ProjectSource for ProjectView {
}
}

impl ProjectSource for std::sync::Arc<ProjectView> {
fn uuid(&self) -> uuid::Uuid {
self.uuid
}
}

impl ProjectView {
/// Opens a read only [`DocumentView`].
///
Expand Down
Loading