-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bb03a10
commit 0fbb014
Showing
6 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
module-fx/src/main/java/place/sita/modulefx/BadApiUsageException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package place.sita.modulefx; | ||
|
||
public class BadApiUsageException extends RuntimeException { | ||
|
||
public BadApiUsageException() { | ||
} | ||
|
||
public BadApiUsageException(String message) { | ||
super(message); | ||
} | ||
|
||
public BadApiUsageException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
public BadApiUsageException(Throwable cause) { | ||
super(cause); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
module-fx/src/main/java/place/sita/modulefx/vtg/MessageListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package place.sita.modulefx.vtg; | ||
|
||
public interface MessageListener { | ||
|
||
void receive(Object message); | ||
|
||
} |
65 changes: 65 additions & 0 deletions
65
module-fx/src/main/java/place/sita/modulefx/vtg/VirtualTreeGroup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package place.sita.modulefx.vtg; | ||
|
||
import place.sita.modulefx.BadApiUsageException; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
public class VirtualTreeGroup { | ||
|
||
private final UUID id = UUID.randomUUID(); | ||
private VirtualTreeGroup parent; | ||
private final List<VirtualTreeGroup> children = new ArrayList<>(); | ||
private final List<VirtualTreeGroupElement> group = new ArrayList<>(); | ||
|
||
public UUID id() { | ||
return id; | ||
} | ||
|
||
public void addChild(VirtualTreeGroup node) { | ||
if (node.parent != null) { | ||
throw new BadApiUsageException("Node already has a parent"); | ||
} | ||
node.parent = this; | ||
children.add(node); | ||
} | ||
|
||
public void removeChild(UUID id) { | ||
VirtualTreeGroup child = children.stream().filter(n -> n.id().equals(id)).findFirst().orElse(null); | ||
|
||
if (child == null) { | ||
throw new BadApiUsageException("Not a child of this group"); | ||
} | ||
|
||
child.parent = null; | ||
children.remove(child); | ||
} | ||
|
||
/** | ||
* Passes message to all other connected nodes | ||
*/ | ||
public void message(UUID senderId, Object message) { | ||
for (VirtualTreeGroupElement element : group) { | ||
if (element.getId().equals(senderId)) { | ||
continue; | ||
} | ||
element.receive(message); | ||
} | ||
|
||
if (parent != null && !parent.id().equals(senderId)) { | ||
parent.message(id, message); | ||
} | ||
|
||
for (VirtualTreeGroup child : children) { | ||
if (!child.id().equals(senderId)) { | ||
child.message(id, message); | ||
} | ||
} | ||
} | ||
|
||
public void addElement(VirtualTreeGroupElement element) { | ||
group.add(element); | ||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
module-fx/src/main/java/place/sita/modulefx/vtg/VirtualTreeGroupElement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package place.sita.modulefx.vtg; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
public class VirtualTreeGroupElement { | ||
|
||
private final UUID id = UUID.randomUUID(); | ||
private final List<MessageListener> listeners = new ArrayList<>(); | ||
|
||
public UUID getId() { | ||
return id; | ||
} | ||
|
||
public void addListener(MessageListener listener) { | ||
listeners.add(listener); | ||
} | ||
|
||
public void receive(Object message) { | ||
for (MessageListener listener : listeners) { | ||
listener.receive(message); | ||
} | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
module-fx/src/test/java/place/sita/modulefx/vtg/VirtualTreeGroupTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package place.sita.modulefx.vtg; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
import place.sita.modulefx.BadApiUsageException; | ||
|
||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
|
||
public class VirtualTreeGroupTest { | ||
|
||
@Test | ||
public void shouldReportAddingChildTwice() { | ||
// given | ||
VirtualTreeGroup group = new VirtualTreeGroup(); | ||
VirtualTreeGroup child = new VirtualTreeGroup(); | ||
group.addChild(child); | ||
|
||
// when | ||
assertThatThrownBy(() -> group.addChild(child)) | ||
// then | ||
.isInstanceOf(BadApiUsageException.class) | ||
.hasMessage("Node already has a parent"); | ||
} | ||
|
||
@Test | ||
public void shouldPassMessageToChildrenParentAndOtherElementsButNotSelf() { | ||
// given | ||
VirtualTreeGroup groupWithSelf = new VirtualTreeGroup(); | ||
VirtualTreeGroup parent = new VirtualTreeGroup(); | ||
VirtualTreeGroup child = new VirtualTreeGroup(); | ||
parent.addChild(groupWithSelf); | ||
groupWithSelf.addChild(child); | ||
|
||
MessageListener listenerInParent = Mockito.mock(MessageListener.class); | ||
MessageListener otherListenerInMiddle = Mockito.mock(MessageListener.class); | ||
MessageListener selfListenerInMiddle = Mockito.mock(MessageListener.class); | ||
MessageListener listenerInChild = Mockito.mock(MessageListener.class); | ||
|
||
VirtualTreeGroupElement parentElement = new VirtualTreeGroupElement(); | ||
parentElement.addListener(listenerInParent); | ||
parent.addElement(parentElement); | ||
|
||
VirtualTreeGroupElement otherElementInMiddle = new VirtualTreeGroupElement(); | ||
otherElementInMiddle.addListener(otherListenerInMiddle); | ||
groupWithSelf.addElement(otherElementInMiddle); | ||
|
||
VirtualTreeGroupElement selfElementInMiddle = new VirtualTreeGroupElement(); | ||
selfElementInMiddle.addListener(selfListenerInMiddle); | ||
groupWithSelf.addElement(selfElementInMiddle); | ||
|
||
VirtualTreeGroupElement childElement = new VirtualTreeGroupElement(); | ||
childElement.addListener(listenerInChild); | ||
child.addElement(childElement); | ||
|
||
// when | ||
groupWithSelf.message(selfElementInMiddle.getId(), "message"); | ||
|
||
// then | ||
Mockito.verify(listenerInParent).receive("message"); | ||
Mockito.verify(otherListenerInMiddle).receive("message"); | ||
Mockito.verify(selfListenerInMiddle, Mockito.never()).receive(anyString()); | ||
Mockito.verify(listenerInChild).receive("message"); | ||
} | ||
|
||
@Test | ||
public void shouldNotMessageRemovedChild() { | ||
// given | ||
VirtualTreeGroup group = new VirtualTreeGroup(); | ||
VirtualTreeGroup child = new VirtualTreeGroup(); | ||
group.addChild(child); | ||
|
||
MessageListener listener = Mockito.mock(MessageListener.class); | ||
VirtualTreeGroupElement element = new VirtualTreeGroupElement(); | ||
element.addListener(listener); | ||
child.addElement(element); | ||
|
||
// when | ||
group.removeChild(child.id()); | ||
group.message(element.getId(), "message"); | ||
|
||
// then | ||
Mockito.verify(listener, Mockito.never()).receive("message"); | ||
} | ||
|
||
} |