us.ihmc.simulationconstructionset.dataBuffer.MirroredYoVariableRegistry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simulation-construction-set
Show all versions of simulation-construction-set
Simulation Construction Set
package us.ihmc.simulationconstructionset.dataBuffer;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import us.ihmc.yoVariables.registry.YoRegistry;
import us.ihmc.yoVariables.variable.YoVariable;
public class MirroredYoVariableRegistry extends YoRegistry
{
private final ConcurrentLinkedQueue mirrorPendingActions = new ConcurrentLinkedQueue<>();
private final ConcurrentLinkedQueue originalPendingActions = new ConcurrentLinkedQueue<>();
public MirroredYoVariableRegistry(YoRegistry original)
{
super(original.getName());
copyRegistry(original, this);
}
private void copyRegistry(YoRegistry original, YoRegistry mirror)
{
List originalVariables = original.getVariables();
for (YoVariable originalVariable : originalVariables)
{
YoVariable mirrorVariable = originalVariable.duplicate(mirror);
bindVariables(originalVariable, mirrorVariable, originalPendingActions, mirrorPendingActions);
}
for (YoRegistry childMirror : original.getChildren())
{
YoRegistry newRegistry = new YoRegistry(childMirror.getName());
mirror.addChild(newRegistry);
copyRegistry(childMirror, newRegistry);
}
}
/**
* 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()
{
while (!mirrorPendingActions.isEmpty())
mirrorPendingActions.poll().run();
}
/**
* Mirrors changes from the original registry to the mirror registry
*/
public void updateValuesFromOriginal()
{
while (!originalPendingActions.isEmpty())
originalPendingActions.poll().run();
}
private static void bindVariables(YoVariable variableA,
YoVariable variableB,
ConcurrentLinkedQueue actionQueueA,
ConcurrentLinkedQueue actionQueueB)
{
Runnable actionA = () -> variableB.setValue(variableA, true);
Runnable actionB = () -> variableA.setValue(variableB, true);
variableA.addListener(v ->
{
if (variableA.getValueAsLongBits() != variableB.getValueAsLongBits())
actionQueueA.add(actionA);
});
variableB.addListener(v ->
{
if (variableA.getValueAsLongBits() != variableB.getValueAsLongBits())
actionQueueB.add(actionB);
});
}
ConcurrentLinkedQueue getMirrorPendingActions()
{
return mirrorPendingActions;
}
ConcurrentLinkedQueue getOriginalPendingActions()
{
return originalPendingActions;
}
}