浏览代码

Fix huge blowup of notifications caused by an explicit loop in signal-ing.

Sam Jaffe 5 年之前
父节点
当前提交
9ecabb02b3

+ 3 - 4
src/main/lombok/org/leumasjaffe/recipe/view/PhasePanel.java

@@ -9,7 +9,6 @@ import org.leumasjaffe.observer.ForwardingObservableListener;
 import org.leumasjaffe.observer.Observable;
 import org.leumasjaffe.observer.ObserverDispatch;
 import org.leumasjaffe.recipe.model.Phase;
-import org.leumasjaffe.recipe.model.Preparation;
 import org.leumasjaffe.recipe.model.Step;
 
 import lombok.AccessLevel;
@@ -21,14 +20,15 @@ import org.jdesktop.swingx.VerticalLayout;
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class PhasePanel extends JPanel {
 	ForwardingObservableListener<Phase> listener = new ForwardingObservableListener<>();
-	ForwardingObservableListener<Preparation> linkBack = new ForwardingObservableListener<>();
 
 	AutoGrowPanel panelSteps;
 	
 	public PhasePanel(final Phase phase) {		
 		setLayout(new VerticalLayout(5));
 		
-		phase.getPreparation().ifPresent(prep -> add(new PreparationPanel(prep)));
+		if (phase.getPreparation().isPresent()) {
+			add(new PreparationPanel(phase));
+		}
 		
 		final List<Step> steps = phase.getCooking();
 		panelSteps = new AutoGrowPanel(StepPanel::new, Step::new,
@@ -46,7 +46,6 @@ public class PhasePanel extends JPanel {
 		phase.getRest().ifPresent(rest -> add(new RestPanel(rest)));
 
 		listener.setObserved(phase, allChildren(phase));
-		phase.getPreparation().ifPresent(prep -> linkBack.setObserved(prep, phase));
 	}
 	
 	private static List<Observable> allChildren(Phase phase) {

+ 9 - 7
src/main/lombok/org/leumasjaffe/recipe/view/PreparationPanel.java

@@ -3,11 +3,13 @@ package org.leumasjaffe.recipe.view;
 import javax.swing.JPanel;
 
 import org.jdesktop.swingx.VerticalLayout;
+import org.leumasjaffe.observer.IndirectObservableListener;
 import org.leumasjaffe.observer.ObservableController;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.recipe.controller.ReplaceChildrenController;
 import org.leumasjaffe.recipe.model.Duration;
 import org.leumasjaffe.recipe.model.Ingredient;
+import org.leumasjaffe.recipe.model.Phase;
 import org.leumasjaffe.recipe.model.Preparation;
 
 import lombok.AccessLevel;
@@ -27,7 +29,7 @@ import javax.swing.JFormattedTextField;
 @FieldDefaults(level=AccessLevel.PRIVATE)
 public class PreparationPanel extends JPanel {
 	ReplaceChildrenController<Preparation, Ingredient> controller;
-	ObservableListener<JPanel, Preparation> childListener;
+	IndirectObservableListener<JPanel, Preparation> childListener;
 	ObservableListener<JFormattedTextField, Preparation> durationListener;
 	
 	public PreparationPanel() {
@@ -87,20 +89,20 @@ public class PreparationPanel extends JPanel {
 		panelLeft.add(panelIngredients, gbc_panelIngredients);
 		
 		// This indirection allows for testing of controller
-		childListener = new ObservableListener<>(panelIngredients,
+		childListener = new IndirectObservableListener<>(panelIngredients,
 				(c, v) -> controller.accept(c, v));
 		durationListener = ObservableController.from(panelDuration.txtTime,
 				Preparation::getDuration, Preparation::setDuration);
 	}
 	
-	public PreparationPanel(final Preparation preparation) {
+	public PreparationPanel(final Phase phase) {
 		this();
-		setModel(preparation);
+		setModel(phase);
 	}
 	
-	public void setModel(final Preparation preparation) {
-		durationListener.setObserved(preparation);
-		childListener.setObserved(preparation);
+	public void setModel(final Phase phase) {
+		durationListener.setObserved(phase.getPreparation().get());
+		childListener.setObserved(phase.getPreparation().get(), phase);
 	}
 
 }

+ 7 - 2
src/test/java/org/leumasjaffe/recipe/view/PreparationPanelTest.java

@@ -2,6 +2,8 @@ package org.leumasjaffe.recipe.view;
 
 import static org.mockito.Mockito.*;
 
+import java.util.Optional;
+
 import javax.swing.JFormattedTextField;
 
 import org.junit.jupiter.api.BeforeEach;
@@ -11,6 +13,7 @@ import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
 import org.leumasjaffe.recipe.controller.ReplaceChildrenController;
 import org.leumasjaffe.recipe.model.Ingredient;
+import org.leumasjaffe.recipe.model.Phase;
 import org.leumasjaffe.recipe.model.Preparation;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
@@ -22,11 +25,13 @@ class PreparationPanelTest extends SwingTestCase {
 	@Mock ObservableListener<JFormattedTextField, Preparation> durationListener;
 	@Mock ReplaceChildrenController<Preparation, Ingredient> controller;
 	Preparation stuff = new Preparation();
+	@Mock Phase parent;
 	@InjectMocks PreparationPanel panel = new PreparationPanel();
 	
 	@BeforeEach
 	void setUp() {
-		panel.setModel(stuff);
+		doReturn(Optional.of(stuff)).when(parent).getPreparation();
+		panel.setModel(parent);
 	}
 
 	@Test
@@ -37,7 +42,7 @@ class PreparationPanelTest extends SwingTestCase {
 
 	@Test
 	void testUpdatesNumberOfChildrenWhenNotified() {
-		ObserverDispatch.notifySubscribers(stuff);		
+		ObserverDispatch.notifySubscribers(parent);		
 
 		verify(controller, times(2)).accept(any(), same(stuff));
 	}