1 /****************************************************************************
  2  Copyright (c) 2011-2012 cocos2d-x.org
  3  Copyright (c) 2013-2014 Chukong Technologies Inc.
  4 
  5  http://www.cocos2d-x.org
  6 
  7  Permission is hereby granted, free of charge, to any person obtaining a copy
  8  of this software and associated documentation files (the "Software"), to deal
  9  in the Software without restriction, including without limitation the rights
 10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  copies of the Software, and to permit persons to whom the Software is
 12  furnished to do so, subject to the following conditions:
 13 
 14  The above copyright notice and this permission notice shall be included in
 15  all copies or substantial portions of the Software.
 16 
 17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 23  THE SOFTWARE.
 24  ****************************************************************************/
 25 
 26 /**
 27  * The trigger manager of Cocostudio
 28  * @class
 29  * @name ccs.triggerManager
 30  */
 31 ccs.triggerManager = /** @lends ccs.triggerManager# */{
 32     _eventTriggers: {},
 33     _triggerObjs: {},
 34     _movementDispatches: [],
 35 
 36     /**
 37      * Parses the triggers.
 38      * @param {Array} triggers
 39      */
 40     parse: function (triggers) {
 41         for (var i = 0; i < triggers.length; ++i) {
 42             var subDict = triggers[i];
 43             var triggerObj = new ccs.TriggerObj();
 44             triggerObj.serialize(subDict);
 45             var events = triggerObj.getEvents();
 46             for (var j = 0; j < events.length; j++) {
 47                 var event = events[j];
 48                 this.add(event, triggerObj);
 49             }
 50             this._triggerObjs[triggerObj.getId()] = triggerObj;
 51         }
 52     },
 53 
 54     /**
 55      * Returns the event triggers by event id.
 56      * @param {Number} event
 57      * @returns {Array}
 58      */
 59     get: function (event) {
 60         return this._eventTriggers[event];
 61     },
 62 
 63     /**
 64      * Returns the trigger object by id
 65      * @param {Number} id
 66      * @returns {ccs.TriggerObj}
 67      */
 68     getTriggerObj: function (id) {
 69         return this._triggerObjs[id];
 70     },
 71 
 72     /**
 73      * Adds event and trigger object to trigger manager.
 74      * @param event
 75      * @param triggerObj
 76      */
 77     add: function (event, triggerObj) {
 78         var eventTriggers = this._eventTriggers[event];
 79         if (!eventTriggers)
 80             eventTriggers = [];
 81         if (eventTriggers.indexOf(triggerObj) === -1) {
 82             eventTriggers.push(triggerObj);
 83             this._eventTriggers[event] = eventTriggers;
 84         }
 85     },
 86 
 87     /**
 88      * Removes all event triggers from manager.
 89      */
 90     removeAll: function () {
 91         for (var key in this._eventTriggers) {
 92             var triObjArr = this._eventTriggers[key];
 93             for (var j = 0; j < triObjArr.length; j++) {
 94                 var obj = triObjArr[j];
 95                 obj.removeAll();
 96             }
 97         }
 98         this._eventTriggers = {};
 99     },
100 
101     /**
102      * Removes event object from trigger manager.
103      * @param {*} event
104      * @param {*} Obj
105      * @returns {Boolean}
106      */
107     remove: function (event, Obj) {
108         if (Obj)
109             return this._removeObj(event, Obj);
110 
111         var bRet = false;
112         do {
113             var triObjects = this._eventTriggers[event];
114             if (!triObjects)
115                 break;
116             for (var i = 0; i < triObjects.length; i++) {
117                 var triObject = triObjects[i];
118                 if (triObject)
119                     triObject.removeAll();
120             }
121             delete this._eventTriggers[event];
122             bRet = true;
123         } while (0);
124         return bRet;
125     },
126 
127     _removeObj: function (event, Obj) {
128         var bRet = false;
129         do
130         {
131             var triObjects = this._eventTriggers[event];
132             if (!triObjects) break;
133             for (var i = 0; i < triObjects.length; i++) {
134                 var triObject = triObjects[i];
135                 if (triObject && triObject == Obj) {
136                     triObject.removeAll();
137                     triObjects.splice(i, 1);
138                     break;
139                 }
140             }
141             bRet = true;
142         } while (0);
143         return bRet;
144     },
145 
146     /**
147      * Removes trigger object from manager
148      * @param {Number} id
149      * @returns {boolean}
150      */
151     removeTriggerObj: function (id) {
152         var obj = this.getTriggerObj(id);
153         if (!obj)
154             return false;
155         var events = obj.getEvents();
156         for (var i = 0; i < events.length; i++) {
157             var event = events[i];
158             this.remove(event, obj);
159         }
160         return true;
161     },
162 
163     /**
164      * Returns the event triggers whether is empty.
165      * @returns {boolean}
166      */
167     isEmpty: function () {
168         return !this._eventTriggers || this._eventTriggers.length <= 0;
169     },
170 
171     /**
172      * Adds an armature movement callback to manager.
173      * @param {ccs.Armature} armature
174      * @param {function} callFunc
175      * @param {Object} target
176      */
177     addArmatureMovementCallBack: function (armature, callFunc, target) {
178         if (armature == null || target == null || callFunc == null)
179             return;
180         var locAmd, hasADD = false;
181         for (var i = 0; i < this._movementDispatches.length; i++) {
182             locAmd = this._movementDispatches[i];
183             if (locAmd && locAmd[0] === armature) {
184                 locAmd.addAnimationEventCallBack(callFunc, target);
185                 hasADD = true;
186             }
187         }
188         if (!hasADD) {
189             var newAmd = new ccs.ArmatureMovementDispatcher();
190             armature.getAnimation().setMovementEventCallFunc(newAmd.animationEvent, newAmd);
191             newAmd.addAnimationEventCallBack(callFunc, target);
192             this._movementDispatches.push([armature, newAmd]);
193         }
194     },
195 
196     /**
197      * Removes armature movement callback from manager.
198      * @param {ccs.Armature} armature
199      * @param {Object} target
200      * @param {function} callFunc
201      */
202     removeArmatureMovementCallBack: function (armature, target, callFunc) {
203         if (armature == null || target == null || callFunc == null)
204             return;
205         var locAmd;
206         for (var i = 0; i < this._movementDispatches.length; i++) {
207             locAmd = this._movementDispatches[i];
208             if (locAmd && locAmd[0] === armature)
209                 locAmd.removeAnimationEventCallBack(callFunc, target);
210         }
211     },
212 
213     /**
214      * Removes an armature's all movement callbacks.
215      * @param {ccs.Armature} armature
216      */
217     removeArmatureAllMovementCallBack: function (armature) {
218         if (armature == null)
219             return;
220         var locAmd;
221         for (var i = 0; i < this._movementDispatches.length; i++) {
222             locAmd = this._movementDispatches[i];
223             if (locAmd && locAmd[0] === armature) {
224                 this._movementDispatches.splice(i, 1);
225                 break;
226             }
227         }
228     },
229 
230     /**
231      * Removes all armature movement callbacks from ccs.triggerManager.
232      */
233     removeAllArmatureMovementCallBack: function () {
234         this._movementDispatches.length = 0;
235     },
236 
237     /**
238      * Returns the version of ccs.triggerManager
239      * @returns {string}
240      */
241 	version: function () {
242 		return "1.2.0.0";
243 	}
244 };
245 
246 /**
247  * The armature movement dispatcher for trigger manager.
248  * @class
249  * @extends ccs.Class
250  */
251 ccs.ArmatureMovementDispatcher = ccs.Class.extend(/** @lends ccs.ArmatureMovementDispatcher# */{
252     _mapEventAnimation: null,
253 
254     /**
255      * Constructor of ArmatureMovementDispatcher.
256      */
257     ctor: function () {
258         this._mapEventAnimation = [];
259     },
260 
261     /**
262      * Calls armature movement events.
263      * @param {ccs.Armature} armature
264      * @param {Number} movementType
265      * @param {String} movementID
266      */
267     animationEvent: function (armature, movementType, movementID) {
268         var locEventAni, locTarget, locFunc;
269         for (var i = 0; i < this._mapEventAnimation.length; i++) {
270             locEventAni = this._mapEventAnimation[i];
271             locTarget = locEventAni[0];
272             locFunc = locEventAni[1];
273             if (locFunc)
274                 locFunc.call(locTarget, armature, movementType, movementID);
275         }
276     },
277 
278     /**
279      * Adds animation event callback to event animation list
280      * @param {function} callFunc
281      * @param {Object|null} [target]
282      */
283     addAnimationEventCallBack: function (callFunc, target) {
284         this._mapEventAnimation.push([target, callFunc]);
285     },
286 
287     /**
288      * Removes animation event callback from trigger manager.
289      * @param {function} callFunc
290      * @param {Object|null} [target]
291      */
292     removeAnimationEventCallBack: function (callFunc, target) {
293         var locEventAni;
294         for (var i = 0; i < this._mapEventAnimation.length; i++) {
295             locEventAni = this._mapEventAnimation[i];
296             if (locEventAni[0] === target) {
297                 this._mapEventAnimation.splice(i, 1);
298             }
299         }
300     }
301 });