Guest User

Untitled

a guest
Sep 12th, 2024
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.97 KB | None | 0 0
  1. Certainly! You can implement the `From<&Scene>` trait for your `ECS` struct by recursively processing each node in your `Scene`. Here's how you can do it:
  2.  
  3. ```rust
  4. impl From<&Scene> for ECS {
  5. fn from(value: &Scene) -> Self {
  6. let mut new_ecs = ECS::new();
  7. let mut node_id_counter = 0; // Start entity IDs from 0
  8.  
  9. new_ecs.scene_name = value.name.clone();
  10. new_ecs.scene_resource_path = value.resource_path.clone();
  11. new_ecs.scene_id = value.id.clone();
  12.  
  13. // Process the root node and its children recursively
  14. let root_entity = new_ecs.process_game_node(&value.root_node, &mut node_id_counter, None);
  15. new_ecs.scene_root = root_entity;
  16.  
  17. new_ecs
  18. }
  19. }
  20. ```
  21.  
  22. Now, let's implement the `process_game_node` function. This function will:
  23.  
  24. - Assign a unique `Entity` ID to each node.
  25. - Update the relevant fields in the `ECS` struct.
  26. - Recursively process the children of each node.
  27.  
  28. Here's the implementation:
  29.  
  30. ```rust
  31. impl ECS {
  32. // ... existing methods ...
  33.  
  34. fn process_game_node(
  35. &mut self,
  36. node: &GameNodeKind,
  37. node_id_counter: &mut usize,
  38. parent_entity: Option<Entity>,
  39. ) -> Entity {
  40. // Assign a new Entity ID
  41. let entity = Entity(*node_id_counter);
  42. *node_id_counter += 1;
  43.  
  44. // Map GameNodeKind to GameNodeKindClean for storage
  45. let kind_clean = match node {
  46. GameNodeKind::Instance(_) => GameNodeKindClean::Instance,
  47. GameNodeKind::Node2D(_) => GameNodeKindClean::Node2D,
  48. };
  49. self.game_node_kind.insert(entity, kind_clean);
  50.  
  51. // Process the node based on its kind
  52. match node {
  53. GameNodeKind::Instance(game_node) => {
  54. // Update general node information
  55. self.game_node_id.insert(entity, game_node.id);
  56. self.game_node_name.insert(entity, game_node.name.clone());
  57.  
  58. if let Some(script) = &game_node.script {
  59. self.game_node_script.insert(entity, script.clone());
  60. }
  61.  
  62. // Process children recursively
  63. let mut child_entities = Vec::new();
  64. for child in &game_node.children {
  65. let child_entity = self.process_game_node(child, node_id_counter, Some(entity));
  66. child_entities.push(child_entity);
  67. }
  68. self.game_node_children.insert(entity, child_entities);
  69. }
  70. GameNodeKind::Node2D(game_node) => {
  71. // Update general node information
  72. self.game_node_id.insert(entity, game_node.id);
  73. self.game_node_name.insert(entity, game_node.name.clone());
  74.  
  75. if let Some(script) = &game_node.script {
  76. self.game_node_script.insert(entity, script.clone());
  77. }
  78.  
  79. // Update transform information
  80. self.transforms.insert(entity, game_node.data.transform.clone());
  81.  
  82. // Map Node2DKind to Node2DKindClean and process specific data
  83. match &game_node.data.kind {
  84. Node2DKind::Node2D(_) => {
  85. self.node_2d_kind.insert(entity, Node2DKindClean::Node2D);
  86. }
  87. Node2DKind::RigidBody(rigid_body) => {
  88. self.node_2d_kind.insert(entity, Node2DKindClean::RigidBody);
  89. self.rigid_body_velocity.insert(entity, rigid_body.velocity);
  90. self.rigid_body_type.insert(entity, rigid_body.body.clone());
  91. }
  92. Node2DKind::Collider(collider) => {
  93. self.node_2d_kind.insert(entity, Node2DKindClean::Collider);
  94. self.collider.insert(entity, collider.clone());
  95. }
  96. Node2DKind::Render(render) => {
  97. self.node_2d_kind.insert(entity, Node2DKindClean::Render);
  98. self.render_offset.insert(entity, render.offset);
  99. self.render_layer.insert(entity, render.layer.clone());
  100.  
  101. // Map RenderKind to RenderKindClean and update GID
  102. let render_kind_clean = match &render.kind {
  103. RenderKind::AnimatedSprite(gid) => {
  104. self.render_gid.insert(entity, gid.clone());
  105. RenderKindClean::AnimatedSprite
  106. }
  107. RenderKind::Sprite(gid) => {
  108. self.render_gid.insert(entity, gid.clone());
  109. RenderKindClean::Sprite
  110. }
  111. };
  112. self.render_kind.insert(entity, render_kind_clean);
  113. }
  114. }
  115.  
  116. // Process children recursively
  117. let mut child_entities = Vec::new();
  118. for child in &game_node.children {
  119. let child_entity = self.process_game_node(child, node_id_counter, Some(entity));
  120. child_entities.push(child_entity);
  121. }
  122. self.game_node_children.insert(entity, child_entities);
  123. }
  124. }
  125.  
  126. // If there's a parent entity, you can handle parent-specific logic here if needed
  127.  
  128. entity
  129. }
  130. }
  131. ```
  132.  
  133. **Explanation:**
  134.  
  135. - **Entity Assignment:** We use `node_id_counter` to assign a unique `Entity` ID to each node.
  136. - **Kind Mapping:** We map `GameNodeKind` and `Node2DKind` to their corresponding `Clean` enums for storage in the `ECS` HashMaps.
  137. - **Data Insertion:** We insert the node's ID, name, script, and kind into the respective HashMaps.
  138. - **Transform and Specific Data:** For `Node2D` nodes, we insert transform data and handle specific kinds like `RigidBody`, `Collider`, and `Render`.
  139. - **Children Processing:** We recursively process each child node and collect their `Entity` IDs to build the `game_node_children` mapping.
  140. - **Parent-Child Relationships:** We store the children of each node in the `game_node_children` HashMap. If you need to track parents, you can add a similar mapping.
  141.  
  142. **Notes:**
  143.  
  144. - Ensure that all fields in your `ECS` struct are correctly updated based on the data in your `Scene`.
  145. - The `entity_id` field in `GameNode<T>` seems optional and might be used elsewhere. Since we're assigning new `Entity` IDs during the conversion, you might not need to use it directly in this context.
  146. - This implementation assumes that the `ECS` struct's HashMaps are meant to store components associated with each `Entity`.
  147.  
  148. **Testing:**
  149.  
  150. You can test this implementation by creating a `Scene` with various nodes and ensuring that the resulting `ECS` struct contains all the expected data.
  151.  
  152. **Example Usage:**
  153.  
  154. ```rust
  155. fn main() {
  156. let scene = Scene {
  157. id: "ExampleScene".to_string(),
  158. name: "Example Scene".to_string(),
  159. resource_path: ResourcePath("path/to/resource".to_string()),
  160. root_node: GameNodeKind::Node2D(GameNode {
  161. id: GameNodeId(Entity(0)),
  162. name: "RootNode".to_string(),
  163. entity_id: None,
  164. data: Node2D {
  165. transform: Transform {
  166. position: (0.0, 0.0),
  167. scale: (1.0, 1.0),
  168. velocity: (0.0, 0.0),
  169. rotation: 0.0,
  170. },
  171. kind: Node2DKind::Render(Render {
  172. offset: (0.0, 0.0),
  173. layer: LayerKind::Background,
  174. kind: RenderKind::Sprite(Gid(1)),
  175. }),
  176. },
  177. script: Some("root_script".to_string()),
  178. children: vec![],
  179. }),
  180. };
  181.  
  182. let ecs: ECS = (&scene).into();
  183. // Now, ecs contains all the data from the scene
  184. }
  185. ```
  186.  
  187. This approach should help you convert your `Scene` into the `ECS` format effectively.
Advertisement
Add Comment
Please, Sign In to add comment