                ctrl))
       ;; no more elements to render
       [rendering rendered seen ctrl])))
+
+
+(defn register-ratoms-map [ratoms-map ratoms component]
+  (reduce (fn [rmap ratom]
+            (when (contains? ratoms-map ratom)
+              (throw (ex-info "Reactive atom has already a dependent parent component" {:ratom ratom
+                                                                                        :parent-component (get ratoms-map ratom)
+                                                                                        :child-component component})))
+            (assoc rmap ratom component)) ratoms-map ratoms))
+
+(defn unregister-ratoms-map [ratoms-map component]
+  (reduce (fn [rmap [ratom comp]]
+            (if (= comp component)
+              rmap
+              (assoc rmap ratom comp))) {} ratoms-map))
+
+
+
 ;;{
 ;; The main rendering function follows.
 ;;}

                                :previous-args (vec args)
                                :previous-render invoked
                                :previous-ratom-args ratom-args})))))
        ;; otherwise it is an item, already rendering
        :else
        (recur (rest elements)
               ratoms-map

        (= (ffirst elements) ::return)
        (let [component (second (first elements))]
          (recur (rest elements)
                 (unregister-ratoms-map ratoms-map component) ; the dependency is removed after the return
                 rendering
                 rendered
                 seen
                 ctrl))
        ;; if it's a component call, i.e.  [component args ...]  with component a function
        (fn? (ffirst elements))
        (let [component (ffirst elements)
              args (rest (first elements))
              ratoms (filter reactive-atom? args) ; we analyze all reactive atoms referenced in the arguments
              new-ratoms (filter #(not (contains? ratoms-map %)) ratoms) ; some ratoms are already tracked
              ratom-args (mapv deref ratoms)] ; we take all the current values of the referenced ratoms
          ;;(println "[render-component] component=" component)
          ;;(println "  => args=" args)
          ;;(println "  => ratom-args=" ratom-args)
          ;; We check if there is some available component information (values of a previous call)
          (if-let [comp-infos (get (:components ctrl) component)]
            (do #_(when (:previous-available comp-infos)
                  (println " => previous args= " (:previous-args comp-infos))
                  (println " => previous ratom args= " (:previous-ratom-args comp-infos)))
                ;; In the component infos do we have the values from a previous call?
                ;; moreover, are these previous values the same as the current values
                (if (and (:previous-available comp-infos)
                         (= (:previous-args comp-infos) args) ;
                         (= (:previous-ratom-args comp-infos) ratom-args))
                  ;; if it is the case there is no need for a new rendering of the whole component
                  (do
                    ;; (println "  ---> No need for new rendering <---")
                    (recur (cons (:previous-render comp-infos) (cons [::return component] (rest elements)))
                           ;; XXX: old code does not work since the component returns directly (?)
                           ;; (register-ratoms-map ratoms-map new-ratoms component) ; the dependencies are still listed
                           ratoms-map ;; unchanged is ok (guessing ...)
                           rendering
                           rendered
                           (conj seen component) ; we saw this component already
                           ctrl))
                  ;; otherwise, we need to update the component hence we make an explicit call
                  (let [invoked (apply component args)]
                    ;;(println "  ---> Rendering required <---")
                    (recur (cons invoked (cons [::return component] (rest elements))) ; we will return after handling the subcomponents
                           (register-ratoms-map ratoms-map new-ratoms component) ; we register the new dependencies
                           rendering
                           (conj rendered component) ; the component was asked to be rendered
                           (conj seen component)     ; we saw it
                           ;; we update the controller with the new argument values
                           (assoc-in ctrl [:components component]
                                     (assoc comp-infos
                                            :previous-available true
                                            :previous-args (vec args)
                                            :previous-ratom-args ratom-args
                                            :previous-render invoked))))))
            ;; the component is unknown, there is no previous information available
            (let [;; ratoms (filter reactive-atom? args) ; XXX old code : already done above !
                  ;; new-ratoms (filter #(not (contains? ratoms-map %)) ratoms) ; XXX: same
                  ;; We add the component as depending on all the newly discovered ratoms
                  _ (doseq [new-ratom new-ratoms]
                      (ratom/depend-component! new-ratom component))
                  ;; we then perform the call explicitly
                  invoked (apply component args)
                  ;; ratom-args (mapv deref ratoms)
                  ]
              ;;(println "  ---> Registering unknown component <---")
              ;; this is exactly the same continuation as the previous case (re-invokation)
              (recur (cons invoked (cons [::return component] (rest elements)))
                     (register-ratoms-map ratoms-map new-ratoms component)
                     rendering
