Skip to content
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
.local
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2024"
authors = ["Thiago Ramos"]
description = "A flexible and efficient library for managing 2D grid-based layouts with automatic collision handling and dynamic vertical expansion"
documentation = "https://docs.rs/grid-engine"
homepage = "https://github.com/thiagodejesus/grid-engine"
repository = "https://github.com/thiagodejesus/grid-engine"
readme = "README.md"
keywords = ["grid", "layout", "collision", "2d", "dashboard"]
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/managing_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn main() {

let mut grid = GridEngine::new(10, 12);

grid.events.add_changes_listener(Box::new(|event| {
grid.events_mut().add_changes_listener(Box::new(|event| {
println!("Event triggered: {:#?}", event);
}));

Expand Down
178 changes: 162 additions & 16 deletions src/grid_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,22 @@
//!
//! ```
//! use grid_engine::grid_engine::GridEngine;
//! # use std::error::Error;
//!
//! # fn main() -> Result<(), Box<dyn Error>> {
//! let mut grid = GridEngine::new(10, 12);
//!
//! // Add items to the grid
//! grid.add_item("item1".to_string(), 2, 2, 2, 4).unwrap();
//! grid.add_item("item1".to_string(), 2, 2, 2, 4)?;
//!
//! // Move items (handles collisions automatically)
//! grid.move_item("item1", 4, 4).unwrap();
//! grid.move_item("item1", 4, 4)?;
//!
//! // Remove items
//! grid.remove_item("item1").unwrap();
//! grid.remove_item("item1")?;
//! #
//! # Ok(())
//! # }
//! ```

use crate::error::{GridEngineError, InnerGridError, ItemError};
Expand All @@ -54,23 +59,92 @@ use std::{collections::BTreeMap, fmt::Debug};
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct AddChangeData {
/// The node being added to the grid
pub value: Node,
value: Node,
}

impl AddChangeData {
/// Creates a new AddChangeData instance
///
/// # Arguments
///
/// * `value` - The node being added to the grid
///
/// # Returns
///
/// A new instance of AddChangeData
pub fn new(value: Node) -> Self {
Self { value }
}

/// Returns the node being added
pub fn value(&self) -> &Node {
&self.value
}
}

/// Represents data for an item removal change
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct RemoveChangeData {
/// The node being removed from the grid
pub value: Node,
value: Node,
}

impl RemoveChangeData {
/// Creates a new RemoveChangeData instance
///
/// # Arguments
///
/// * `value` - The node being removed from the grid
///
/// # Returns
///
/// A new instance of RemoveChangeData
pub fn new(value: Node) -> Self {
Self { value }
}

/// Returns the node being removed
pub fn value(&self) -> &Node {
&self.value
}
}

/// Represents data for an item movement change
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct MoveChangeData {
/// The original state of the node
pub old_value: Node,
old_value: Node,
/// The new state of the node after movement
pub new_value: Node,
new_value: Node,
}

impl MoveChangeData {
/// Creates a new MoveChangeData instance
///
/// # Arguments
///
/// * `old_value` - The original state of the node
/// * `new_value` - The new state of the node after movement
///
/// # Returns
///
/// A new instance of MoveChangeData
pub fn new(old_value: Node, new_value: Node) -> Self {
Self {
old_value,
new_value,
}
}

/// Returns the original state of the node
pub fn old_value(&self) -> &Node {
&self.old_value
}

/// Returns the new state of the node after movement
pub fn new_value(&self) -> &Node {
&self.new_value
}
}

/// Represents different types of changes that can occur in the grid
Expand Down Expand Up @@ -104,7 +178,7 @@ pub struct GridEngine {
/// Changes waiting to be applied
pending_changes: Vec<Change>,
/// Event system for tracking grid changes
pub events: GridEvents,
events: GridEvents,
}

impl GridEngine {
Expand All @@ -131,16 +205,36 @@ impl GridEngine {
}
}

/// Creates a new node with the specified parameters.
fn new_node(&mut self, id: String, x: usize, y: usize, w: usize, h: usize) -> Node {
Node::new(id, x, y, w, h)
}

/// Creates a change operation to add a new node to the grid.
fn create_add_change(&mut self, node: Node) {
self.pending_changes
.push(Change::Add(AddChangeData { value: node }));
}

/// Get the nodes sorted by id
///
/// # Example
///
/// ```
/// use grid_engine::grid_engine::GridEngine;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut grid = GridEngine::new(10, 10);
/// grid.add_item("b".to_string(), 0, 0, 2, 2).unwrap();
/// grid.add_item("a".to_string(), 0, 2, 2, 2).unwrap();
///
/// let nodes = grid.get_nodes();
/// assert_eq!(nodes.len(), 2);
/// assert_eq!(nodes[0].id(), "a");
/// assert_eq!(nodes[1].id(), "b");
/// # Ok(())
/// # }
/// ```
pub fn get_nodes(&self) -> Vec<Node> {
let mut cloned: Vec<Node> = self.items.values().cloned().collect();
// Would be better to sort by some created_at
Expand All @@ -157,6 +251,20 @@ impl GridEngine {
/// # Returns
///
/// A reference to the InnerGrid instance
///
/// # Example
///
/// ```
/// use grid_engine::grid_engine::GridEngine;
/// use std::error::Error;
///
/// # fn main() -> Result<(), Box<dyn Error>> {
/// let grid = GridEngine::new(10, 10);
/// let inner_grid = grid.get_inner_grid();
/// assert_eq!(inner_grid.rows(), 10);
/// assert_eq!(inner_grid.cols(), 10);
/// # Ok(())
/// # }
pub fn get_inner_grid(&self) -> &InnerGrid {
&self.grid
}
Expand All @@ -183,9 +291,19 @@ impl GridEngine {
///
/// ```
/// use grid_engine::grid_engine::GridEngine;
/// use std::error::Error;
///
/// # fn main() -> Result<(), Box<dyn Error>> {
/// let mut grid = GridEngine::new(10, 10);
/// grid.add_item("box1".to_string(), 0, 0, 2, 2).unwrap(); // 2x2 item at top-left
/// grid.add_item("box1".to_string(), 0, 0, 2, 2)?; // 2x2 item at top-left
///
/// // Check if the item was added correctly
/// let item = grid.get_nodes();
/// assert_eq!(item.len(), 1);
/// assert_eq!(item[0].id(), "box1");
///
/// # Ok(())
/// # }
/// ```
pub fn add_item(
&mut self,
Expand Down Expand Up @@ -239,10 +357,16 @@ impl GridEngine {
///
/// ```
/// use grid_engine::grid_engine::GridEngine;
/// use std::error::Error;
///
/// # fn main() -> Result<(), Box<dyn Error>> {
///
/// let mut grid = GridEngine::new(10, 10);
/// grid.add_item("box1".to_string(), 0, 0, 2, 2).unwrap();
/// grid.remove_item("box1").unwrap(); // Removes the item
/// grid.add_item("box1".to_string(), 0, 0, 2, 2)?;
/// grid.remove_item("box1")?; // Removes the item
///
/// # Ok(())
/// # }
/// ```
pub fn remove_item(&mut self, id: &str) -> Result<Node, GridEngineError> {
let node = match self.items.get(id) {
Expand Down Expand Up @@ -409,10 +533,23 @@ impl GridEngine {
///
/// ```
/// use grid_engine::grid_engine::GridEngine;
/// # use std::error::Error;
///
/// # fn main() -> Result<(), Box<dyn Error>> {
///
/// let mut grid = GridEngine::new(10, 10);
/// grid.add_item("box1".to_string(), 0, 0, 2, 2).unwrap();
/// grid.move_item("box1", 2, 2).unwrap(); // Moves box to position 2,2
/// grid.add_item("box1".to_string(), 0, 0, 2, 2)?;
/// grid.move_item("box1", 2, 2)?; // Moves box to position 2,2
///
/// // Check if the item was moved correctly
/// let item = grid.get_nodes();
/// assert_eq!(item.len(), 1);
/// assert_eq!(item[0].x(), &2);
/// assert_eq!(item[0].y(), &2);
///
/// # Ok(())
/// # }
///
/// ```
pub fn move_item(
&mut self,
Expand Down Expand Up @@ -483,11 +620,20 @@ impl GridEngine {
}
}

self.events.trigger_changes_event(&ChangesEventValue {
changes: changes.to_vec(),
});
self.events
.trigger_changes_event(&ChangesEventValue::new(changes.to_vec()));
Ok(())
}

/// Returns a reference to the grid events system.
pub fn events(&self) -> &GridEvents {
&self.events
}

/// Returns a mutable reference to the grid events system.
pub fn events_mut(&mut self) -> &mut GridEvents {
&mut self.events
}
}

mod tests {
Expand Down
Loading