5 * <p>複数のクラスを混ぜることができるようにし、同じ関数やプロパティを複数のクラスに追加することができるようにするenchant.jsプラグイン.
6 * その上、コピーアンドペーストをしないために、製法({@link enchant.Class.MixingRecipe})で定義された関数やプロパティを
7 * 複数クラスに混ぜることもできるようにする.</p>
8 * <p>これで複数の継承ようなことができるということ</p>
10 * <li>enchant.js v0.6 以上.</li></ul></p>
11 * 詳細は{@link enchant.Class.mixClasses}, {@link enchant.Class.MixingRecipe.createFromClass},
12 * {@link enchant.Class.mixClassesFromRecipe}, {@link enchant.Class.MixingRecipe} や
13 * {@link enchant.Class.applyMixingRecipe} 参照してください.
16 * <p>A plugin for enchant.js which allows to mix
17 * arbitrary many {@link enchant.Class} classes together.
18 * It is also possible to add functions and properties defined
19 * as a recipe ({@link enchant.Class.MixingRecipe}) to arbitrary many classes to avoid copy and paste.</p>
20 * <p>Through this it is possible to achieve a behavior similar to multiple inheritance</p>
22 * <li>enchant.js v0.6 or later.</li></ul></p>
23 * See also {@link enchant.Class.mixClasses}, {@link enchant.Class.MixingRecipe.createFromClass},
24 * {@link enchant.Class.mixClassesFromRecipe}, {@link enchant.Class.MixingRecipe} and
25 * {@link enchant.Class.applyMixingRecipe} for an introduction.
28 * <p>Ein Plugin für enchant.js mit dem es möglich ist, beliebig viele
29 * {@link enchant.Class} Klassen zusammen zu mischen.
30 * Um Copy & Paste zu vermeiden, ist es auch möglich Funktionen und
31 * Properties, die in einem Rezept ({@link enchant.Class.MixingRecipe})
32 * definiert sind zu beliebig vielen Klassen hinzuzufügen.</p>
33 * <p>Durch dies ist es möglich ein Verhalten ähnlich zu multipler Vererbung zu erlangen.</p>
35 * <li>enchant.js v0.6 oder höher.</li></ul></p>
36 * Weiterführende Informationen: {@link enchant.Class.mixClasses}, {@link enchant.Class.MixingRecipe.createFromClass},
37 * {@link enchant.Class.mixClassesFromRecipe}, {@link enchant.Class.MixingRecipe} und
38 * {@link enchant.Class.applyMixingRecipe}
40 * @require enchant.js v0.6+
43 * @author Ubiquitous Entertainment Inc. (Kevin Kratzer)
46 if (enchant !== undefined) {
52 var decorateFunctionFactory = function(srcFunction, currentFunctionName) {
54 var firstResult, secondResult;
55 firstResult = this._mixing[currentFunctionName].apply(this,arguments);
56 secondResult = srcFunction.apply(this,arguments);
69 var voidFunction = function(){};
74 var multipleMixingCombinationFunctionFactory = function(oldFunc,newFunc, key) {
76 var firstResult = oldFunc.apply(this,arguments);
77 var mixingStore = this._mixing[key];
78 this._mixing[key] = voidFunction;
79 var secondResult = newFunc.apply(this,arguments);
80 this._mixing[key] = mixingStore;
93 var createFromPrototypeNonRecursive = function(decorate, override, properties, source, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList) {
94 for(var key in source) {
95 if(source.hasOwnProperty(key)) {
96 var descriptor = Object.getOwnPropertyDescriptor(source, key);
97 if(descriptor.value && typeof(descriptor.value) === 'function') {
98 if((!functionIgnoreNameList || functionIgnoreNameList.indexOf(key) === -1) && key !== 'constructor') {
99 if(!functionOverrideNameList || functionOverrideNameList.indexOf(key) === -1) {
100 decorate[key] = (decorateFunctionFactory(source[key],key));
102 override[key] = source[key];
106 if(!propertyIgnoreNameList || propertyIgnoreNameList.indexOf(key) === -1 && key !== '_mixing') {
107 properties[key] = descriptor;
117 var createFromPrototype = function(decorate,override,properties,source,onlyOwnProperties, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList) {
118 if(!onlyOwnProperties && source instanceof Object) {
119 createFromPrototype(decorate,override,properties,Object.getPrototypeOf(source),onlyOwnProperties, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList);
121 createFromPrototypeNonRecursive(decorate,override,properties,source, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList);
127 var getFunctionParams = function(methodString) {
128 if(typeof(methodString) !== 'string') {
129 methodString = methodString.toString();
131 return methodString.substring(methodString.indexOf('(')+1,methodString.indexOf(')')).replace(/\s+/,'').split(',');
134 /*Public Interface */
136 * @scope enchant.Class.MixingRecipe.prototype
138 enchant.Class.MixingRecipe = enchant.Class.create({
141 * 混ぜる中、どういう風に関数やプロパティが追加されるか設定する新たなMixingRecipeを生成する.
142 * クラスからMixingRecipeを生成することには {@link enchant.Class.MixingRecipe.createFromClass} を参照してください.
143 * @class 混ぜる先にどういう風に混ぜる処理を行うか設定する.
144 * このために、MixingRecipeはプロパティが三つある:
145 * <ul><li>decorateMethods(先の関数をラップする関数、デコレータ・パターンを参照してください)</li>
146 * <li>overrideMethods (先の関数をオーバーライドする関数)</li>
147 * <li>overrideProperties (先のプロパティをオーバーライドするプロパティ)</li></ul>
148 * <p>{@link enchant.Class.mixClasses}、 {@link enchant.Class.mixClassesFromRecipe} や {@link enchant.Class.applyMixingRecipe} を参照してください.</p>
149 * @param {Object} decorateMethods 先の関数をラップする関数、デコレータ・パターンを参照してください. 混ぜる結果のクラスでラップされた関数をアクセスするように_mixingというプロパティがある、例:this._mixing.myFunction.apply(this,arguments).<br>(キーと値のペア持っているオブジェクト、キーは関数名、値は関数).
150 * @param {Object} overrideMethods 先の関数をオーバーライドする関数.<br>(キーと値のペア持っているオブジェクト、キーは関数名、値は関数).
151 * @param {Object} properties 先のプロパティをオーバーライドするプロパティ.<br>(キーと値のペア持っているオブジェクト、キーは関数名、値はプロパティデスクリプタ).
152 * @property {Object} decorateMethods 先の関数をラップする関数、デコレータ・パターンを参照してください. 混ぜる結果のクラスでラップされた関数をアクセスするように_mixingというプロパティがある、例:this._mixing.myFunction.apply(this,arguments).<br>(キーと値のペア持っているオブジェクト、キーは関数名、値は関数).
153 * @property {Object} overrideMethods 先の関数をオーバーライドする関数.<br>(キーと値のペア持っているオブジェクト、キーは関数名、値は関数).
154 * @property {Object} overrideProperties 先のプロパティをオーバーライドするプロパティ.<br>(キーと値のペア持っているオブジェクト、キーは関数名、値はプロパティデスクリプタ).
157 * Creates a new MixingRecipe which is used for describing in which way functions and properties should be added during the mixing.
158 * To create a recipe from an existing class see {@link enchant.Class.MixingRecipe.createFromClass}
159 * @class This class is describing in which way the mixing will be performed on the target classes.
160 * For this purpose, MixingRecipe contains three properties:
161 * <ul><li>decorateMethods (methods which will be decorated in the target, see decorator pattern)</li>
162 * <li>overrideMethods (methods which will be overriden in the target)</li>
163 * <li>overrideProperties (properties which will be redefined in the target)</li></ul>
164 * <p>See also {@link enchant.Class.mixClasses}, {@link enchant.Class.mixClassesFromRecipe} and {@link enchant.Class.applyMixingRecipe}.</p>
165 * @param {Object} decorateMethods The methods which will be decorated in the target, see decorator pattern. To access methods which have been decorated in the class resulting from mixing the _mixing property can be used, e.g. this._mixing.myFunction.apply(this,arguments).<br>(Object containing key-value pairs, key := function name, value := function).
166 * @param {Object} overrideMethods The methods which will be overriden in the target.<br>(Object containing key-value pairs, key := function name, value := function).
167 * @param {Object} properties The properties which will be redefined in the target.<br>(Object containing key-value pairs, key := function name, value := property descriptor).
168 * @property {Object} decorateMethods The methods which will be decorated in the target, see decorator pattern. To access methods which have been decorated in the class resulting from mixing the _mixing property can be used, e.g. this._mixing.myFunction.apply(this,arguments).<br>(Object containing key-value pairs, key := function name, value := function).
169 * @property {Object} overrideMethods The methods which will be overriden in the target.<br>(Object containing key-value pairs, key := function name, value := function).
170 * @property {Object} overrideProperties The properties which will be redefined in the target.<br>(Object containing key-value pairs, key := function name, value := property descriptor).
173 * Erstellt ein neues MixingRecipe, welches beschreibt, auf welche Art und Weise Funktionen und Properties während des Mischens hinzugefügt werden.
174 * Um ein Rezept aus einer bereits existierend Klasse zu erstellen, ist auf {@link enchant.Class.MixingRecipe.createFromClass} zu verweisen.
175 * @class Diese Klasse beschreibt auf welche Art und Weise das mischen mit der Zielklasse durchgeführt wird.
176 * Für diesen Zweck enthählt ein MixingRecipe drei Properties:
177 * <ul><li>decorateMethods (Methoden, welche in der Zielklasse dekoriert werden, siehe Dekorierer Entwurfsmuster)</li>
178 * <li>overrideMethods (Methoden, welche in der Zielklasse überschrieben werden)</li>
179 * <li>overrideProperties (Properties, welche in der Zielklasse redefiniert werden)</li></ul>
180 * <p>Siehe auch: {@link enchant.Class.mixClasses}, {@link enchant.Class.mixClassesFromRecipe} und {@link enchant.Class.applyMixingRecipe}.</p>
181 * @param {Object} decorateMethods Die Methoden, welche in der Zielklasse dekoriert werden, siehe Dekorierer Entwurfsmuster. Auf die dekoriertie Methode kann in der durch das Mixen erstellten Klasse mit Hilfe des _mixing Property zugegriffen werden, z.B. this._mixing.myFunction.apply(this,arguments).<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Funktion)
182 * @param {Object} overrideMethods Die Methoden, welche in der Zielklasse überschrieben werden.<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Funktion).
183 * @param {Object} properties Die Properties, welche in der Zielklasse redefiniert werden.<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Propertydescriptor).
184 * @property {Object} decorateMethods Die Methoden, welche in der Zielklasse dekoriert werden, siehe Dekorierer Entwurfsmuster. Auf die dekoriertie Methode kann in der durch das Mixen erstellten Klasse mit Hilfe des _mixing Property zugegriffen werden, z.B. this._mixing.myFunction.apply(this,arguments).<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Funktion)
185 * @property {Object} overrideMethods Die Methoden, welche in der Zielklasse überschrieben werden.<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Funktion).
186 * @property {Object} overrideProperties Die Properties, welche in der Zielklasse redefiniert werden.<br>(Objekt welches Schlüssel-Wert Paare enthält, Schlüssel := Funktionsname, Wert := Propertydescriptor).
189 * var recipe = new enchant.Class.MixingRecipe({
190 * add : function(value) {
191 * this._myValue += 3*value;
192 * this._mixing.add.apply(this,arguments);
194 * mult : function(value) {
195 * this._myValue *= value*7;
196 * this._mixing.mult.apply(this,arguments);
199 * sub : function(value) {
200 * this._myValue -= 5*value;
205 * return 3*this._myPropertyValue;
207 * set : function(val) {
208 * this._myPropertyValue = val;
211 * var NewClass = enchant.Class.applyMixingRecipe(Class1,recipe);
215 initialize : function(decorateMethods, overrideMethods, properties) {
216 this.decorateMethods = decorateMethods;
217 this.overrideMethods = overrideMethods;
218 this.overrideProperties = properties;
224 * 引数のクルスの関数やプロパティから、MixingRecipeを生成する.
225 * デフォルト振舞はsourceClassの全ての関数やプロパティ、スーパークラスの関数やプロパティも使用して、
226 * 混ぜる先の関数をラップする(decorate).<br>_mixingプロパティでラップされた関数が自動的に、
227 * sourceClassと混ぜる先の関数を呼び出されるので、関係なくてもいい.
228 * <p>対応引数でデフォルト振舞を変更ができる.</p>
230 * @param {Function<constructor enchant.Classで生成された関数>} sourceClass このクラスから、MixingRecipeが生成される.
231 * @param [boolean] onlyOwnProperties Trueの場合、スーパークラスの関数やプロパティが無視されない.
232 * @param [Array<String>] functionOverrideNameList 混ぜるときオーバーライドされる関数名を持っている配列.
233 * @param [Array<String>] functionIgnoreNameList MixingRecipeを生成するとき無視される関数名を持っている配列.
234 * @param [Array<String>] propertyIgnoreNameList MixingRecipeを生成するとき無視されるプロパティ名を持っている配列.
235 * @returns {enchant.Class.MixingRecipe} クラス定義から生成されたMixingRecipe.
238 * Takes the methods and properties of the given class to create a new MixingRecipe.
239 * The default behavior is to take all functions and properties of the given class
240 * including functions and properties defined in super classes, whereas functions
241 * are set to decorate the mixing target.<br>Methods which are decorated will automatically
242 * call the soureClass method and the mixing target method (using the _mixing property) -
243 * so there is no need to handle this yourself.
244 * <p>To change the default behavior set the corresponding arguments of the function.</p>
246 * @param {Function<constructor function created with enchant.Class>} sourceClass The class which will be used to create the recipe.
247 * @param [boolean] onlyOwnProperties If set to true, the functions and properties of the super classes will be ignored.
248 * @param [Array<String>] functionOverrideNameList An array containing names of functions which should be set to override functions in the target during mixing.
249 * @param [Array<String>] functionIgnoreNameList An array containing names of functions which should be ignored when creating the recipe.
250 * @param [Array<String>] propertyIgnoreNameList An array containing names of properties which should be ignored when creating the recipe.
251 * @returns {enchant.Class.MixingRecipe} The MixingRecipe created from the definition of the sourceClass.
254 * Nimmt die Methoden und Properties der übergebenen Klasse um ein neues MixingRecipe zu erstellen.
255 * Das Standardverhalten dabei ist, alle Funktionen und Properties der übergebenen Klasse,
256 * einschließlich der Funktionen und Properties in den Superklassen zu nehmen und diese
257 * in der Zielklasse beim mixen zu dekorieren.<br>Methoden welche dekoriert werden, rufen
258 * automatisch die Methoden der sourceClass und der Zielklasse des Mixens, mit Hilfe des
259 * _mixing Properties, auf. Daher muss dies nicht selbst berücksichtigt werden.
260 * <p>Durch die entsprechenden Argumente der Funktion kann das Standardverhalten zu verändert werden.</p>
262 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} sourceClass Die Klasse aus der das MixingRecipe erstellt wird.
263 * @param [boolean] onlyOwnProperties Wenn dieses Argument true ist, werden Funktionen und Properties der Superklassen ignoriert.
264 * @param [Array<String>] functionOverrideNameList Ein Array welches Namen von Funktionen enthält, welche während des Mixens überschrieben werden sollen.
265 * @param [Array<String>] functionIgnoreNameList Ein Array welches Namen von Funktionen enthält, welche bei der MixingRecipe erstellung ignoriert werden sollen.
266 * @param [Array<String>] propertyIgnoreNameList Ein Array welches Namen von Properties enthält, welche bei der MixingRecipe erstellung ignoriert werden sollen.
267 * @returns {enchant.Class.MixingRecipe} Das MixingRecipe, welches aus der Definition der sourceClass erstellt wurde.
270 * var recipe = enchant.Class.MixingRecipe.createFromClass(Class2, true,
271 * ['overrideFunction1','overrideFunction2'],
272 * ['ignoreFunction1','ignoreFunction2'],
273 * ['ignoreProperty1','ignorePropterty2']);
274 * recipe.overrideMethods['additionalFunction'] = new function() {
275 * console.log('Hello, World');
277 * recipe.overrideProperties['newProperty'] = {
279 * return this._newProperty;
281 * set : function(val) {
282 * this._newProperty = val;
285 * var NewClass = enchant.Class.mixClassesFromRecipe(Class1,Class2,recipe);
289 enchant.Class.MixingRecipe.createFromClass = function(sourceClass, onlyOwnProperties, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList) {
294 var source = sourceClass.prototype;
295 createFromPrototype(decorate,override,properties,source,onlyOwnProperties, functionOverrideNameList, functionIgnoreNameList, propertyIgnoreNameList);
296 return new enchant.Class.MixingRecipe(decorate,override,properties);
301 * 設定されたMixingRecipeを使用して、firstClassというクラスに実行して、この結果を戻る。設定されたMixingRecipeはsecondClassというクラスに関係があったほうがいい.
302 * どちらでもクラスの初期化関数を呼び出すデフォルト初期化関数が追加される.
303 * このデフォルト初期か関数の書式は:<br>
304 * ([firstClass コンストラクタ 引数 1],...,[firstClass コンストラクタ 引数 n],[secondClass コンストラクタ 引数 1],...[secondClass コンストラクタ 引数 n])</p>
305 * <p>どちらでもクラスが変更されない</p>{@link enchant.Class.MixingRecipe} を参照してください.
306 * @param {Function<constructor enchant.Classで生成された関数>} firstClass MixingRecipeを実行されるクラス.
307 * @param {Function<constructor enchant.Classで生成された関数>} sourceClass MixingRecipに関係があるクラス。デフォルト初期化関数に使用される。
308 * @param {enchant.Class.MixingRecipe} recipe firstClassに実行される製法。 secondClassに関係があったほうがいい.
309 * @param [Function] initializeMethod 設定すると、新しいクラスの初期化にデフォルト初期化関数が使用されないけど、この関数が使用される.
310 * @returns {Function<constructor enchant.Classで生成された関数>} 製法でどちらでもクラスを混ぜた結果クラス.
313 * Uses the given MixingRecipe, applies it to the first class and returns the result - the MixingRecipe should correspond to the secondClass.
314 * A default initialize method will be added which will call the initialize functions of both classes.
315 * The signature for the default initialize method is:<br>
316 * ([firstClass constructor arg 1],...,[firstClass constructor arg n],[secondClass constructor arg1],...[secondClass constructor arg n])
317 * <p>Both classes will not be modified.</p> See also: {@link enchant.Class.MixingRecipe}
319 * @param {Function<constructor function created with enchant.Class>} firstClass The class to which the recipe will be applied.
320 * @param {Function<constructor function created with enchant.Class>} secondClass The class which is related to the MixingRecipe, used for the default initialize function.
321 * @param {enchant.Class.MixingRecipe} recipe The recipe which is applied to the first class - should correspond to the secondClass.
322 * @param [Function] initializeMethod If provided, this function will be used to initialize the resulting class instead of the default initialize method.
323 * @returns {Function<constructor function created with enchant.Class>} initializeMethod The class which is the result of mixing both classes using the recipe.
326 * Nutzt das gegebene MixingRecipe, wendet es auf die "firstClass" Klasse an und liefert das Ergebnis daraus zurück - das MixingRecipe sollte der secondClass entsprechen.
327 * Eine Standard-Initialisierungsmethode wird hinzugefügt, welche die Initialisierungsmethode beider Klassen aufruft.
328 * Die Signatur für diese Standard-Initialisierungsmethode ist:<br>
329 * ([firstClass Konstruktor Arg 1],...,[firstClass Konstruktor Arg n],[secondClass Konstruktor Arg 1],...[secondClass Konstruktor Arg n])</p>
330 * <p>Beide Klassen werden nicht verändert.</p> Siehe auch: {@link enchant.Class.MixingRecipe}
331 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} firstClass Die Klasse auf die das MixingRecipe angewendet wird.
332 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} secondClass Die Klasse die dem MixingRecipe entpsricht, wird für die Standard-Initialisierungsmethode genutzt.
333 * @param {enchant.Class.MixingRecipe} recipe Das MixingRecipe, welches auf die firstClass Klasse angewendet wird - sollte der secondClass entsprechen.
334 * @param [Function] initializeMethod Falls gegeben, wird diese Methode, anstelle der Standard-Initialisierungsmethode, zum Initialisieren der resultierenden Klasse verwendet.
335 * @returns {Function<constructor Funktion die mit enchant.Class erstellt wurde>} Die Klasse, welche das Ergebnis des Mixens beider Klassen mit Hilfe des MixingRecipe darstellt.
338 * var MapGroup = enchant.Class.mixClasses(Map, Group,true);
339 * var map = new MapGroup(16, 16);
340 * var SpriteLabel = enchant.Class.mixClasses(Sprite, Label,true);
341 * var kumaLabel = new SpriteLabel(32,32,'Kuma');
344 enchant.Class.mixClassesFromRecipe = function(firstClass, secondClass, recipe, initializeMethod) {
345 var result = enchant.Class.applyMixingRecipe(firstClass,recipe);
346 var paramLength = getFunctionParams(firstClass.prototype.initialize).length;
347 if(typeof(initializeMethod) !== 'function') {
348 initializeMethod = function() {
349 var args = Array.prototype.slice.call(arguments);
350 secondClass.prototype.initialize.apply(this,args.slice(paramLength));
351 firstClass.prototype.initialize.apply(this,args.slice(0,paramLength));
354 result.prototype.initialize = initializeMethod;
361 * secondClassというクルスからMixingRecipeを生成して、firstClassというクラスに実行して、この結果を戻る.
362 * デフォルト振舞はsecondClassの全ての関数やプロパティ、スーパークラスの関数やプロパティも使用して、
363 * 混ぜる先の関数をラップする(decorate).<br>_mixingプロパティでラップされた関数が自動的に、
364 * sourceClassと混ぜる先の関数を呼び出されるので、関係なくてもいい.
365 * <p>その上、どちらでもクラスの初期化関数を呼び出すデフォルト初期化関数が追加される.このデフォルト初期か関数の書式は:<br>
366 * ([firstClass コンストラクタ 引数 1],...,[firstClass コンストラクタ 引数 n],[secondClass コンストラクタ 引数 1],...[secondClass コンストラクタ 引数 n])</p>
367 * <p>どちらでもクラスが変更されない</p>{@link enchant.Class.MixingRecipe} を参照してください.
368 * @param {Function<constructor enchant.Classで生成された関数>} firstClass MixingRecipeを実行されるクラス.
369 * @param {Function<constructor enchant.Classで生成された関数>} sourceClass このクラスから、MixingRecipeが生成される.
370 * @param [boolean] onlyOwnProperties Trueの場合、スーパークラスの関数やプロパティが無視されない.
371 * @param [Function] initializeMethod 設定すると、新しいクラスの初期化にデフォルト初期化関数が使用されないけど、この関数が使用される.
372 * @returns {Function<constructor enchant.Classで生成された関数>} どちらでもクラスを混ぜた結果クラス.
375 * Creates an MixingRecipe out of the second class, applies it to the first class and returns the result.
376 * The default behavior is to take all functions and properties of the second class,
377 * including functions and properties defined in its super classes, whereas functions
378 * are set to decorate the mixing target.<br>Methods which are decorated will automatically
379 * call the soureClass method and the mixing target method (using the _mixing property) -
380 * so there is no need to handle this yourself.
381 * <p>Furthermore, a default initialize method will be added which will
382 * call the initialize functions of both classes. The signature for the default initialize method is:<br>
383 * ([firstClass constructor arg 1],...,[firstClass constructor arg n],[secondClass constructor arg 1],...[secondClass constructor arg n])</p>
384 * <p>Both classes will not be modified.</p> See also: {@link enchant.Class.MixingRecipe}
386 * @param {Function<constructor function created with enchant.Class>} firstClass The class to which the recipe will be applied.
387 * @param {Function<constructor function created with enchant.Class>} secondClass The class from which the recipe will be created
388 * @param [boolean] useOnlyOwnPropertiesForSecondClass If set to true, the functions and properties of the super classes will be ignored during the recipe creation of the secondClass.
389 * @param [Function] initializeMethod If provided, this function will be used to initialize the resulting class instead of the default initialize method.
390 * @returns {Function<constructor function created with enchant.Class>} The class which is the result of mixing both classes.
393 * Erstellt ein MixingRecipe aus der "secondClass" Klasse, wendet dieses auf die "firstClass" Klasse an und liefert das Ergebnis daraus zurück.
394 * Das Standardverhalten dabei ist, alle Funktionen und Properties der "secondClass" Klasse,
395 * einschließlich der Funktionen und Properties in deren Superklassen zu nehmen und diese
396 * in der Zielklasse beim mixen zu dekorieren.<br>Methoden welche dekoriert werden, rufen
397 * automatisch die Methoden der sourceClass und der Zielklasse des Mixens, mit Hilfe des
398 * _mixing Properties, auf. Daher muss dies nicht selbst berücksichtigt werden.
399 * <p>Des Weiteren wird eine Standard-Initialisierungsmethode, welche die Initialisierungsmethode beider Klassen aufruft, hinzugefügt.
400 * Die Signatur für diese Standard-Initialisierungsmethode ist:<br>
401 * ([firstClass Konstruktor Arg 1],...,[firstClass Konstruktor Arg n],[secondClass Konstruktor Arg 1],...[secondClass Konstruktor Arg n])</p>
402 * <p>Beide Klassen werden nicht verändert.</p> Siehe auch: {@link enchant.Class.MixingRecipe}
404 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} firstClass Die Klasse auf die das MixingRecipe angewendet wird.
405 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} secondClass Die Klasse aus der das MixingRecipe erstellt wird.
406 * @param [boolean] onlyOwnProperties Wenn dieses Argument true ist, werden Funktionen und Properties der Superklassen der "secondClass" Klasse ignoriert.
407 * @param [Function] initializeMethod Falls gegeben, wird diese Methode, anstelle der Standard-Initialisierungsmethode, zum Initialisieren der resultierenden Klasse verwendet.
408 * @returns {Function<constructor Funktion die mit enchant.Class erstellt wurde>} Die Klasse, welche das Ergebnis des Mixens beider Klassen darstellt.
411 * var MapGroup = enchant.Class.mixClasses(Map, Group,true);
412 * var map = new MapGroup(16, 16);
413 * var SpriteLabel = enchant.Class.mixClasses(Sprite, Label,true);
414 * var kumaLabel = new SpriteLabel(32,32,'Kuma');
417 enchant.Class.mixClasses = function(firstClass, secondClass, useOnlyOwnPropertiesForSecondClass, initializeMethod) {
418 return enchant.Class.mixClassesFromRecipe(firstClass,secondClass,enchant.Class.MixingRecipe.createFromClass(secondClass, useOnlyOwnPropertiesForSecondClass, [], ['initialize'], []),initializeMethod);
423 * 設定されたMixingRecipeを先クラスに実行して、新たなクラスを生成してこのクラスを戻る.
424 * 先クラスが変更されない.<br>{@link enchant.Class.MixingRecipe} を参照してください.
426 * @param {Function<constructor enchant.Classで生成された関数>} target MixingRecipeを実行される先クラス.
427 * @param {enchant.Class.MixingRecipe} source 先に新しい機能を追加するMixingRecipe.
428 * @returns {Function<constructor enchant.Classで生成された関数>} sourceという製法とtargetというクラスを混ぜた結果クラス.
431 * Applies the defined MixingRecipe to the target class creating a new class definition which is then returned.
432 * The target class is not modified directly.<br>See also: {@link enchant.Class.MixingRecipe}.
434 * @param {Function<constructor function created with enchant.Class>} target The class to which the recipe will be applied.
435 * @param {enchant.Class.MixingRecipe} source The MixingRecipe which is used to add new functionality to the target.
436 * @returns {Function<constructor function created with enchant.Class>} The class which is the result of mixing the target class with the source recipe.
439 * Wendet das übergebene MixingRecipe auf die Zielklasse an, erstellt eine neue Klassendefinition und liefert diese als Rückgabewert zurück.
440 * Die Zielklasse wird nicht modifiziert.<br>Siehe auch: {@link enchant.Class.MixingRecipe}.
442 * @param {Function<constructor Funktion die mit enchant.Class erstellt wurde>} target Die Klasse auf die das MixingRecipe angewendet wird.
443 * @param {enchant.Class.MixingRecipe} source Das MixingRecipe, welches genutzt wird um der Zielklasse neue Funktionalität zu verleihen.
444 * @returns {Function<constructor Funktion die mit enchant.Class erstellt wurde>} Die Klasse, welche das Ergebnis des Mixens der Zielklasse (target) mit dem Rezept (source) darstellt.
447 * var recipe = new enchant.Class.MixingRecipe({
448 * // ... see enchant.Class.MixingRecipe
450 * // ... see enchant.Class.MixingRecipe
452 * // ... see enchant.Class.MixingRecipe
454 * var NewClass = applyMixingRecipe(Class1,recipe);
457 enchant.Class.applyMixingRecipe = function(target, source) {
458 var result = enchant.Class.create(target,{});
459 target = result.prototype;
460 for(var recipeKey in source) {
461 if(source.hasOwnProperty(recipeKey)) {
462 var currentSource = source[recipeKey];
463 if(recipeKey === 'overrideMethods') {
464 for(var methodKey in currentSource) {
465 if(currentSource.hasOwnProperty(methodKey)) {
466 target[methodKey] = currentSource[methodKey];
467 if(target._mixing && target._mixing[methodKey]) {
468 target._mixing[methodKey] = voidFunction;
472 } else if(recipeKey === 'overrideProperties') {
473 for(var propertyKey in currentSource) {
474 if(currentSource.hasOwnProperty(propertyKey)) {
475 Object.defineProperty(target,propertyKey,currentSource[propertyKey]);
478 } else if(recipeKey === 'decorateMethods') {
479 if(!target._mixing) {
482 for(var key in currentSource) {
483 if(currentSource.hasOwnProperty(key)) {
484 var targetHolder = target;
486 while(targetHolder instanceof Object && !targetHolder[key]) {
487 targetHolder = Object.getPrototypeOf(targetHolder);
490 if(target._mixing[key]) {
491 var newFunc = targetHolder[key];
492 target._mixing[key] = (multipleMixingCombinationFunctionFactory(target._mixing[key],newFunc,key));
494 target._mixing[key] = targetHolder[key];
495 if(!target._mixing[key]) {
496 target._mixing[key] = voidFunction;
499 target[key] = currentSource[key];