[1097] | 1 | package org.expeditee.core;
|
---|
| 2 |
|
---|
| 3 | import java.util.Stack;
|
---|
| 4 |
|
---|
| 5 | public class EnforcedClipStack {
|
---|
| 6 |
|
---|
| 7 | /** The stack of sub-area clips. */
|
---|
| 8 | private Stack<Clip> _clipStack;
|
---|
| 9 |
|
---|
| 10 | /** Default constructor. */
|
---|
| 11 | public EnforcedClipStack()
|
---|
| 12 | {
|
---|
| 13 | _clipStack = new Stack<Clip>();
|
---|
| 14 | }
|
---|
| 15 |
|
---|
| 16 | /** Pushes a new clip onto the stack, ensuring that it is a sub-area of the top of the stack. */
|
---|
| 17 | public EnforcedClipKey push(Clip clip)
|
---|
| 18 | {
|
---|
| 19 | // No null clips allowed
|
---|
| 20 | if (clip == null) return null;
|
---|
| 21 |
|
---|
| 22 | // Leave the given clip unchanged (in case the provider wants to keep using it)
|
---|
| 23 | clip = clip.clone();
|
---|
| 24 |
|
---|
| 25 | // Each clip must be a sub-area of the one below it in the stack
|
---|
| 26 | if (!_clipStack.isEmpty()) {
|
---|
| 27 | clip.intersectWith(_clipStack.peek());
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | // Put the new clip on the stack
|
---|
| 31 | _clipStack.push(clip);
|
---|
| 32 |
|
---|
| 33 | // Return the clipped area
|
---|
| 34 | return EnforcedClipKey.get(clip);
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 | /** Pops the top of the stack if there given key corresponds to it. */
|
---|
| 38 | public Clip pop(EnforcedClipKey key)
|
---|
| 39 | {
|
---|
| 40 | if (!_clipStack.isEmpty() && key != null && key.matches(_clipStack.peek())) return _clipStack.pop();
|
---|
| 41 |
|
---|
| 42 | return null;
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | /** Returns a copy of the current top of the stack. */
|
---|
| 46 | public Clip peek()
|
---|
| 47 | {
|
---|
| 48 | if (!_clipStack.isEmpty()) return _clipStack.peek().clone();
|
---|
| 49 |
|
---|
| 50 | return null;
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | /** Key class to ensure only the owner of a given pushed clip can pop it again. */
|
---|
| 54 | public static class EnforcedClipKey {
|
---|
| 55 |
|
---|
| 56 | /** The clip this key corresponds to. */
|
---|
| 57 | private Clip _keyedClip;
|
---|
| 58 |
|
---|
| 59 | /** Gets a key for the given clip. */
|
---|
| 60 | public static EnforcedClipKey get(Clip clip)
|
---|
| 61 | {
|
---|
| 62 | if (clip == null) return null;
|
---|
| 63 |
|
---|
| 64 | return new EnforcedClipKey(clip);
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | /** Private constructor so clip cannot be null. */
|
---|
| 68 | private EnforcedClipKey(Clip clip)
|
---|
| 69 | {
|
---|
| 70 | _keyedClip = clip;
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | /** Whether this key corresponds to the given clip. */
|
---|
| 74 | public boolean matches(Clip clip)
|
---|
| 75 | {
|
---|
| 76 | return clip == _keyedClip;
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | }
|
---|