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 }