use crate::types::Handle;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Group {
pub handle: Handle,
pub owner: Handle,
pub name: String,
pub description: String,
pub entities: Vec<Handle>,
pub selectable: bool,
}
impl Group {
pub const OBJECT_TYPE: &'static str = "GROUP";
pub fn new(name: impl Into<String>) -> Self {
Self {
handle: Handle::NULL,
owner: Handle::NULL,
name: name.into(),
description: String::new(),
entities: Vec::new(),
selectable: true,
}
}
pub fn unnamed() -> Self {
Self::new("*A")
}
pub fn with_description(name: impl Into<String>, description: impl Into<String>) -> Self {
let mut group = Self::new(name);
group.description = description.into();
group
}
pub fn is_unnamed(&self) -> bool {
self.name.is_empty() || self.name.starts_with('*')
}
pub fn add_entity(&mut self, handle: Handle) {
if !self.entities.contains(&handle) {
self.entities.push(handle);
}
}
pub fn add_entities(&mut self, handles: impl IntoIterator<Item = Handle>) {
for handle in handles {
self.add_entity(handle);
}
}
pub fn remove_entity(&mut self, handle: Handle) -> bool {
if let Some(pos) = self.entities.iter().position(|h| *h == handle) {
self.entities.remove(pos);
true
} else {
false
}
}
pub fn clear(&mut self) {
self.entities.clear();
}
pub fn len(&self) -> usize {
self.entities.len()
}
pub fn is_empty(&self) -> bool {
self.entities.is_empty()
}
pub fn contains(&self, handle: Handle) -> bool {
self.entities.contains(&handle)
}
pub fn get(&self, index: usize) -> Option<Handle> {
self.entities.get(index).copied()
}
pub fn iter(&self) -> impl Iterator<Item = &Handle> {
self.entities.iter()
}
pub fn set_selectable(&mut self, selectable: bool) {
self.selectable = selectable;
}
pub fn with_desc(mut self, description: impl Into<String>) -> Self {
self.description = description.into();
self
}
pub fn with_selectable(mut self, selectable: bool) -> Self {
self.selectable = selectable;
self
}
pub fn with_entity(mut self, handle: Handle) -> Self {
self.add_entity(handle);
self
}
pub fn with_entities(mut self, handles: impl IntoIterator<Item = Handle>) -> Self {
self.add_entities(handles);
self
}
}
impl Default for Group {
fn default() -> Self {
Self::unnamed()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_group_creation() {
let group = Group::new("TestGroup");
assert_eq!(group.name, "TestGroup");
assert!(group.is_empty());
assert!(group.selectable);
assert!(!group.is_unnamed());
}
#[test]
fn test_group_unnamed() {
let group = Group::unnamed();
assert!(group.is_unnamed());
assert!(group.name.starts_with('*'));
}
#[test]
fn test_group_with_description() {
let group = Group::with_description("MyGroup", "This is a test group");
assert_eq!(group.name, "MyGroup");
assert_eq!(group.description, "This is a test group");
}
#[test]
fn test_group_add_entity() {
let mut group = Group::new("Test");
group.add_entity(Handle::new(100));
group.add_entity(Handle::new(101));
assert_eq!(group.len(), 2);
assert!(group.contains(Handle::new(100)));
assert!(group.contains(Handle::new(101)));
}
#[test]
fn test_group_add_duplicate() {
let mut group = Group::new("Test");
group.add_entity(Handle::new(100));
group.add_entity(Handle::new(100));
assert_eq!(group.len(), 1);
}
#[test]
fn test_group_add_entities() {
let mut group = Group::new("Test");
group.add_entities(vec![Handle::new(100), Handle::new(101), Handle::new(102)]);
assert_eq!(group.len(), 3);
}
#[test]
fn test_group_remove_entity() {
let mut group = Group::new("Test");
group.add_entity(Handle::new(100));
group.add_entity(Handle::new(101));
assert!(group.remove_entity(Handle::new(100)));
assert_eq!(group.len(), 1);
assert!(!group.contains(Handle::new(100)));
assert!(!group.remove_entity(Handle::new(999))); }
#[test]
fn test_group_clear() {
let mut group = Group::new("Test");
group.add_entities(vec![Handle::new(100), Handle::new(101)]);
group.clear();
assert!(group.is_empty());
}
#[test]
fn test_group_get() {
let mut group = Group::new("Test");
group.add_entity(Handle::new(100));
group.add_entity(Handle::new(101));
assert_eq!(group.get(0), Some(Handle::new(100)));
assert_eq!(group.get(1), Some(Handle::new(101)));
assert_eq!(group.get(2), None);
}
#[test]
fn test_group_selectable() {
let mut group = Group::new("Test");
assert!(group.selectable);
group.set_selectable(false);
assert!(!group.selectable);
}
#[test]
fn test_group_builder() {
let group = Group::new("Test")
.with_desc("Description")
.with_selectable(false)
.with_entity(Handle::new(100))
.with_entities(vec![Handle::new(101), Handle::new(102)]);
assert_eq!(group.description, "Description");
assert!(!group.selectable);
assert_eq!(group.len(), 3);
}
#[test]
fn test_group_iter() {
let mut group = Group::new("Test");
group.add_entities(vec![Handle::new(100), Handle::new(101)]);
let handles: Vec<Handle> = group.iter().copied().collect();
assert_eq!(handles, vec![Handle::new(100), Handle::new(101)]);
}
}