From c8bc1ca363da67653e1f857a6dc63388004d2802 Mon Sep 17 00:00:00 2001 From: player-03 Date: Wed, 4 Jan 2012 23:25:48 -0500 Subject: [PATCH 1/2] Removed strong references that weren't being used but could in the way of garbage collection. --- src/away3d/containers/Scene3D.as | 192 ++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 4 deletions(-) diff --git a/src/away3d/containers/Scene3D.as b/src/away3d/containers/Scene3D.as index 907a992..dee633b 100644 --- a/src/away3d/containers/Scene3D.as +++ b/src/away3d/containers/Scene3D.as @@ -1,7 +1,191 @@ -package away3d.containers { +package away3d.containers +{ import away3d.arcane; import away3d.core.base.*; - import away3d.core.session.*; import away3d.core.traverse.*; import away3d.lights.*; import flash.utils.*; use namespace arcane; /** * The root container of all 3d objects in a single scene */ public class Scene3D extends ObjectContainer3D { /** @private */ arcane function setId(object:Object3D):void { var i:int = 0; while(_objects.length > i && _objects[i]) i++; _objects[i] = object; object._id = i; } /** @private */ arcane function clearId(id:int):void { delete _objects[id]; } /** @private */ arcane function internalRemoveLight(light:AbstractLight):void { var index:int; if (light is AmbientLight3D) { index = _ambientLights.indexOf(light); if (index == -1) return; _ambientLights.splice(index, 1); } else if (light is DirectionalLight3D) { index = _directionalLights.indexOf(light); if (index == -1) return; _directionalLights.splice(index, 1); } else if (light is PointLight3D) { index = _pointLights.indexOf(light); if (index == -1) return; _pointLights.splice(index, 1); } _numLights--; } /** @private */ arcane function internalAddLight(light:AbstractLight):void { if (light is AmbientLight3D) _ambientLights.push(light as AmbientLight3D); else if (light is DirectionalLight3D) _directionalLights.push(light as DirectionalLight3D); else if (light is PointLight3D) _pointLights.push(light as PointLight3D); _numLights++; } /** @private */ arcane function flagObject(object:Object3D):void { + import away3d.core.session.*; + import away3d.core.traverse.*; + import away3d.lights.*; + + import flash.utils.*; + + use namespace arcane; + + /** + * The root container of all 3d objects in a single scene + */ + public class Scene3D extends ObjectContainer3D + { + /** @private */ + arcane function setId(object:Object3D):void + { + var i:int = 0; + + while(_objects.length > i && _objects[i]) + i++; + + _objects[i] = object; + + object._id = i; + } + /** @private */ + arcane function clearId(id:int):void + { + delete _objects[id]; + } + /** @private */ + arcane function internalRemoveLight(light:AbstractLight):void + { + var index:int; + + if (light is AmbientLight3D) { + index = _ambientLights.indexOf(light); + if (index == -1) + return; + _ambientLights.splice(index, 1); + } else if (light is DirectionalLight3D) { + index = _directionalLights.indexOf(light); + if (index == -1) + return; + _directionalLights.splice(index, 1); + } else if (light is PointLight3D) { + index = _pointLights.indexOf(light); + if (index == -1) + return; + _pointLights.splice(index, 1); + } + + _numLights--; + } + /** @private */ + arcane function internalAddLight(light:AbstractLight):void + { + if (light is AmbientLight3D) + _ambientLights.push(light as AmbientLight3D); + else if (light is DirectionalLight3D) + _directionalLights.push(light as DirectionalLight3D); + else if (light is PointLight3D) + _pointLights.push(light as PointLight3D); + + _numLights++; + } + /** @private */ + arcane function flagObject(object:Object3D):void + { for each (_view in viewDictionary) - _view._updatedObjects[object] = object; } /** @private */ arcane function flagSession(session:AbstractSession):void { for each (_view in viewDictionary) _view._updatedSessions[session] = session; } private var _ambientLights:Vector. = new Vector.(); private var _directionalLights:Vector. = new Vector.(); private var _pointLights:Vector. = new Vector.(); private var _numLights:uint; private var _objects:Vector. = new Vector.(); private var _view:View3D; public var viewDictionary:Dictionary = new Dictionary(true); /** * Traverser object for all custom tick() methods * * @see away3d.core.base.Object3D#tick() */ public var tickTraverser:TickTraverser = new TickTraverser(); /** * Defines whether scene events are automatically triggered by the view, or manually by updateScene() */ public var autoUpdate:Boolean; /** * Interface for physics (not implemented) */ public var physics:IPhysicsScene; public function get ambientLights():Vector. { - return _ambientLights; } public function get directionalLights():Vector. { return _directionalLights; } public function get pointLights():Vector. { return _pointLights; } public function get numLights():uint { return _numLights; } /** * Creates a new Scene3D object * * @param ...initarray An array of 3d objects to be added as children of the scene on instatiation. Can contain an initialisation object */ public function Scene3D(...initarray) { var init:Object; var childarray:Vector. = new Vector.(); for each (var object:Object in initarray) if (object is Object3D) childarray.push(object as Object3D); else init = object; //force ownCanvas and ownLights if (init) init["ownCanvas"] = true; else init = {ownCanvas:true}; super(init); autoUpdate = ini.getBoolean("autoUpdate", true); var ph:Object = ini.getObject("physics"); if (ph is IPhysicsScene) physics = ph as IPhysicsScene; if (ph is Boolean) if (ph == true) physics = null; // new RobPhysicsEngine(); if (ph is Object) physics = null; // new RobPhysicsEngine(ph); // ph - init object for each (var child:Object3D in childarray) addChild(child); } /** * Calling manually will update 3d objects that execute updates on their tick() methods. * Uses the TickTraverser to traverse all tick methods in the scene. * * @see away3d.core.base.Object3D#tick() * @see away3d.core.traverse.TickTraverser */ public function updateTime(time:int = -1):void { //set current time if (time == -1) time = getTimer(); //traverser scene ticks tickTraverser.now = time; traverse(tickTraverser); if (physics != null) physics.updateTime(time); } } } \ No newline at end of file + _view._updatedObjects[object] = true; + } + /** @private */ + arcane function flagSession(session:AbstractSession):void + { + for each (_view in viewDictionary) + _view._updatedSessions[session] = true; + } + + private var _ambientLights:Vector. = new Vector.(); + private var _directionalLights:Vector. = new Vector.(); + private var _pointLights:Vector. = new Vector.(); + private var _numLights:uint; + private var _objects:Vector. = new Vector.(); + private var _view:View3D; + + public var viewDictionary:Dictionary = new Dictionary(true); + + /** + * Traverser object for all custom tick() methods + * + * @see away3d.core.base.Object3D#tick() + */ + public var tickTraverser:TickTraverser = new TickTraverser(); + + /** + * Defines whether scene events are automatically triggered by the view, or manually by updateScene() + */ + public var autoUpdate:Boolean; + + /** + * Interface for physics (not implemented) + */ + public var physics:IPhysicsScene; + + public function get ambientLights():Vector. + { + return _ambientLights; + } + + public function get directionalLights():Vector. + { + return _directionalLights; + } + + public function get pointLights():Vector. + { + return _pointLights; + } + + public function get numLights():uint + { + return _numLights; + } + + /** + * Creates a new Scene3D object + * + * @param ...initarray An array of 3d objects to be added as children of the scene on instatiation. Can contain an initialisation object + */ + public function Scene3D(...initarray) + { + var init:Object; + var childarray:Vector. = new Vector.(); + + for each (var object:Object in initarray) + if (object is Object3D) + childarray.push(object as Object3D); + else + init = object; + + //force ownCanvas and ownLights + if (init) + init["ownCanvas"] = true; + else + init = {ownCanvas:true}; + + super(init); + + autoUpdate = ini.getBoolean("autoUpdate", true); + + var ph:Object = ini.getObject("physics"); + if (ph is IPhysicsScene) + physics = ph as IPhysicsScene; + if (ph is Boolean) + if (ph == true) + physics = null; // new RobPhysicsEngine(); + if (ph is Object) + physics = null; // new RobPhysicsEngine(ph); // ph - init object + + for each (var child:Object3D in childarray) + addChild(child); + } + + /** + * Calling manually will update 3d objects that execute updates on their tick() methods. + * Uses the TickTraverser to traverse all tick methods in the scene. + * + * @see away3d.core.base.Object3D#tick() + * @see away3d.core.traverse.TickTraverser + */ + public function updateTime(time:int = -1):void + { + //set current time + if (time == -1) + time = getTimer(); + + //traverser scene ticks + tickTraverser.now = time; + traverse(tickTraverser); + + + if (physics != null) + physics.updateTime(time); + } + } +} From 126c00b79909bb49c09b836e3f99c0885ec390bc Mon Sep 17 00:00:00 2001 From: player-03 Date: Wed, 4 Jan 2012 23:43:20 -0500 Subject: [PATCH 2/2] Made the reference to the source object weak so that the object can be garbage collected. --- src/away3d/core/utils/ViewSourceObject.as | 25 +++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/away3d/core/utils/ViewSourceObject.as b/src/away3d/core/utils/ViewSourceObject.as index 19adf32..8e2d64e 100644 --- a/src/away3d/core/utils/ViewSourceObject.as +++ b/src/away3d/core/utils/ViewSourceObject.as @@ -8,6 +8,7 @@ package away3d.core.utils import away3d.core.render.*; import away3d.core.vos.*; import away3d.materials.*; + import flash.utils.Dictionary; import flash.geom.*; @@ -55,7 +56,7 @@ package away3d.core.utils private var _sv1y:Number; private var _sv2x:Number; private var _sv2y:Number; - + private var _startIndex:uint; private var _endIndex:uint; private var _faceVO:FaceVO; @@ -71,7 +72,8 @@ package away3d.core.utils private var _vertexIndex:uint; private var segmentCommands:Vector. = Vector.(["M", "L"]); private var faceCommands:Vector. = Vector.(["M", "L", "L"]); - + private var _sourceReference:Dictionary = new Dictionary(true); + private function getEndLoopIndex(i:uint):uint { var j:uint = i + 1; @@ -110,7 +112,7 @@ package away3d.core.utils return (ax - bx)*(ax - bx) + (ay - by)*(ay - by); } - public var source:Object3D; + //public var source:Object3D; public var screenVertices:Vector.; public var screenIndices:Vector.; public var screenUVTs:Vector.; @@ -121,7 +123,22 @@ package away3d.core.utils this.source = source; } - + public function get source():Object3D { + for (var s:Object in _sourceReference) { + return s as Object3D; + } + + return null; + } + + public function set source(newSource:Object3D):void { + for (var s:Object in _sourceReference) { + delete _sourceReference[s]; + } + + _sourceReference[newSource] = true; + } + public function contains(priIndex:uint, renderer:Renderer, x:Number, y:Number):Boolean { _startIndex = renderer.primitiveProperties[uint(priIndex*9)];