Partage
  • Partager sur Facebook
  • Partager sur Twitter

Clôner et fusionner des arbres.

Je bloque

    24 octobre 2023 à 17:55:52

    Salut je souhaite  clôner et fusionner des structures arborescente comme par exemple sur git quand on clône ou qu'on fusionne des répertoires et des fichiers.

    Le problème c'est que je ne vois pas du tout comment faire, voici la classe qui représente mes arbres.

    class ComponentMapping {
                    template <class>
                    friend class World;
                    friend class CloningSystem;
                    friend class MergingSystem;
                    friend class Grid;
                    std::vector<std::vector<EntityId>> childrenMapping;
                    std::vector<std::optional<EntityId>> parentMapping;
                    public :
                    template <typename Factory>
                    void addChild(EntityId parentId, EntityId child, Factory& factory) {
    
                        for (unsigned int i = 0; i < childrenMapping.size(); i++) {
                            childrenMapping[parentId].resize(factory.getNbEntities());
                        }
    
                        childrenMapping[parentId].push_back(child);
                        parentMapping.resize(factory.getNbEntities());
                        parentMapping[child] = parentId;
                    }
                    EntityId getRoot(EntityId entityId) {
                        EntityId root = entityId;
                        while (parentMapping[root].has_value()) {
                            root = parentMapping[root].value();
                        }
                        return root;
                    }
                    std::vector<EntityId> getChildren(EntityId entity) {
                        return childrenMapping[entity];
                    }
                    EntityId getParent(EntityId entity) {
                        if(parentMapping[entity].has_value());
                           return parentMapping[entity].value();
                        return -1;
                    }
                    void setParent(EntityId entity, EntityId parent) {
                        parentMapping[entity] = parent;
                    }
                    bool remove(EntityId entity) {
                        std::vector<EntityId> children = childrenMapping[entity];
                        for (unsigned int i = 0; i < children.size(); i++) {
                            remove(childrenMapping[children[i]]);
                        }
                        childrenMapping[entity].clear();
                    }
                    EntityId clone(EntityFactory& factory) {
    
                    }
                    void merge(EntityId toMerge, EntityFactory& facvtory) {
                    }
                    template <typename... Signature, typename System, typename... Params>
                    void apply(System& system, std::vector<EntityId>& entities, std::tuple<Params...>& params, bool reverse=false) {
                      bool first;
                      EntityId tmpParentEntity;
                      EntityId tmpClonedParentEntity;
                      if (reverse) {
                          for (unsigned int i = 0; i < entities.size(); i++) {
                            first = false;
                            tmpParentEntity = -1;
                            tmpClonedParentEntity = -1;
                            auto additionnal_params = std::make_tuple(first, tmpClonedParentEntity, tmpParentEntity);
                            auto cated_params = std::tuple_cat(params, additionnal_params);
                            std::vector<EntityId> children = childrenMapping[entities[i]];
                            std::vector<EntityId> addedChildren;
                            while (children.size() > 0) {
                                for (unsigned int i = 0; i < children.size(); i++) {
                                    addedChildren.push_back(children[i]);
                                }
                                if (parentMapping[children[0]].has_value()) {
                                    EntityId parentId = parentMapping[children[0]];
                                    children = childrenMapping[parentId];
                                } else {
                                    children.clear();
                                }
                            }
                            for (unsigned i = 0; i < addedChildren.size(); i++) {
                                this->template apply_impl<Signature...>(addedChildren[i], system, cated_params, std::index_sequence_for<Signature...>());
                            }
                            this->template apply_impl<Signature...>(entities[i], system, cated_params, std::index_sequence_for<Signature...>());
                          }
                      } else {
                          for (unsigned int i = 0; i < entities.size(); i++) {
                            first = false;
                            tmpParentEntity = -1;
                            tmpClonedParentEntity = -1;
                            auto additionnal_params = std::make_tuple(first, tmpClonedParentEntity, tmpParentEntity);
                            auto cated_params = std::tuple_cat(params, additionnal_params);
                            this->template apply_impl<Signature...>(entities[i], system, cated_params, std::index_sequence_for<Signature...>());
                            std::vector<EntityId> children = childrenMapping[entities[i]];
                            std::vector<EntityId> addedChildren;
                            while (children.size() > 0) {
                                for (unsigned int i = 0; i < children.size(); i++) {
                                    addedChildren.push_back(children[i]);
                                }
                                if (parentMapping[children[0]].has_value()) {
                                    EntityId parentId = parentMapping[children[0]];
                                    children = childrenMapping[parentId];
                                } else {
                                    children.clear();
                                }
                            }
                            for (int i = addedChildren.size()-1; i >=0; i++) {
                                this->template apply_impl<Signature...>(addedChildren[i], system, cated_params, std::index_sequence_for<Signature...>());
                            }
                          }
                      }
                    }
    
                    template <typename... Signature, typename System, size_t... I, typename... Params>
                    void apply_impl(EntityId entityId, System& system, std::tuple<Params...>& params, std::index_sequence<I...>) {
                        system<Signature...>(entityId, params);
                    }
                    template <typename... Signature, typename System, typename... Params, class R>
                    void apply(System& system, std::vector<EntityId>& entities, std::tuple<Params...>& params, std::vector<R>& ret, bool reverse=false) {
                      bool first;
                      EntityId tmpParentEntity;
                      EntityId tmpClonedParentEntity;
                      auto additionnal_params = std::make_tuple(tmpParentEntity);
                      auto cated_params = std::tuple_cat(params, additionnal_params);
                      if (reverse) {
                          for (unsigned int i = 0; i < entities.size(); i++) {
                            first = false;
                            tmpParentEntity = -1;
                            tmpClonedParentEntity = -1;
                            auto additionnal_params = std::make_tuple(first, tmpClonedParentEntity, tmpParentEntity);
                            auto cated_params = std::tuple_cat(params, additionnal_params);
                            std::vector<EntityId> children = childrenMapping[entities[i]];
                            std::vector<EntityId> addedChildren;
                            while (children.size() > 0) {
                                for (unsigned int i = 0; i < children.size(); i++) {
                                    addedChildren.push_back(children[i]);
                                }
                                if (parentMapping[children[0]].has_value()) {
                                    EntityId parentId = parentMapping[children[0]];
                                    children = childrenMapping[parentId];
                                } else {
                                    children.clear();
                                }
                            }
                            for (unsigned i = 0; i < addedChildren.size(); i++) {
                                this->template apply_impl<Signature...>(addedChildren[i], system, cated_params, std::index_sequence_for<Signature...>(), ret);
                            }
                            this->template apply_impl<Signature...>(entities[i], system, cated_params, std::index_sequence_for<Signature...>(), ret);
                          }
                      } else {
                          for (unsigned int i = 0; i < entities.size(); i++) {
                            first = false;
                            tmpParentEntity = -1;
                            tmpClonedParentEntity = -1;
                            auto additionnal_params = std::make_tuple(first, tmpClonedParentEntity, tmpParentEntity);
                            auto cated_params = std::tuple_cat(params, additionnal_params);
                            this->template apply_impl<Signature...>(entities[i], tuple, system, cated_params, std::index_sequence_for<Signature...>(), ret);
                            std::vector<EntityId> children = childrenMapping[entities[i]];
                            std::vector<EntityId> addedChildren;
                            while (children.size() > 0) {
                                for (unsigned int i = 0; i < children.size(); i++) {
                                    addedChildren.push_back(children[i]);
                                }
                                if (parentMapping[children[0]].has_value()) {
                                    EntityId parentId = parentMapping[children[0]];
                                    children = childrenMapping[parentId];
                                } else {
                                    children.clear();
                                }
                            }
                            for (int i = addedChildren.size()-1; i >=0; i++) {
                                this->template apply_impl<Signature...>(addedChildren[i], system, cated_params, std::index_sequence_for<Signature...>(), ret);
                            }
                          }
                      }
                    }
                    template <typename... Signature, typename DynamicTuple, typename System, size_t... I, typename... Params, typename R>
                    void apply_impl(EntityId entityId, DynamicTuple& tuple, System& system, std::tuple<Params...>& params, std::index_sequence<I...>, std::vector<R>& rets) {
    
                        rets.push_back(system<Signature...>(entityId, params));
                    }
    
                };

    Je ne sais pas quoi mettre dans les méthodes clône et merge.

    Merci d'avance pour votre aide.

    • Partager sur Facebook
    • Partager sur Twitter
      1 novembre 2023 à 18:34:40

      Salut! Après moultes recherches je pense avoir trouvé mais je n'ai pas encore testé :

      template <typename... Signature>
                      EntityId clone(EntityFactory& factory, EntityId toClone, EntityId parent = -1) {
                          EntityId clonedId = factory.createEntity();
                          clone_impl(toClone, clonedId, factory)
                          for (unsigned int i = 0; i < childrenMapping[toClone].size(); i++) {
                              parentMapping[childrenMapping[i]] = clonedId;
                              childrenMapping[clonedId] = childrenMapping[i];
                              clone(factory, childrenMapping[i], clonedId);
                          }
                          return clonedId;
                      }
                      template <typename... Components, size_t I = 0, class = typename std::enable_if_t<(sizeof...(Components) != 0 && I < sizeof...(Components)-1)>>
                      void clone_impl(EntityId toCloneId, EntityId clonedId, EntityFactory& factory) {
                          //si l'entité possède le composant en question on le clône.
                          if (getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId)) {
                              addComponent(clonedId, *getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId), factory);
                          }
                          clone_impl<Components..., I+1>(toCloneId, clonedId, factory);
                      }
                      template <typename... Components, size_t I = 0, class... D, class = typename std::enable_if_t<(sizeof...(Components) != 0 && I == sizeof...(Components)-1)>>
                      void clone_impl(EntityId toCloneId, EntityId clonedId, EntityFactory& factory) {
                          if (getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId)) {
                              addComponent(clonedId, *getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId), factory);
                          }
                      }
                      template <typename... Components, size_t I = 0, class... D, class...E, class = typename std::enable_if_t<(sizeof...(Components) == 0)>>
                      void clone_impl(EntityId tocloneId, EntityId clonedId, EntityFactory& factory) {
                      }
                      template <typename... Signature>
                      EntityId merge(EntityFactory& factory, EntityId toMerge1, EntityId toMerge2, EntityId parent=-1) {
                          EntityId merged = factory.createEntity();
                          if (parent != -1 && toMerge1 != -1) {
                              merge_node<Signature...>(merged, toMerge1, factory);
                          }
                          if (parent != -1 && toMerge2 != -1) {
                              merge_node<Signature...>(merged, toMerge2, factory);
                          }
                          for (unsigned int i = 0; i < childrenMapping[toMerge1]; i++) {
                              parentMapping[childrenMapping[i]] = merged;
                              childrenMapping[merged] = childrenMapping[i];
                              merge(factory, childrenMapping[i], -1, merged);
                          }
                          for (unsigned int i = 0; i < childrenMapping[toMerge2]; i++) {
                              parentMapping[childrenMapping[i]] = merged;
                              childrenMapping[merged] = childrenMapping[i];
                              merge(factory, -1, childrenMapping[i], merged);
                          }
                          return merged;
                      }
                      template <typename... Signature, size_t I = 0, class = typename std::enable_if_t<(sizeof...(Signature) != 0 && I < sizeof...(Signature)-1)>
                      void merge_node(EntityId entityId, EntityId toMergeId, EntityFactory& factory) {
                          //si l'entité possède le composant en question on le clône.
                          if (getComponent<std::tuple_element_t<I, std::tuple<Signature...>(toMergeId)) {
                              componentMapping.addComponent(entityId, *getComponent<std::tuple_element_t<I, std::tuple<Signature...>>(toMergeId), factory);
                          }
                          merge_node<T, I+1>(toCloneId, clonedId, factory);
                      }
                      template <typename... Signature, size_t I = 0, class... D, class = typename std::enable_if_t<(sizeof...(Signature) != 0 && I == sizeof...(Signature)-1)>
                      void merge_node(EntityId entityId, EntityId toMergeId, EntityFactory& factory) {
                          if (getComponent<std::tuple_element_t<I, std::tuple<Signature...>(toMergeId)) {
                              componentMapping.addComponent(entityId, *getComponent<std::tuple_element_t<I, std::tuple<Signature...>>(toMergeId), factory);
                          }
                      }
                      template <typename... Signature, size_t I = 0, class... D, class...E, class = typename std::enable_if_t<(sizeof...(Signature) == 0)>
                      void merge_node(EntityId tocloneId, EntityId clonedId; EntityFactory& factory) {
                      }

      Je vais en avoir besoin pour mon ECS dans mon framework.



      -
      Edité par OmbreNoire 1 novembre 2023 à 20:41:44

      • Partager sur Facebook
      • Partager sur Twitter
        4 novembre 2023 à 9:16:34

        Salut, j'ai corrigé le code :

        template <typename... Signature>
                        EntityId clone(EntityFactory& factory, EntityId toClone, EntityId parent = -1) {
                            EntityId clonedId = factory.createEntity(getComponent<EntityInfoComponent>(toClone))->groupName);
                            clone_impl(toClone, clonedId, factory);
                            if (parent != -1) {
                                childrenMapping[parent].resize(factory.getNbEntities());
                                parentMapping.resize(factory.getNbEntities());
                                childrenMapping[parent] = clonedId;
                                parentMapping[clonedId] = parent;
                            }
                            for (unsigned int i = 0; i < childrenMapping[toClone].size(); i++) {
                                clone(factory, childrenMapping[i], clonedId);
                            }
                            return clonedId;
                        }
                        template <typename... Components, size_t I = 0, class = typename std::enable_if_t<(sizeof...(Components) != 0 && I < sizeof...(Components)-1)>>
                        void clone_impl(EntityId toCloneId, EntityId clonedId, EntityFactory& factory) {
                            //si l'entité possède le composant en question on le clône.
                            if (getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId)) {
                                addComponent(clonedId, *getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId), factory);
                            }
                            clone_impl<Components..., I+1>(toCloneId, clonedId, factory);
                        }
                        template <typename... Components, size_t I = 0, class... D, class = typename std::enable_if_t<(sizeof...(Components) != 0 && I == sizeof...(Components)-1)>>
                        void clone_impl(EntityId toCloneId, EntityId clonedId, EntityFactory& factory) {
                            if (getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId)) {
                                addComponent(clonedId, *getComponent<std::tuple_element_t<I, std::tuple<Components...>>(toCloneId), factory);
                            }
                        }
                        template <typename... Components, size_t I = 0, class... D, class...E, class = typename std::enable_if_t<(sizeof...(Components) == 0)>>
                        void clone_impl(EntityId tocloneId, EntityId clonedId, EntityFactory& factory) {
                        }
                        template <typename... Signature>
                        EntityId merge(EntityFactory& factory, EntityId toMerge1, EntityId toMerge2, std::string groupeName, EntityId parent=-1) {
                            EntityId merged = factory.createEntity(groupName);
                            EntityId merged1, merged2;
                            if (parent == -1) {
                                merged1 = factory.createEntity(getComponent<EntityInfoComponent>(toMerge1)->groupName);
                                merged2 = factory.createEntity(getComponent<EntityInfoComponent>(toMerge2)->groupName);
                                merge_node<Signature...>(merged, toMerge1, factory);
                                merge_node<Signature...>(merged, toMerge2, factory);
                                childrenMapping[parentId].resize(factory.getNbEntities());
                                parentMapping.resize(factory.getNbEntities());
                                childrenMapping[merged] = merged1;
                                parentMapping[merged1] = merged;
                                childrenMapping[merged] = merged2;
                                parentMapping[merged2] = merged;
                            }
                            if (parent != -1 && toMerge1 != -1) {
                                childrenMapping[parentId].resize(factory.getNbEntities());
                                parentMapping.resize(factory.getNbEntities());
                                childrenMapping[parent] = merged;
                                parentMapping[merged] = parent;
                                merge_node<Signature...>(merged, toMerge1, factory);
                            }
                            if (parent != -1 && toMerge2 != -1) {
                                childrenMapping[parentId].resize(factory.getNbEntities());
                                parentMapping.resize(factory.getNbEntities());
                                childrenMapping[parent] = merged;
                                parentMapping[merged] = parent;
                                merge_node<Signature...>(merged, toMerge2, factory);
                            }
                            for (unsigned int i = 0; i < childrenMapping[toMerge1]; i++) {
                                merge(factory, childrenMapping[i], -1, getComponent<EntityInfoComponent>(childrenMapping[i])->groupName, (parent == -1) ? merged1 : merged);
                            }
                            for (unsigned int i = 0; i < childrenMapping[toMerge2]; i++) {
                                merge(factory, -1, childrenMapping[i], getComponent<EntityInfoComponent>(childrenMapping[i])->groupName, (parent == -1) ? merged2 : merged);
                            }
                            return merged;
                        }
                        template <typename... Signature, size_t I = 0, class = typename std::enable_if_t<(sizeof...(Signature) != 0 && I < sizeof...(Signature)-1)>
                        void merge_node(EntityId entityId, EntityId toMergeId, EntityFactory& factory) {
                            //si l'entité possède le composant en question on le clône.
                            if (getComponent<std::tuple_element_t<I, std::tuple<Signature...>(toMergeId)) {
                                componentMapping.addComponent(entityId, *getComponent<std::tuple_element_t<I, std::tuple<Signature...>>(toMergeId), factory);
                            }
                            merge_node<T, I+1>(toCloneId, clonedId, factory);
                        }
                        template <typename... Signature, size_t I = 0, class... D, class = typename std::enable_if_t<(sizeof...(Signature) != 0 && I == sizeof...(Signature)-1)>
                        void merge_node(EntityId entityId, EntityId toMergeId, EntityFactory& factory) {
                            if (getComponent<std::tuple_element_t<I, std::tuple<Signature...>(toMergeId)) {
                                componentMapping.addComponent(entityId, *getComponent<std::tuple_element_t<I, std::tuple<Signature...>>(toMergeId), factory);
                            }
                        }
                        template <typename... Signature, size_t I = 0, class... D, class...E, class = typename std::enable_if_t<(sizeof...(Signature) == 0)>
                        void merge_node(EntityId tocloneId, EntityId clonedId; EntityFactory& factory) {
                        }

        J'avais oublié de gérer le cas particulier de la racine dans merged.

        J'ai pas encore pu testé par contre.

        -
        Edité par OmbreNoire 4 novembre 2023 à 9:17:02

        • Partager sur Facebook
        • Partager sur Twitter

        Clôner et fusionner des arbres.

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown