View Javadoc

1   /*
2    * Entreri, an entity-component framework in Java
3    *
4    * Copyright (c) 2013, Michael Ludwig
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without modification,
8    * are permitted provided that the following conditions are met:
9    *
10   *     Redistributions of source code must retain the above copyright notice,
11   *         this list of conditions and the following disclaimer.
12   *     Redistributions in binary form must reproduce the above copyright notice,
13   *         this list of conditions and the following disclaimer in the
14   *         documentation and/or other materials provided with the distribution.
15   *
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package com.lhkbob.entreri.impl;
28  
29  import com.lhkbob.entreri.Component;
30  import com.lhkbob.entreri.Entity;
31  import com.lhkbob.entreri.Ownable;
32  import com.lhkbob.entreri.Owner;
33  
34  import java.util.HashSet;
35  import java.util.Set;
36  
37  /**
38   * Utility for shared implementation of {@link com.lhkbob.entreri.Ownable} and {@link
39   * com.lhkbob.entreri.Owner}
40   *
41   * @author Michael Ludwig
42   */
43  class OwnerSupport {
44      private final Ownable target;
45      private final Set<Ownable> ownedObjects;
46      private Owner currentOwner;
47  
48      /**
49       * Create a new OwnerSupport that functions as both the {@link Owner} and {@link
50       * Ownable} implementation for <var>target</var>
51       *
52       * @param target The actual ownable
53       */
54      public OwnerSupport(Ownable target) {
55          if (target == null) {
56              throw new NullPointerException("Ownable cannot be null");
57          }
58          this.target = target;
59          ownedObjects = new HashSet<>();
60          currentOwner = null;
61      }
62  
63      /**
64       * @param obj The object now owned
65       *
66       * @see Owner#notifyOwnershipGranted(Ownable)
67       */
68      public void notifyOwnershipGranted(Ownable obj) {
69          ownedObjects.add(obj);
70      }
71  
72      /**
73       * @param obj The object no longer owned
74       *
75       * @see Owner#notifyOwnershipRevoked(Ownable)
76       */
77      public void notifyOwnershipRevoked(Ownable obj) {
78          ownedObjects.remove(obj);
79      }
80  
81      /**
82       * @param owner The owner, possibly flyweight
83       *
84       * @see Ownable#setOwner(Owner)
85       */
86      public void setOwner(Owner owner) {
87          if (currentOwner != null) {
88              currentOwner.notifyOwnershipRevoked(target);
89          }
90          if (owner != null) {
91              currentOwner = owner.notifyOwnershipGranted(target);
92          } else {
93              currentOwner = null;
94          }
95      }
96  
97      /**
98       * @return The owner
99       *
100      * @see Ownable#getOwner()
101      */
102     public Owner getOwner() {
103         return currentOwner;
104     }
105 
106     /**
107      * Set the owner of all currently owned children to null. If any of the children are
108      * entities or components, they are removed from their creating system or entity,
109      * respectively.
110      */
111     public void disownAndRemoveChildren() {
112         // Mark all owned objects as not owned
113         // if they are an entity or component, recurse and remove them as well
114         Set<Ownable> cloned = new HashSet<Ownable>(ownedObjects);
115         for (Ownable owned : cloned) {
116             owned.setOwner(null);
117             if (owned instanceof Entity) {
118                 Entity ownedEntity = (Entity) owned;
119                 ownedEntity.getEntitySystem().removeEntity(ownedEntity);
120             } else if (owned instanceof Component) {
121                 Component ownedComp = (Component) owned;
122                 ownedComp.getEntity().remove(ownedComp.getType());
123             }
124         }
125     }
126 }