3
* This file is part of jReality. jReality is open source software, made
4
* available under a BSD license:
6
* Copyright (c) 2003-2006, jReality Group: Charles Gunn, Tim Hoffmann, Markus
7
* Schmies, Steffen Weissmann.
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions are met:
14
* - Redistributions of source code must retain the above copyright notice, this
15
* list of conditions and the following disclaimer.
17
* - Redistributions in binary form must reproduce the above copyright notice,
18
* this list of conditions and the following disclaimer in the documentation
19
* and/or other materials provided with the distribution.
21
* - Neither the name of jReality nor the names of its contributors nor the
22
* names of their associated organizations may be used to endorse or promote
23
* products derived from this software without specific prior written
26
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
* POSSIBILITY OF SUCH DAMAGE.
41
package opencog.spacetime.scene;
43
import java.util.Collections;
44
import java.util.HashMap;
46
import java.util.Map.Entry;
48
import opencog.spacetime.scene.data.AttributeEntity;
49
import opencog.spacetime.scene.event.AppearanceEvent;
50
import opencog.spacetime.scene.event.AppearanceEventMulticaster;
51
import opencog.spacetime.scene.event.AppearanceListener;
55
* The appearance node. Contains attributes of arbitrary type stored as <i>(key,value)</i>
56
* pairs in a HashMap<String, Object>. There are special methods for setting attributes
57
* whose values are common built-in types: <code>double</code>, <code>float</code>,<code>int</code>,
58
* <code>boolean</code>,and <code>char</code>.
60
* You can query the state of the Appearance by using {@link #getAttribute(String)}. If
61
* not attribute has been defined for this key, the special object {@link #INHERITED} is returned.
63
* If you wish to remove an attribute value from the key <i>foo</i>, call
65
* setAttribute(foo, Appearance.INHERITED);
68
* Some wiser person will have to tell you when the special object {@link #DEFAULT} is returned.
70
* TODO: fire ONE single event that reports all changed attributes
73
public class Appearance extends SceneGraphNode
75
// steffen: i changed these to objects otherwise an effective appearance can never return them...
76
// obsolete now: it would be convenient if these were no inner classes but just objects....
77
public static final Object DEFAULT = new Object();
78
public static final Object INHERITED = new Object();
80
private transient AppearanceListener appearanceListener;
81
private HashMap<String, Object> attributes=new HashMap<String, Object>();
82
private Set<String> storedAttributes = Collections.unmodifiableSet(attributes.keySet());
84
private transient HashMap<String, Object> changedAttributes=new HashMap<String, Object>();
86
private static int UNNAMED_ID;
88
public Appearance(String name) {
93
super("app "+(UNNAMED_ID++));
96
public Object getAttribute(String key)
100
Object aa=attributes.get(key);
101
return aa!=null? aa : INHERITED;
107
public Object getAttribute(String key, Class type)
111
Object val=getAttribute(key);
112
if(val==DEFAULT||type.isInstance(val)) return val;
119
public void setAttribute(String key, Object value)
121
setAttribute(key, value, value.getClass());
124
public void setAttribute(String key, Object value, Class declaredType)
131
if(declaredType==null||value==null) throw new NullPointerException();
134
old=attributes.remove(key);
138
// TODO: is this check ok? (cheap enough?)
139
if (AttributeEntity.class.isAssignableFrom(value.getClass()))
140
throw new IllegalArgumentException("no proxies allowed");
141
old=attributes.put(key, value);
143
// TODO: if (!new.equals(old)) ... ???
144
if (old != value ) fireAppearanceChanged(key, old);
149
public void setAttribute(String key, double value)
151
setAttribute(key, new Double(value));
153
public void setAttribute(String key, float value)
155
setAttribute(key, new Float(value));
157
public void setAttribute(String key, int value)
159
setAttribute(key, new Integer(value));
161
public void setAttribute(String key, long value)
163
setAttribute(key, new Long(value));
165
public void setAttribute(String key, boolean value)
167
setAttribute(key, Boolean.valueOf(value));
169
public void setAttribute(String key, char value)
171
setAttribute(key, new Character(value));
174
public void addAppearanceListener(AppearanceListener listener) {
176
appearanceListener=AppearanceEventMulticaster.add(appearanceListener, listener);
179
public void removeAppearanceListener(AppearanceListener listener) {
181
appearanceListener=AppearanceEventMulticaster.remove(appearanceListener, listener);
186
* Tell the outside world that this appearance has changed.
188
protected void writingFinished() {
190
for (Entry<String, Object> e : changedAttributes.entrySet() ) {
191
appearanceListener.appearanceChanged(new AppearanceEvent(this, e.getKey(), e.getValue()));
194
changedAttributes.clear();
198
protected void fireAppearanceChanged(String key, Object old) {
199
if(appearanceListener != null) changedAttributes.put(key, old);
202
public Set getStoredAttributes() {
203
return storedAttributes;
206
public void accept(SceneGraphVisitor v) {
214
static void superAccept(Appearance a, SceneGraphVisitor v) {
217
private void superAccept(SceneGraphVisitor v) {