001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.perseus.model;
027:
028: import java.util.Vector;
029:
030: import java.io.PrintStream;
031:
032: /**
033: *
034: * @version $Id: TimeContainerSupport.java,v 1.4 2006/06/29 10:47:35 ln156897 Exp $
035: */
036: public class TimeContainerSupport extends TimedElementSupport {
037: /**
038: * The container's current simple time
039: */
040: protected Time simpleTime = Time.UNRESOLVED;
041:
042: /**
043: * The set of children TimedElementSupport contained
044: * in this container.
045: */
046: protected Vector timedElementChildren = new Vector(5);
047:
048: /**
049: * Default constructor
050: */
051: public TimeContainerSupport() {
052: }
053:
054: /**
055: * @return this container's current simple time
056: */
057: public Time getSimpleTime() {
058: return simpleTime;
059: }
060:
061: /**
062: * Resets this container and all its children. This, in effect, moves the
063: * container back to the begining of its timeline, i.e., prior to begining
064: * the first interval.
065: */
066: protected void initialize() {
067: super .initialize();
068:
069: // If a new interval was created, children have already been initialized
070: // (see dispatchOnNewInterval). Otherwise, make sure we initialize the
071: // full tree.
072: if (currentInterval == null) {
073: for (int i = 0; i < timedElementChildren.size(); i++) {
074: TimedElementSupport child = (TimedElementSupport) timedElementChildren
075: .elementAt(i);
076: child.initialize();
077: }
078: }
079: }
080:
081: /**
082: * When a container resets, it needs to clear all its children which have
083: * IntervalTimeInstances on syncBases which are also children
084: * (or descendants) of this container.
085: *
086: * @see <a href="http://www.w3.org/TR/smil20#smil-timing-Timing-ResetDefaultAttribute">
087: * SMIL 2 Specification, Resetting element state</a>
088: */
089: void reset() {
090: super .reset();
091:
092: for (int i = 0; i < timedElementChildren.size(); i++) {
093: TimedElementSupport child = (TimedElementSupport) timedElementChildren
094: .elementAt(i);
095: child.removeSyncBaseTimesUnder(this );
096: }
097:
098: }
099:
100: /**
101: * Removes all <code>IntervalTimeInstance</code>s in the begin and end
102: * instance list if the syncBase is a descendant of syncTimeContainer
103: *
104: * @param syncTimeContainer the container under which times should be
105: * removed.
106: */
107: void removeSyncBaseTimesUnder(
108: final TimeContainerSupport syncTimeContainer) {
109: super .removeSyncBaseTimesUnder(syncTimeContainer);
110:
111: for (int i = 0; i < timedElementChildren.size(); i++) {
112: TimedElementSupport child = (TimedElementSupport) timedElementChildren
113: .elementAt(i);
114: child.removeSyncBaseTimesUnder(syncTimeContainer);
115: }
116: }
117:
118: /**
119: * Samples this time container at the given simple time.
120: *
121: * @param simpleTime this timed element's simple time.
122: */
123: void sampleAt(final long simpleTime) {
124: setSimpleTime(simpleTime);
125:
126: for (int i = 0; i < timedElementChildren.size(); i++) {
127: TimedElementSupport child = (TimedElementSupport) timedElementChildren
128: .elementAt(i);
129: if (seeking) {
130: child.seeking = true;
131: child.sample(this .simpleTime);
132: child.seeking = false;
133: } else {
134: child.sample(this .simpleTime);
135: }
136: }
137: }
138:
139: /**
140: * Dispatches endEvent. As per the SMIL 2 specification, this dispatches
141: * an endEvent for the resolved end time, not the observed end
142: * time.
143: *
144: * @param currentTime the current sampling time.
145: *
146: * @see <a href="http://www.w3.org/TR/smil20/smil-timing.html#Timing-BeginValueSemantics">
147: * SMIL2's Begin value semantics</a>
148: */
149: void dispatchEndEvent(final Time currentTime) {
150: super .dispatchEndEvent(currentTime);
151:
152: // Now, force children to end now. Before invoking children, we need
153: // to update the container's simpleTime.
154: long time = currentInterval.end.value
155: - currentInterval.begin.value;
156: if (simpleDur.isResolved()) {
157: if (time > 0) {
158: time = time % simpleDur.value;
159: if (time == 0) {
160: time = simpleDur.value;
161: }
162: }
163: }
164:
165: endChildrenAt(time);
166: }
167:
168: /**
169: * Calls all the registered <code>TimeDependent</code>s so that they
170: * are notified of a new TimeInterval creation. When a time container
171: * creates a new interval, its children are re-initialized.
172: */
173: void dispatchOnNewInterval() {
174: super .dispatchOnNewInterval();
175:
176: // Now, re-initialize all children.
177: for (int i = 0; i < timedElementChildren.size(); i++) {
178: TimedElementSupport child = (TimedElementSupport) timedElementChildren
179: .elementAt(i);
180: child.initialize();
181: }
182: }
183:
184: /**
185: * Implementation helper to set the simple time object.
186: *
187: * @param time the new simple time value
188: */
189: void setSimpleTime(final long time) {
190: if (simpleTime == Time.UNRESOLVED) {
191: simpleTime = new Time(time);
192: } else {
193: simpleTime.value = time;
194: }
195: }
196:
197: /**
198: * When a container starts a new iteration, it needs to:
199: * - end its children at the end of the previous interval.
200: * - reset its children.
201: *
202: * @param prevIter the last iteration this element was playing.
203: * @param curIter the new iteration this element is playing.
204: */
205: protected void onStartingRepeat(final int prevIter,
206: final int curIter) {
207: // First, force ending children at the end of the previous iteration.
208: long time = currentInterval.begin.value + simpleDur.value
209: * (prevIter + 1);
210:
211: endChildrenAt(time);
212:
213: // Now, reset the children so that they are ready for the next sampling
214: // at the begining of current interval.
215: for (int i = 0; i < timedElementChildren.size(); i++) {
216: TimedElementSupport child = (TimedElementSupport) timedElementChildren
217: .elementAt(i);
218: child.initialize();
219: }
220:
221: }
222:
223: /**
224: * Implementation helper. Ends all children at the requested input time.
225: *
226: * @param time the time, in this container's simple time system, at which
227: * children should be stopped.
228: */
229: void endChildrenAt(final long time) {
230: setSimpleTime(time);
231:
232: // First, end all children. Adding end times does not cause a state
233: // transition. To make the children transition to their new state, we
234: // invoke sample in a second iteration (see below).
235: for (int i = 0; i < timedElementChildren.size(); i++) {
236: TimedElementSupport child = (TimedElementSupport) timedElementChildren
237: .elementAt(i);
238: child.end();
239: }
240:
241: // Now, sample children on the end time
242: for (int i = 0; i < timedElementChildren.size(); i++) {
243: TimedElementSupport child = (TimedElementSupport) timedElementChildren
244: .elementAt(i);
245: child.sample(simpleTime);
246: }
247: }
248:
249: /**
250: * Debug method: Traces the container and all its children.
251: */
252: /**
253: * Traces this viewport tree
254: */
255: void dump() {
256: dump(this , "", System.err);
257: }
258:
259: /**
260: * Debug: traces the input ModelNode, using the input prefix
261: *
262: * @param t the node to dump
263: * @param prefix the string used to prefix the node information
264: * @param out the stream where the node structure is dumped.
265: */
266: static void dump(final TimedElementSupport t, final String prefix,
267: final PrintStream out) {
268: out.println(prefix + t);
269: if (t instanceof TimeContainerSupport) {
270: TimeContainerSupport tc = (TimeContainerSupport) t;
271: for (int i = 0; i < tc.timedElementChildren.size(); i++) {
272: TimedElementSupport c = (TimedElementSupport) tc.timedElementChildren
273: .elementAt(i);
274: dump(c, prefix + "+--> ", out);
275: }
276: }
277: }
278: }
|