All Downloads are FREE. Search and download functionalities are using the official Maven repository.

us.ihmc.simulationconstructionset.dataBuffer.MirroredYoVariableRegistry Maven / Gradle / Ivy

package us.ihmc.simulationconstructionset.dataBuffer;

import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

import us.ihmc.yoVariables.listener.YoVariableChangedListener;
import us.ihmc.yoVariables.registry.YoRegistry;
import us.ihmc.yoVariables.variable.YoVariable;

public class MirroredYoVariableRegistry extends YoRegistry
{
   private final BiMap variableMap = HashBiMap.create();
   private final ConcurrentLinkedQueue changedVariablesInMirror = new ConcurrentLinkedQueue<>();
   private final ConcurrentLinkedQueue changedVariablesInOriginal = new ConcurrentLinkedQueue<>();

   private boolean enableChangedListener = true;
   private final YoRegistryChangedListener mirroredChangeListener = new YoRegistryChangedListener(changedVariablesInMirror);
   private final YoRegistryChangedListener originalChangeListener = new YoRegistryChangedListener(changedVariablesInOriginal);

   public MirroredYoVariableRegistry(YoRegistry original)
   {
      super(original.getName());

      copyRegistry(original, this);
   }

   private void copyRegistry(YoRegistry original, YoRegistry target)
   {
      List vars = original.getVariables();

      for (YoVariable var : vars)
      {
         YoVariable newVar = var.duplicate(target);
         variableMap.put(var, newVar);
         addVariableListener(newVar, var);
      }

      for (YoRegistry child : original.getChildren())
      {
         YoRegistry newRegistry = new YoRegistry(child.getName());
         target.addChild(newRegistry);
         copyRegistry(child, newRegistry);
      }
   }

   private void addVariableListener(YoVariable newVar, YoVariable var)
   {
      newVar.addListener(mirroredChangeListener);
      var.addListener(originalChangeListener);
   }

   /**
    * Updates changes from the mirror to the original registry and then from the original to the mirror
    * registry
    */
   public void updateMirror()
   {
      updateChangedValues();
      updateValuesFromOriginal();
   }

   /**
    * Mirrors changes from the mirror registry to the original registry
    */
   public void updateChangedValues()
   {
      for (YoVariable changed = changedVariablesInMirror.poll(); changed != null; changed = changedVariablesInMirror.poll())
      {
         YoVariable originalVar = variableMap.inverse().get(changed);
         originalVar.setValue(changed, false);
         callListenersForVariable(originalVar);
      }
   }

   /**
    * Mirrors changes from the original registry to the mirror registry
    */
   public void updateValuesFromOriginal()
   {
      for (YoVariable changed = changedVariablesInOriginal.poll(); changed != null; changed = changedVariablesInOriginal.poll())
      {
         YoVariable mirroredVar = variableMap.get(changed);
         mirroredVar.setValue(changed, false);
         callListenersForVariable(mirroredVar);
      }
   }

   private void callListenersForVariable(YoVariable variable)
   {
      enableChangedListener = false;
      variable.notifyListeners();
      enableChangedListener = true;
   }

   private class YoRegistryChangedListener implements YoVariableChangedListener
   {
      final ConcurrentLinkedQueue queue;

      private YoRegistryChangedListener(ConcurrentLinkedQueue queue)
      {
         this.queue = queue;
      }

      @Override
      public void changed(YoVariable v)
      {
         if (enableChangedListener)
            queue.add(v);
      }
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy