From 93d31fddbe4186dfb00b9a4df77c89b5c1b3b98e Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 17 Nov 2012 20:03:29 +0100 Subject: [PATCH 01/34] minor sprintf doc formatting --- src/de/polygonal/core/fmt/Sprintf.hx | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/de/polygonal/core/fmt/Sprintf.hx b/src/de/polygonal/core/fmt/Sprintf.hx index bc35e8e..a98d338 100644 --- a/src/de/polygonal/core/fmt/Sprintf.hx +++ b/src/de/polygonal/core/fmt/Sprintf.hx @@ -52,63 +52,54 @@ using haxe.Int32; *

If there is more than one argument (or if the only argument passed is not an array), Sprintf will use the arguments as is.

*

  * Sprintf.format("This is %s", "acceptable");
- * Sprintf.format("This is also %s", ["acceptable"]);
- * 

+ * Sprintf.format("This is also %s", ["acceptable"]);

* *

Numbered Parameters

*

Arguments can now be accessed by number via the following format: `%[argnumber$][flags][width][.precision][length]specifier`

*

Note: The number 1 refers to the first argument, not 0

*

- * Sprintf.format("%s is %d years old, and his name is %1$s", ["Joe", 32]);
- * 

+ * Sprintf.format("%s is %d years old, and his name is %1$s", ["Joe", 32]);

* *

Named Parameters

*

Arguments can now be specified as named properties of an object using the following format: `%(name)`. Named arguments will always refer to the first parameter.

*

Named Parameters can even be used in conjunction with other argument types:

*

- * Sprintf.format("%(name) is %(age), and wants to be a %2$s", {name:"Joe", age:32}, "Programmer");
- * 

+ * Sprintf.format("%(name) is %(age), and wants to be a %2$s", {name:"Joe", age:32}, "Programmer");

* *

Compile-Time Checks

*

If the format string is inline, several checks can be done at compile time, and they can issue an error or warning during the compile.

*

Format String Verification

*

An incorrect format string will throw an error:

*

- * Sprintf.format("%m", 3); // Compile-time error: invalid format specifier
- * 

+ * Sprintf.format("%m", 3); // Compile-time error: invalid format specifier

* *

Not Enough Arguments

*

Compilation will fail if there are not enough arguments passed for the number of specifiers given

*

- * Sprintf.format("%s %s %s", "bob", "joe"); // Compile-time error: Not enough arguments
- * 

+ * Sprintf.format("%s %s %s", "bob", "joe"); // Compile-time error: Not enough arguments

* *

Width and Precision

*

Widths and precisions are checked at compile time when possible

*

  * Sprintf.format("Age/3 = %.*f", 10.1, 2); // Compile-time error: precision must be an integer
- * Sprintf.format("Age/3 = %*f", 10.1, 4); // Compile-time error: width must be an integer
- * 

+ * Sprintf.format("Age/3 = %*f", 10.1, 4); // Compile-time error: width must be an integer

* *

Number Types

*

The value's type is checked whenever possible

*

  * Sprintf.format("%f", "5"); // Compile-time error: the value must be a number
- * Sprintf.format("%d", 4.1); // Complile-time error: the value must be an integer
- * 

+ * Sprintf.format("%d", 4.1); // Complile-time error: the value must be an integer

* *

Flag Mis-matches (Warning)

*

A compiler warning will be issued for flag combinations that don't make sense

*

  * Sprintf.format("% +f", 3.1);
- * // Compile-time warning: ` ' flag ignored with '+' flag in printf format
- * 

+ * // Compile-time warning: ` ' flag ignored with '+' flag in printf format

* *

Unused Arguments (Warning)

*

If compiled with the verbose flag, a compiler warning will be issued for arguments that are left unused

*

- * Sprintf.format("%s", "first", "second"); // Compile-time warning: Unused parameters
- * 

+ * Sprintf.format("%s", "first", "second"); // Compile-time warning: Unused parameters

*/ class Sprintf { From 54aa596c0d5e61773f9c29b3dfa1bf58d1bb6c60 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 17 Nov 2012 20:03:42 +0100 Subject: [PATCH 02/34] add PropertyFile.parse() --- src/de/polygonal/core/util/PropertyFile.hx | 207 +++++++++++---------- 1 file changed, 105 insertions(+), 102 deletions(-) diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index 8891ba4..fdc32d7 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -37,12 +37,6 @@ import haxe.macro.Context; import haxe.macro.Expr; #end -typedef Pair = -{ - var key:String; - var val:Dynamic; -} - class PropertyFile { #if macro @@ -54,10 +48,105 @@ class PropertyFile var fields = Context.getBuildFields(); var assign = new Array(); - try + var access = [APublic]; + if (staticFields) + { + access.push(AStatic); + access.push(AInline); + } + + var map = parse(neko.io.File.getContent(url)); + for (key in map.keys()) { - var s = neko.io.File.getContent(url); + var val = map.get(key); + var c = null, n:String, p = []; + if (val.indexOf(',') != -1) + { + var arrExpr = []; + var arrType; + var tmp:Array = val.split(','); + + if (tmp[0].indexOf('.') != -1) + { + for (i in tmp) arrExpr.push({expr: EConst(CFloat(Std.string(Std.parseFloat(i)))), pos: pos}); + arrType = 'Float'; + } + else + { + var int = Std.parseInt(tmp[0]); + if (int == null) + { + for (i in tmp) arrExpr.push({expr: EConst(CString(i)), pos: pos}); + arrType = 'String'; + } + else + { + for (i in tmp) arrExpr.push({expr: EConst(CInt(Std.string(Std.parseInt(i)))), pos: pos}); + arrType = 'Int'; + } + } + + n = 'Array'; + c = EArrayDecl(arrExpr); + p = [TPType(TPath({sub: null, name: arrType, pack: [], params: []}))]; + } + else + if (val.indexOf('.') != -1) + { + if (Math.isNaN(Std.parseFloat(val))) + { + c = EConst(CString(val)); + n = 'String'; + } + else + { + c = EConst(CFloat(val)); + n = 'Float'; + } + } + else + if (val == 'true' || val == 'false') + { + c = EConst(CIdent(val)); + n = 'Bool'; + } + else + { + var int = Std.parseInt(val); + if (int == null) + { + c = EConst(CString(val)); + n = 'String'; + } + else + { + c = EConst(CInt(val)); + n = 'Int'; + } + } + + if (c == null) + Context.error('invalid field type', Context.currentPos()); + + if (staticFields) + fields.push({name: key, doc: null, meta: [], access: access, kind: FVar(TPath({pack: [], name: n, params: p, sub: null}), {expr: c, pos: pos}), pos: pos}); + else + { + fields.push({name: key, doc: null, meta: [], access: access, kind: FVar(TPath({pack: [], name: n, params: p, sub: null})), pos: pos}); + assign.push({expr: EBinop(Binop.OpAssign, {expr: EConst(CIdent(key)), pos: pos}, {expr: c, pos: pos}), pos:pos}); + } + } + + if (!staticFields) fields.push({name: 'new', doc: null, meta: [], access: [APublic], kind: FFun({args: [], ret: null, expr: {expr: EBlock(assign), pos:pos}, params: []}), pos: pos}); + return fields; + } + #end + + public static function parse(s:String):Hash + { + try + { var a = []; var b = ''; var i = 0; @@ -104,111 +193,25 @@ class PropertyFile b += s.charAt(i++); } - if (b != '') - a.push(b); - - var access = [APublic]; - if (staticFields) - { - access.push(AStatic); - access.push(AInline); - } + if (b != '') a.push(b); + var pairs = new Hash(); var next = 0; for (i in 0...a.length >> 1) { - var fieldName = a[next++]; - var fieldValue = a[next++]; - - var c = null, n:String, p = []; - if (fieldValue.indexOf(',') != -1) - { - var arrExpr = []; - var arrType; - var tmp = fieldValue.split(','); - - if (tmp[0].indexOf('.') != -1) - { - for (i in tmp) arrExpr.push({expr: EConst(CFloat(Std.string(Std.parseFloat(i)))), pos: pos}); - arrType = 'Float'; - } - else - { - var int = Std.parseInt(tmp[0]); - if (int == null) - { - for (i in tmp) arrExpr.push({expr: EConst(CString(i)), pos: pos}); - arrType = 'String'; - } - else - { - for (i in tmp) arrExpr.push({expr: EConst(CInt(Std.string(Std.parseInt(i)))), pos: pos}); - arrType = 'Int'; - } - } - - n = 'Array'; - c = EArrayDecl(arrExpr); - p = [TPType(TPath({sub: null, name: arrType, pack: [], params: []}))]; - } - else - if (fieldValue.indexOf('.') != -1) - { - if (Math.isNaN(Std.parseFloat(fieldValue))) - { - c = EConst(CString(fieldValue)); - n = 'String'; - } - else - { - c = EConst(CFloat(fieldValue)); - n = 'Float'; - } - } - else - if (fieldValue == 'true' || fieldValue == 'false') - { - c = EConst(CIdent(fieldValue)); - n = 'Bool'; - } - else - { - var int = Std.parseInt(fieldValue); - if (int == null) - { - c = EConst(CString(fieldValue)); - n = 'String'; - } - else - { - c = EConst(CInt(fieldValue)); - n = 'Int'; - } - } - - if (c == null) - Context.error('invalid field type', Context.currentPos()); - - if (staticFields) - fields.push({name: fieldName, doc: null, meta: [], access: access, kind: FVar(TPath({pack: [], name: n, params: p, sub: null}), {expr: c, pos: pos}), pos: pos}); - else - { - fields.push({name: fieldName, doc: null, meta: [], access: access, kind: FVar(TPath({pack: [], name: n, params: p, sub: null})), pos: pos}); - assign.push({expr: EBinop(Binop.OpAssign, {expr: EConst(CIdent(fieldName)), pos: pos}, {expr: c, pos: pos}), pos:pos}); - } + var key = a[next++]; + var val = a[next++]; + pairs.set(key, val); } + return pairs; } catch (unknown:Dynamic) { - Context.error('error parsing file: ' + unknown, Context.currentPos()); + return throw ('error parsing file: ' + unknown); } - - if (!staticFields) fields.push({name: 'new', doc: null, meta: [], access: [APublic], kind: FFun({args: [], ret: null, expr: {expr: EBlock(assign), pos:pos}, params: []}), pos: pos}); - return fields; } - #end - public static function getStaticFields(x:Class, filter:EReg = null):Array + public static function getStaticFields(x:Class, filter:EReg = null):Array<{key:String, val:Dynamic}> { var pairs = new Array(); From 75f828342c868e25e16c5d5c9e4dfd76aa2c7c17 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 24 Nov 2012 18:38:35 +0100 Subject: [PATCH 03/34] LogMessage.data Dynamic type --- src/de/polygonal/core/log/Log.hx | 4 +--- src/de/polygonal/core/log/LogMessage.hx | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/de/polygonal/core/log/Log.hx b/src/de/polygonal/core/log/Log.hx index 37f419f..24a84ed 100644 --- a/src/de/polygonal/core/log/Log.hx +++ b/src/de/polygonal/core/log/Log.hx @@ -294,12 +294,10 @@ class Log inline function output(level:Int, x:Dynamic, ?posInfos:PosInfos):Void { - var s = Std.string(x); - _counter++; if (_counter == 1000) _counter = 0; _logMessage.id = _counter; - _logMessage.data = s; + _logMessage.data = x; _logMessage.log = this; _logMessage.outputLevel = level; _logMessage.posInfos = posInfos; diff --git a/src/de/polygonal/core/log/LogMessage.hx b/src/de/polygonal/core/log/LogMessage.hx index 833fe49..ad00618 100644 --- a/src/de/polygonal/core/log/LogMessage.hx +++ b/src/de/polygonal/core/log/LogMessage.hx @@ -37,7 +37,7 @@ class LogMessage public function new() {} public var id:Int; - public var data:String; + public var data:Dynamic; public var outputLevel:Int; public var posInfos:haxe.PosInfos; public var log:Log; From 0542ad8d7ac44943572eb95b0a3110bd2b471b51 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 24 Nov 2012 18:39:00 +0100 Subject: [PATCH 04/34] Tween fix for haxe3 --- src/de/polygonal/core/tween/GenericTween.hx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/de/polygonal/core/tween/GenericTween.hx b/src/de/polygonal/core/tween/GenericTween.hx index 6369d3d..876e605 100644 --- a/src/de/polygonal/core/tween/GenericTween.hx +++ b/src/de/polygonal/core/tween/GenericTween.hx @@ -33,6 +33,7 @@ import de.polygonal.core.tween.ease.Ease; import de.polygonal.ds.ArrayUtil; using de.polygonal.ds.BitFlags; +using Reflect; /** *

Supports tweening of any field of any object.

@@ -68,11 +69,21 @@ class GenericTween extends Tween, implements TweenTarget public function set(x:Float):Void { - for (field in _fields) Reflect.setField(_object, field, x); + for (field in _fields) + { + if (Reflect.hasField(_object, field)) + Reflect.setField(_object, field, x); + else + Reflect.setProperty(_object, field, x); + } } public function get():Float { - return Reflect.field(_object, _fields[0]); + return + if (Reflect.hasField(_object, _fields[0])) + Reflect.field(_object, _fields[0]); + else + Reflect.getProperty(_object, _fields[0]); } } \ No newline at end of file From 5a5946ef1e59322ff6e6aa4a260ad859f930d4f8 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 24 Nov 2012 18:39:13 +0100 Subject: [PATCH 05/34] minor --- src/de/polygonal/core/math/random/ParkMiller31.hx | 2 ++ src/de/polygonal/core/time/StopWatch.hx | 1 + src/de/polygonal/core/util/Assert.hx | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/de/polygonal/core/math/random/ParkMiller31.hx b/src/de/polygonal/core/math/random/ParkMiller31.hx index e97c8c8..3564074 100644 --- a/src/de/polygonal/core/math/random/ParkMiller31.hx +++ b/src/de/polygonal/core/math/random/ParkMiller31.hx @@ -29,6 +29,8 @@ */ package de.polygonal.core.math.random; +import de.polygonal.core.util.Assert; + #if !flash using haxe.Int32; #end diff --git a/src/de/polygonal/core/time/StopWatch.hx b/src/de/polygonal/core/time/StopWatch.hx index f598cd4..5243804 100644 --- a/src/de/polygonal/core/time/StopWatch.hx +++ b/src/de/polygonal/core/time/StopWatch.hx @@ -32,6 +32,7 @@ package de.polygonal.core.time; import de.polygonal.core.math.Mean; import de.polygonal.ds.Bits; import de.polygonal.ds.DA; +import de.polygonal.core.util.Assert; using de.polygonal.ds.BitFlags; diff --git a/src/de/polygonal/core/util/Assert.hx b/src/de/polygonal/core/util/Assert.hx index 03f2683..a0db4b9 100644 --- a/src/de/polygonal/core/util/Assert.hx +++ b/src/de/polygonal/core/util/Assert.hx @@ -44,7 +44,7 @@ class Assert var error = false; - #if (haxe_211 && haxe3) + #if haxe_211 switch (Context.typeof(predicate)) { case TAbstract(a, b): From 8d6aee657355156187a9db3cfbce218e464376bb Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 24 Nov 2012 18:39:37 +0100 Subject: [PATCH 06/34] add PropertyFile.getClassFields() --- src/de/polygonal/core/util/PropertyFile.hx | 47 ++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index fdc32d7..4218835 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -211,24 +211,39 @@ class PropertyFile } } - public static function getStaticFields(x:Class, filter:EReg = null):Array<{key:String, val:Dynamic}> + public static function getClassFields(x:Class, include:EReg = null, excludeFunctions = true):Array<{name:String, value:Dynamic}> { - var pairs = new Array(); - - for (f in Type.getClassFields(x)) + var typeInfo:TypeTree; + var rtti:String = Reflect.field(x, '__rtti'); + var xml = Xml.parse(rtti).firstElement(); + typeInfo = new haxe.rtti.XmlParser().processElement(xml); + var fields = []; + switch (typeInfo) { - if (f == '__rtti') continue; - - if (filter == null) - { - pairs.push({key: f, val: Reflect.field(x, f)}); - continue; - } - - if (filter.match(f)) - pairs.push({key: f, val: Reflect.field(x, f)}); + case TClassdecl(cl): + for (f in cl.statics) + { + if (excludeFunctions) + { + switch (f.type) + { + case CFunction(_, _): + continue; + default: + } + } + + if (include != null) + { + if (include.match(f.name)) + fields.push({name: f.name, value: Reflect.field(x, f.name)}); + } + else + fields.push({name: f.name, value: Reflect.field(x, f.name)}); + } + default: + throw 'not a class'; } - - return pairs; + return fields; } } \ No newline at end of file From b3443664dc5c38a91270653c03d068570c24eff8 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 25 Nov 2012 14:33:29 +0100 Subject: [PATCH 07/34] remove no_log directive, log only for -D log --- src/de/polygonal/core/Root.hx | 10 ++++++---- src/de/polygonal/core/log/Log.hx | 21 +++++++++++++++++---- src/de/polygonal/core/log/LogHandler.hx | 16 ++++++++-------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/de/polygonal/core/Root.hx b/src/de/polygonal/core/Root.hx index 19fa34d..1dff6b8 100644 --- a/src/de/polygonal/core/Root.hx +++ b/src/de/polygonal/core/Root.hx @@ -53,7 +53,7 @@ class Root * "Hello World!".debug(); * */ - inline public static function debug(x:String) + inline public static function debug(x:Dynamic):Void { #if log #if debug @@ -71,7 +71,7 @@ class Root * "Hello World!".info(); * */ - inline public static function info(x:String) + inline public static function info(x:Dynamic):Void { #if log #if debug @@ -89,7 +89,7 @@ class Root * "Hello World!".warn(); * */ - inline public static function warn(x:String) + inline public static function warn(x:Dynamic):Void { #if log #if debug @@ -107,7 +107,7 @@ class Root * "Hello World!".error(); * */ - inline public static function error(x:String) + inline public static function error(x:Dynamic):Void { #if log #if debug @@ -150,6 +150,7 @@ class Root public static function init(handlers:Array = null, keepNativeTrace = false) { #if !no_traces + #if log var nativeTrace = function(v:Dynamic, ?infos:PosInfos) {}; if (keepNativeTrace) nativeTrace = haxe.Log.trace; @@ -186,5 +187,6 @@ class Root } trace('log initialized.'); #end + #end } } \ No newline at end of file diff --git a/src/de/polygonal/core/log/Log.hx b/src/de/polygonal/core/log/Log.hx index 24a84ed..d3fd316 100644 --- a/src/de/polygonal/core/log/Log.hx +++ b/src/de/polygonal/core/log/Log.hx @@ -123,9 +123,11 @@ class Log */ public function attach(x:LogHandler):Void { + #if log for (observer in _observable) if (observer == x) return; _observable.attach(x, 0); + #end } /** @@ -133,7 +135,9 @@ class Log */ public function detach(x:LogHandler):Void { + #if log _observable.detach(x); + #end } /** @@ -141,8 +145,10 @@ class Log */ public function detachAll():Void { + #if log for (handler in _observable.getObserverList()) detach(cast handler); + #end } /** @@ -222,8 +228,10 @@ class Log * } * @throws de.polygonal.core.util.AssertError invalid log level (debug only). */ + #if !log inline #end public function setLevel(x:Int):Void { + #if log #if debug D.assert((x & LogLevel.ALL) > 0, '(x & LogLevel.ALL) > 0'); #end @@ -242,15 +250,17 @@ class Log x >>= 1; _mask = _mask.clrBits(x); } + #end } /** * Logs a LogLevel.DEBUG message. * @param x the log message. */ + #if !log inline #end public function debug(x:Dynamic, ?posInfos:PosInfos):Void { - #if !no_log + #if log if (_observable.size() > 0) if (_mask.hasBits(LogLevel.DEBUG)) output(LogLevel.DEBUG, x, posInfos); #end @@ -260,9 +270,10 @@ class Log * Logs a LogLevel.INFO message. * @param x the log message. */ + #if !log inline #end public function info(x:Dynamic, ?posInfos:PosInfos):Void { - #if !no_log + #if log if (_observable.size() > 0) if (_mask.hasBits(LogLevel.INFO)) output(LogLevel.INFO, x, posInfos); #end @@ -272,9 +283,10 @@ class Log * Logs a LogLevel.WARN message. * @param x the log message. */ + #if !log inline #end public function warn(x:Dynamic, ?posInfos:PosInfos):Void { - #if !no_log + #if log if (_observable.size() > 0) if (_mask.hasBits(LogLevel.WARN)) output(LogLevel.WARN, x, posInfos); #end @@ -284,9 +296,10 @@ class Log * Logs a LogLevel.ERROR message. * @param x the log message. */ + #if !log inline #end public function error(x:Dynamic, ?posInfos:PosInfos):Void { - #if !no_log + #if log if (_observable.size() > 0) if (_mask.hasBits(LogLevel.ERROR)) output(LogLevel.ERROR, x, posInfos); #end diff --git a/src/de/polygonal/core/log/LogHandler.hx b/src/de/polygonal/core/log/LogHandler.hx index 3e71e87..3bad02b 100644 --- a/src/de/polygonal/core/log/LogHandler.hx +++ b/src/de/polygonal/core/log/LogHandler.hx @@ -250,17 +250,17 @@ class LogHandler implements IObserver { var data = _message.data; - if (data.indexOf('\n') != -1) + if (Std.is(data, String)) { - if (data.indexOf('\r') != -1) data = data.split('\r').join(''); - - var tmp = []; - for (i in data.split('\n')) + var s:String = data; + if (s.indexOf('\n') != -1) { - if (i != '') tmp.push(i); + if (s.indexOf('\r') != -1) s = s.split('\r').join(''); + var tmp = []; + for (i in s.split('\n')) + if (i != '') tmp.push(i); + data = '\n' + tmp.join('\n'); } - - data = '\n' + tmp.join('\n'); } var idFormat = '%s'; From 32b3ecea7e3467bf7e9b00ce4460a5fd0d4ee44e Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 25 Nov 2012 14:38:29 +0100 Subject: [PATCH 08/34] update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b14cddf..7593347 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ If you want to test the latest beta build, you should pull the dev branch and ad ## Changelog +### 1.xx (dev-branch) + + * modified: change LogMessage.data type to Dynamic + ### 1.01 (released 2012-11-15) * fixed: Mathematics.floor(), ceil(), fwrap() for neko, don't use Std.int() for cpp From 6c175dcffe5eab375f63285faf7a2da07c28128a Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 25 Nov 2012 20:30:38 +0100 Subject: [PATCH 09/34] remove string casting in haxe.Log.trace --- src/de/polygonal/core/Root.hx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/de/polygonal/core/Root.hx b/src/de/polygonal/core/Root.hx index 1dff6b8..e9ddfb2 100644 --- a/src/de/polygonal/core/Root.hx +++ b/src/de/polygonal/core/Root.hx @@ -173,17 +173,22 @@ class Root haxe.Log.trace = function(x:Dynamic, ?posInfos:PosInfos) { - var s = Std.string(x); - if (posInfos.customParams != null) + if (Std.is(x, String)) { - if (~/%(([+\- #0])*)?((\d+)|(\*))?(\.(\d?|(\*)))?[hlL]?[bcdieEfgGosuxX]/g.match(s)) - s = Sprintf.format(s, posInfos.customParams); - else - s += ',' + posInfos.customParams.join(','); + var s:String = x; + if (posInfos.customParams != null) + { + if (~/%(([+\- #0])*)?((\d+)|(\*))?(\.(\d?|(\*)))?[hlL]?[bcdieEfgGosuxX]/g.match(s)) + s = Sprintf.format(s, posInfos.customParams); + else + s += ',' + posInfos.customParams.join(','); + } + + x = s; } - Root.log.debug(s, posInfos); - nativeTrace(s, posInfos); + Root.log.debug(x, posInfos); + nativeTrace(x, posInfos); } trace('log initialized.'); #end From 2325d7daf1e50581757d476358a3d4845c550b1b Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 17:44:56 +0100 Subject: [PATCH 10/34] improve PropertyFile parser --- src/de/polygonal/core/util/PropertyFile.hx | 173 +++++++++++---------- 1 file changed, 87 insertions(+), 86 deletions(-) diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index 4218835..7685cb1 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -29,9 +29,6 @@ */ package de.polygonal.core.util; -import de.polygonal.core.fmt.ASCII; -import haxe.rtti.CType.TypeTree; - #if macro import haxe.macro.Context; import haxe.macro.Expr; @@ -143,107 +140,111 @@ class PropertyFile } #end - public static function parse(s:String):Hash + /** + * Parses a .properties file according to this format. + * @return a hash with all key/value pairs defined in str. + */ + public static function parse(str:String):Hash { - try + var pairs = new Hash(); + + var line = ''; + + var i = 0; + var k = str.length - 1; + while (i < k) { - var a = []; - var b = ''; - var i = 0; - while (i < s.length) + var c = str.charAt(i++); + var peek = str.charAt(i); + + if (c == '\r') { - var c = s.charCodeAt(i); - - //skip comment? - if (c == ASCII.NUMBERSIGN || c == ASCII.EXCLAM) + if (peek == '\n') { i++; - var t = ''; - while (s.charCodeAt(i) != ASCII.NEWLINE) + if (str.charAt(i - 3) != '\\') { - t += s.charAt(i); - i++; + var pair = parseLine(line); + if (pair != null) pairs.set(pair.key, pair.val); + line = ''; } - continue; } - - //skip whitespace? - if (ASCII.isWhite(c)) + else + if (str.charAt(i - 2) != '\\') { - if (b != '') - { - a.push(b); - b = ''; - } - i++; - continue; + var pair = parseLine(line); + if (pair != null) pairs.set(pair.key, pair.val); + line = ''; } - - if (c == ASCII.COLON || c == ASCII.EQUAL) - { - if (b != '') - { - a.push(b); - b = ''; - } - i++; - continue; - } - - b += s.charAt(i++); } - - if (b != '') a.push(b); - - var pairs = new Hash(); - var next = 0; - for (i in 0...a.length >> 1) + else + if (c == '\n') { - var key = a[next++]; - var val = a[next++]; - pairs.set(key, val); + if (str.charAt(i - 2) != '\\') + { + var pair = parseLine(line); + if (pair != null) pairs.set(pair.key, pair.val); + line = ''; + } } - return pairs; - } - catch (unknown:Dynamic) - { - return throw ('error parsing file: ' + unknown); + else + if (c == '\\') {} + else + line += c; } + + line += str.charAt(k); + + var pair = parseLine(line); + if (pair != null) pairs.set(pair.key, pair.val); + + return pairs; } - public static function getClassFields(x:Class, include:EReg = null, excludeFunctions = true):Array<{name:String, value:Dynamic}> + static function parseLine(str:String):{key:String, val:String} { - var typeInfo:TypeTree; - var rtti:String = Reflect.field(x, '__rtti'); - var xml = Xml.parse(rtti).firstElement(); - typeInfo = new haxe.rtti.XmlParser().processElement(xml); - var fields = []; - switch (typeInfo) + var i = 0; + var k = str.length; + + while (i < k) { - case TClassdecl(cl): - for (f in cl.statics) - { - if (excludeFunctions) - { - switch (f.type) - { - case CFunction(_, _): - continue; - default: - } - } - - if (include != null) - { - if (include.match(f.name)) - fields.push({name: f.name, value: Reflect.field(x, f.name)}); - } - else - fields.push({name: f.name, value: Reflect.field(x, f.name)}); - } - default: - throw 'not a class'; + if (str.charAt(i) == ' ') + i++; + else + break; } - return fields; + + var c = str.charAt(i); + if (c == '#') return null; + if (c == '!') return null; + + var key = ''; + while (i < k) + { + var c = str.charAt(i++); + if (c == ' ' || c == ':' || c == '=') break; + key += c; + } + + while (i < k) + { + if (str.charAt(i) == ' ') + i++; + else + break; + } + + var val = ''; + while (i < k) + { + var c = str.charAt(i++); + val += c; + } + + if (val == '') val = key; + + if (val == key && val == '') return null; + + return {key: key, val: val}; } } \ No newline at end of file From 1b4e3b25b43ab8b160219cd7aee4ecf1ef4cd4e4 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 17:45:12 +0100 Subject: [PATCH 11/34] add ClassUtil --- src/de/polygonal/core/fmt/StringUtil.hx | 49 ---------- src/de/polygonal/core/sys/Entity.hx | 8 +- src/de/polygonal/core/util/ClassUtil.hx | 124 ++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 51 deletions(-) create mode 100644 src/de/polygonal/core/util/ClassUtil.hx diff --git a/src/de/polygonal/core/fmt/StringUtil.hx b/src/de/polygonal/core/fmt/StringUtil.hx index 93f6d84..5492448 100644 --- a/src/de/polygonal/core/fmt/StringUtil.hx +++ b/src/de/polygonal/core/fmt/StringUtil.hx @@ -145,55 +145,6 @@ class StringUtil return h; } - /** - * Returns the unqualified class name of x. - */ - public static function getUnqualifiedClassName(x:Dynamic):String - { - if (Std.is(x, Class)) - { - var s = Type.getClassName(x); - return s.substr(s.lastIndexOf('.') + 1); - } - else - if (Type.getClass(x) != null) - return getUnqualifiedClassName(Type.getClass(x)); - else - return ''; - } - - /** - * Extracts the package name from x. - */ - public static function getPackageName(x:Dynamic):String - { - if (Std.is(x, String)) - { - var s:String = x; - var i = s.lastIndexOf('.'); - if (i != -1) - return s.substr(0, i); - else - return ''; - } - else - if (Std.is(x, Class)) - { - var s = Type.getClassName(x); - var i = s.lastIndexOf('.'); - if (i != -1) - return s.substr(0, i); - else - return ''; - } - else - if (Type.getClass(x) != null) - return getPackageName(Type.getClass(x)); - else - throw 'invalid argument'; - } - - /** * Generates a random key of given chars and length. */ diff --git a/src/de/polygonal/core/sys/Entity.hx b/src/de/polygonal/core/sys/Entity.hx index 96f6ce8..063eb31 100644 --- a/src/de/polygonal/core/sys/Entity.hx +++ b/src/de/polygonal/core/sys/Entity.hx @@ -33,8 +33,8 @@ import de.polygonal.core.event.IObservable; import de.polygonal.core.event.IObserver; import de.polygonal.core.event.Observable; import de.polygonal.core.fmt.Sprintf; -import de.polygonal.core.fmt.StringUtil; import de.polygonal.core.math.Limits; +import de.polygonal.core.util.ClassUtil; import de.polygonal.ds.Bits; import de.polygonal.ds.Hashable; import de.polygonal.ds.HashKey; @@ -187,7 +187,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable public function new(id:String = null) { - this.id = id == null ? StringUtil.getUnqualifiedClassName(this) : id; + this.id = id == null ? ClassUtil.getUnqualifiedClassName(this) : id; treeNode = new TreeNode(this); key = HashKey.next(); priority = Limits.UINT16_MAX; @@ -415,6 +415,10 @@ class Entity implements IObserver, implements IObservable, implements Hashable */ public function add(x:Dynamic, priority = Limits.UINT16_MAX):Entity { + #if debug + D.assert(x != null, 'x is null'); + #end + var c:Entity = #if flash if (untyped x.hasOwnProperty('prototype')) diff --git a/src/de/polygonal/core/util/ClassUtil.hx b/src/de/polygonal/core/util/ClassUtil.hx new file mode 100644 index 0000000..e589afa --- /dev/null +++ b/src/de/polygonal/core/util/ClassUtil.hx @@ -0,0 +1,124 @@ +/* + * _/ _/ + * _/_/_/ _/_/ _/ _/ _/ _/_/_/ _/_/ _/_/_/ _/_/_/ _/ + * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ + * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ + * _/_/_/ _/_/ _/ _/_/_/ _/_/_/ _/_/ _/ _/ _/_/_/ _/ + * _/ _/ _/ + * _/ _/_/ _/_/ + * + * POLYGONAL - A HAXE LIBRARY FOR GAME DEVELOPERS + * Copyright (c) 2009 Michael Baczynski, http://www.polygonal.de + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package de.polygonal.core.util; + +import haxe.rtti.CType.TypeTree; + +class ClassUtil +{ + /** + * Returns the unqualified class name of x. + */ + public static function getUnqualifiedClassName(x:Dynamic):String + { + if (Std.is(x, Class)) + { + var s = Type.getClassName(x); + return s.substr(s.lastIndexOf('.') + 1); + } + else + if (Type.getClass(x) != null) + return getUnqualifiedClassName(Type.getClass(x)); + else + return ''; + } + + /** + * Extracts the package name from x. + */ + public static function getPackageName(x:Dynamic):String + { + if (Std.is(x, String)) + { + var s:String = x; + var i = s.lastIndexOf('.'); + if (i != -1) + return s.substr(0, i); + else + return ''; + } + else + if (Std.is(x, Class)) + { + var s = Type.getClassName(x); + var i = s.lastIndexOf('.'); + if (i != -1) + return s.substr(0, i); + else + return ''; + } + else + if (Type.getClass(x) != null) + return getPackageName(Type.getClass(x)); + else + throw 'invalid argument'; + } + + /** + * Returns all class fields of the class x. + * @param include if defined, only returns fields that match the given regular expression. + * @param excludeFunctions if true, excludes functions. + */ + public static function getClassFields(x:Class, include:EReg = null, excludeFunctions = true):Array<{name:String, value:Dynamic}> + { + var typeInfo:TypeTree; + var rtti:String = Reflect.field(x, '__rtti'); + var xml = Xml.parse(rtti).firstElement(); + typeInfo = new haxe.rtti.XmlParser().processElement(xml); + var fields = []; + switch (typeInfo) + { + case TClassdecl(cl): + for (f in cl.statics) + { + if (excludeFunctions) + { + switch (f.type) + { + case CFunction(_, _): + continue; + default: + } + } + + if (include != null) + { + if (include.match(f.name)) + fields.push({name: f.name, value: Reflect.field(x, f.name)}); + } + else + fields.push({name: f.name, value: Reflect.field(x, f.name)}); + } + default: + throw 'not a class'; + } + return fields; + } +} \ No newline at end of file From a4e31d9fd5f8d37ceaaa0bf31ec122c3622101d6 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 17:45:30 +0100 Subject: [PATCH 12/34] minor --- src/de/polygonal/core/io/ResourceLoader.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/de/polygonal/core/io/ResourceLoader.hx b/src/de/polygonal/core/io/ResourceLoader.hx index 9b3ef90..8aaec59 100644 --- a/src/de/polygonal/core/io/ResourceLoader.hx +++ b/src/de/polygonal/core/io/ResourceLoader.hx @@ -41,6 +41,7 @@ import de.polygonal.ds.Prioritizable; import de.polygonal.ds.PriorityQueue; import de.polygonal.ds.Set; import de.polygonal.ds.HashKey; +import de.polygonal.core.util.Assert; private class PrioritizedResource extends HashableItem, implements Prioritizable, implements Cloneable { From bd511a065a2e023fee5914ac5276096b9eecefd7 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 17:45:56 +0100 Subject: [PATCH 13/34] add plist extension to resource loader --- src/de/polygonal/core/io/Resource.hx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/de/polygonal/core/io/Resource.hx b/src/de/polygonal/core/io/Resource.hx index edb42f7..2a42cfb 100644 --- a/src/de/polygonal/core/io/Resource.hx +++ b/src/de/polygonal/core/io/Resource.hx @@ -137,7 +137,7 @@ class Resource extends Observable /** * The resource data: *
    - *
  • a DisplayObject (ResourceType.SWF, ResourceType.PIC)
  • + *
  • a DisplayObject or Bitmap object(ResourceType.SWF, ResourceType.PIC)
  • *
  • a Sound object (ResourceType.MP3)
  • *
  • a String containing the text of the loaded file (ResourceType.TXT)
  • *
  • a ByteArray containing raw binary data (ResourceType.RAW)
  • @@ -215,10 +215,10 @@ class Resource extends Observable var suffix = request.url.substr(request.url.lastIndexOf('.') + 1); switch (suffix) { - case 'swf': type = ResourceType.SWF; - case 'gif', 'png', 'jpg': type = ResourceType.PIC; - case 'mp3': type = ResourceType.MP3; - case 'xml', 'txt': type = ResourceType.TXT; + case 'swf': type = ResourceType.SWF; + case 'gif', 'png', 'jpg': type = ResourceType.PIC; + case 'mp3': type = ResourceType.MP3; + case 'xml', 'txt', 'plist' : type = ResourceType.TXT; default: throw 'unknown file type'; From 54b962dc9bfd412fd11bc9dd4e7fc52ff673d600 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 17:46:06 +0100 Subject: [PATCH 14/34] minor haxe3 fix --- src/de/polygonal/core/fmt/Sprintf.hx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/de/polygonal/core/fmt/Sprintf.hx b/src/de/polygonal/core/fmt/Sprintf.hx index a98d338..d11cf62 100644 --- a/src/de/polygonal/core/fmt/Sprintf.hx +++ b/src/de/polygonal/core/fmt/Sprintf.hx @@ -819,6 +819,15 @@ class Sprintf value &= 0xffff; //toBin() + #if haxe3 + var i = value; + do + { + output = ((i & 1) > 0 ? '1' : '0') + output; + i >>>= 1; + } + while (i > 0); + #else var i = value.ofInt(); do { @@ -826,6 +835,7 @@ class Sprintf i = haxe.Int32.ushr(i, 1); } while (i.compare(0.ofInt()) > 0); + #end if (args.precision > 1) { From a9fbc3a40a77b3e4f7a773fe30fa5d63024d683a Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 18:19:01 +0100 Subject: [PATCH 15/34] skip tabs --- src/de/polygonal/core/util/PropertyFile.hx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index 7685cb1..2a0b425 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -208,7 +208,8 @@ class PropertyFile while (i < k) { - if (str.charAt(i) == ' ') + var c = str.charAt(i); + if (c == ' ' || c == '\t') i++; else break; @@ -222,13 +223,14 @@ class PropertyFile while (i < k) { var c = str.charAt(i++); - if (c == ' ' || c == ':' || c == '=') break; + if (c == ' ' || c == '\t' || c == ':' || c == '=') break; key += c; } while (i < k) { - if (str.charAt(i) == ' ') + var c = str.charAt(i); + if (c == ' ' || c == '\t') i++; else break; From 7ef7106f1f9a30d9cf37a0f9718644138d0c20aa Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 2 Dec 2012 18:19:15 +0100 Subject: [PATCH 16/34] update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7593347..527a410 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ If you want to test the latest beta build, you should pull the dev branch and ad ### 1.xx (dev-branch) * modified: change LogMessage.data type to Dynamic + * added: ClassUtil class ### 1.01 (released 2012-11-15) From 7d58075ec0caa5cda182fa35c7d3c2315d522270 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Tue, 25 Dec 2012 14:26:57 +0100 Subject: [PATCH 17/34] add Mat33.setRotateX, setRotateY --- src/de/polygonal/core/math/Mat33.hx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/de/polygonal/core/math/Mat33.hx b/src/de/polygonal/core/math/Mat33.hx index 3bb0f11..132a800 100644 --- a/src/de/polygonal/core/math/Mat33.hx +++ b/src/de/polygonal/core/math/Mat33.hx @@ -149,6 +149,30 @@ class Mat33 return this; } + /** Set as rotation matrix, rotating by angle radians around x-axis. */ + inline public function setRotateX(angle:Float):Mat33 + { + _fastTrig(angle); + var s = sineCosine.x; + var c = sineCosine.y; + m11 = 1; m12 = 0; m13 = 0; + m21 = 0; m22 = c; m23 =-s; + m31 = 0; m32 = s; m33 = c; + return this; + } + + /** Set as rotation matrix, rotating by angle radians around y-axis. */ + inline public function setRotateY(angle:Float):Mat33 + { + _fastTrig(angle); + var s = sineCosine.x; + var c = sineCosine.y; + m11 = c; m12 = 0; m13 = s; + m21 = 0; m22 = 1; m23 = 0; + m31 =-s; m32 = 0; m33 = c; + return this; + } + /** Set as rotation matrix, rotating by angle radians around z-axis. */ inline public function setRotateZ(angle:Float):Mat33 { From 50a107ad84e26a88fadb4d74e807ee8f32fca8b4 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Tue, 25 Dec 2012 14:27:25 +0100 Subject: [PATCH 18/34] minor --- src/de/polygonal/core/math/Mathematics.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/polygonal/core/math/Mathematics.hx b/src/de/polygonal/core/math/Mathematics.hx index 812378c..ff13adf 100644 --- a/src/de/polygonal/core/math/Mathematics.hx +++ b/src/de/polygonal/core/math/Mathematics.hx @@ -348,7 +348,7 @@ class Mathematics { var s0 = 1 - t; var s1 = t; - return m.atan2(s0 * c1 + s1 * c2, s0 * r1 + s1 * r2) * 2; + return m.atan2(s0 * c1 + s1 * c2, s0 * r1 + s1 * r2) * 2.; } } } From 1fe99eb05c1d2b5d8d7255c124a6d8e2e9e1d074 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Tue, 25 Dec 2012 14:27:37 +0100 Subject: [PATCH 19/34] fix Timebase.gameTime --- src/de/polygonal/core/time/Timebase.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/de/polygonal/core/time/Timebase.hx b/src/de/polygonal/core/time/Timebase.hx index 1a203a3..67557fc 100644 --- a/src/de/polygonal/core/time/Timebase.hx +++ b/src/de/polygonal/core/time/Timebase.hx @@ -138,6 +138,7 @@ class Timebase extends Observable timeScale = 1; realTime = 0; realTimeDelta = 0; + gameTime = 0; gameTimeDelta = 0; fps = 60; From 41e95efbe90da60d3d27d133a8859b7711e13100 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Tue, 25 Dec 2012 14:27:45 +0100 Subject: [PATCH 20/34] haxe3 fix --- src/de/polygonal/core/util/PropertyFile.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index 2a0b425..e6f500c 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -52,7 +52,7 @@ class PropertyFile access.push(AInline); } - var map = parse(neko.io.File.getContent(url)); + var map = parse(sys.io.File.getContent(url)); for (key in map.keys()) { var val = map.get(key); From fde06aba9639e63999d014c9a6d2dcef7ce3e141 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 5 Jan 2013 21:48:38 +0100 Subject: [PATCH 21/34] add Mat44.ofMatrix3D --- src/de/polygonal/core/math/Mat44.hx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/de/polygonal/core/math/Mat44.hx b/src/de/polygonal/core/math/Mat44.hx index e87258f..906e4c7 100644 --- a/src/de/polygonal/core/math/Mat44.hx +++ b/src/de/polygonal/core/math/Mat44.hx @@ -885,7 +885,7 @@ class Mat44 } /** - * Copies all 16 matrix elements to the given matrix x.
    + * Copies all 16 matrix elements from this matrix to the given matrix x.
    * If x is omitted, a new Matrix3D object is created on the fly. */ public function toMatrix3D(x:flash.geom.Matrix3D = null):flash.geom.Matrix3D @@ -897,6 +897,21 @@ class Mat44 return x; } + /** + * Copies all 16 matrix elements from the given matrix x into this matrix.
    + * if x is omitted, a new Matrix3D object is created on the fly. + */ + public function ofMatrix3D(x:flash.geom.Matrix3D = null):Mat44 + { + if (x == null) x = new flash.geom.Matrix3D(); + var t = x.rawData; + m11 = t[ 0]; m12 = t[ 1]; m13 = t[ 2]; m14 = t[ 3]; + m21 = t[ 4]; m22 = t[ 5]; m23 = t[ 6]; m24 = t[ 7]; + m31 = t[ 8]; m32 = t[ 9]; m33 = t[10]; m34 = t[11]; + m41 = t[12]; m42 = t[13]; m43 = t[14]; m44 = t[15]; + return this; + } + /** * Copies all 16 matrix elements from the vector x. * @param columnMajor if true, 4 consecutive vector elements are interpreted as colums of the matrix, otherwise as the rows of the matrix. From d3fcec45d2243aed3fda8b38fc8808116e20fb27 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 5 Jan 2013 21:55:47 +0100 Subject: [PATCH 22/34] refactor Mat44.setOrthoSimple() --- src/de/polygonal/core/math/Mat44.hx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/de/polygonal/core/math/Mat44.hx b/src/de/polygonal/core/math/Mat44.hx index 906e4c7..8ab5132 100644 --- a/src/de/polygonal/core/math/Mat44.hx +++ b/src/de/polygonal/core/math/Mat44.hx @@ -346,6 +346,12 @@ class Mat44 /** * Defines a parallel projection, same as glOrtho().
    * @see http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glOrtho.htm + * @param l coordinates for the left clipping plane. + * @param r coordinates for the right clipping plane. + * @param b coordinates for the bottom clipping plane. + * @param t coordinates for the top clipping plane. + * @param n coordinates for the near clipping plane. + * @param f coordinates for the far clipping plane. */ public function setOrtho(l:Float, r:Float, b:Float, t:Float, n:Float, f:Float):Mat44 { @@ -361,20 +367,15 @@ class Mat44 /** * Defines a parallel projection.
    - * Simplied version of setOrtho6() using 4 parameters instead of 6. - * @param w width of field of view - * @param h height of field of view - * @param n near clipping plane - * @param f far clipping plane + * Simplied version of setOrtho6() using 4 parameters instead of 6 for a symmetrical viewing volume. + * @param width width of field of view + * @param height height of field of view + * @param near near clipping plane + * @param far far clipping plane */ - public function setOrthoSimple(w:Float, h:Float, n:Float, f:Float):Mat44 + public function setOrthoSimple(width:Float, height:Float, near:Float, far:Float):Mat44 { - var d = f - n; - m11 = 2 / w; m12 = 0; m13 = 0; m14 = 0; - m21 = 0; m22 = 2 / h; m23 = 0; m24 = 0; - m31 = 0; m32 = 0; m33 = 1 / d; m34 = -n / d; - m41 = 0; m42 = 0; m43 = 0; m44 = 1; - return this; + return setOrtho(0, width, 0, height, near, far); } /** From 5379c85b69807247d9d047c3268ae48ef5193dcf Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 5 Jan 2013 22:05:41 +0100 Subject: [PATCH 23/34] remember draw/tick state when calling Entity.sleep() and Entity.wakeup() --- src/de/polygonal/core/sys/Entity.hx | 22 ++++++++++++++-------- src/de/polygonal/core/sys/EntityType.hx | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/de/polygonal/core/sys/Entity.hx b/src/de/polygonal/core/sys/Entity.hx index 063eb31..ab8f92a 100644 --- a/src/de/polygonal/core/sys/Entity.hx +++ b/src/de/polygonal/core/sys/Entity.hx @@ -80,6 +80,8 @@ class Entity implements IObserver, implements IObservable, implements Hashable inline static var BIT_REMOVE_DESCENDANT = Bits.BIT_16; inline static var BIT_ADD_SIBLING = Bits.BIT_17; inline static var BIT_REMOVE_SIBLING = Bits.BIT_18; + inline static var BIT_TICK_BEFORE_SLEEP = Bits.BIT_19; + inline static var BIT_DRAW_BEFORE_SLEEP = Bits.BIT_20; inline static var BIT_PENDING = BIT_PENDING_ADD | BIT_PENDING_REMOVE; @@ -188,8 +190,8 @@ class Entity implements IObserver, implements IObservable, implements Hashable public function new(id:String = null) { this.id = id == null ? ClassUtil.getUnqualifiedClassName(this) : id; - treeNode = new TreeNode(this); key = HashKey.next(); + treeNode = new TreeNode(this); priority = Limits.UINT16_MAX; _flags = BIT_TICK | BIT_PROCESS_SUBTREE | UPDATE_ALL; _observable = null; @@ -624,7 +626,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable */ public function sibling(x:Class):T { - var a:Int = getClassType(x); + var a = getClassType(x); var n = treeNode.getFirstSibling(); var m = Entity.typeMap; while (n != null) @@ -820,6 +822,10 @@ class Entity implements IObserver, implements IObservable, implements Hashable public function sleep(deep = false) { + clrf(BIT_TICK_BEFORE_SLEEP | BIT_DRAW_BEFORE_SLEEP); + if (hasf(BIT_TICK)) setf(BIT_TICK_BEFORE_SLEEP); + if (hasf(BIT_DRAW)) setf(BIT_DRAW_BEFORE_SLEEP); + if (deep) clrf(BIT_TICK | BIT_DRAW | BIT_PROCESS_SUBTREE); else @@ -828,10 +834,10 @@ class Entity implements IObserver, implements IObservable, implements Hashable public function wakeup(deep = false) { - if (deep) - setf(BIT_TICK | BIT_DRAW | BIT_PROCESS_SUBTREE); - else - setf(BIT_TICK | BIT_DRAW); + if (hasf(BIT_TICK_BEFORE_SLEEP)) setf(BIT_TICK); + if (hasf(BIT_DRAW_BEFORE_SLEEP)) setf(BIT_DRAW); + + if (deep) setf(BIT_PROCESS_SUBTREE); } public function toString():String @@ -1433,9 +1439,9 @@ class Entity implements IObserver, implements IObservable, implements Hashable inline function getClassType(C:Class):Int { #if flash - return untyped C.__etype; + return untyped C.___type; #else - return Reflect.field(C, '__etype'); + return Reflect.field(C, '___type'); #end } diff --git a/src/de/polygonal/core/sys/EntityType.hx b/src/de/polygonal/core/sys/EntityType.hx index a6e8bb6..16886e8 100644 --- a/src/de/polygonal/core/sys/EntityType.hx +++ b/src/de/polygonal/core/sys/EntityType.hx @@ -48,7 +48,7 @@ class EntityType f.push ( { - name: '__etype', + name: '___type', doc: null, meta: [], access: [APublic, AStatic], From 10f7b74c98a39a9d38cd30a5aaca8ad354b3d478 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 19 Jan 2013 21:36:21 +0100 Subject: [PATCH 24/34] improve EntityType macro to allow compilation server --- src/de/polygonal/core/sys/EntityType.hx | 105 +++++++++++++++++++++--- 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/src/de/polygonal/core/sys/EntityType.hx b/src/de/polygonal/core/sys/EntityType.hx index 16886e8..4bf6239 100644 --- a/src/de/polygonal/core/sys/EntityType.hx +++ b/src/de/polygonal/core/sys/EntityType.hx @@ -29,34 +29,115 @@ */ package de.polygonal.core.sys; -import haxe.macro.Expr; +#if macro import haxe.macro.Context; +import haxe.macro.Expr; +#end -class EntityType +/** + * Generates an unique identifier for every class extending de.polygonal.core.sys.Entity. + */ +class EntityType { #if macro - public static var counter = 1; - #end + inline static var CACHE_PATH = 'tmp_entity_type_cache'; - @:macro public static function gen():Array + static var callbackRegistered = false; + static var types:Hash = null; + static var cache:String = null; + static var next = -1; + static var changed = false; + + #if haxe3 macro #else @:macro #end + public static function gen():Array { - if (haxe.macro.Context.defined('display')) return null; - var c = haxe.macro.Context.getLocalClass().get(); + if (Context.defined('display')) return null; + Context.registerModuleDependency('de.polygonal.core.sys.Entity', 'cache'); + + //write cache file when done + if (!callbackRegistered) + { + callbackRegistered = true; + Context.onGenerate(onGenerate); + } - var p = haxe.macro.Context.currentPos(); + var c = Context.getLocalClass().get(); var f = Context.getBuildFields(); - f.push + + //create unique id for the local class + var id = c.module; + if (c.module.indexOf(c.name) == -1) + id += c.name; + + if (cache == null) + if (sys.FileSystem.exists(CACHE_PATH)) + cache = sys.io.File.getContent(CACHE_PATH); + + if (cache != null) + { + if (types == null) + { + //parse cache file and store in types map + types = new Hash(); + next = -1; + for (i in cache.split(';')) + { + var ereg = ~/([\w.]+):(\d+)/; + ereg.match(i); + var j = Std.parseInt(ereg.matched(2)); + if (j > next) next = j; + types.set(ereg.matched(1), j); + } + } + + if (types.exists(id)) + { + //reuse type + addType(f, types.get(id)); + } + else + { + //append type + next++; + addType(f, next); + types.set(id, next); + cache += ';' + id + ':' + next; + changed = true; + } + } + else + { + //no cache file exists + addType(f, 1); + cache = id + ':' + 1; + changed = true; + } + + return f; + } + + static function addType(fields:Array, type:Int):Void + { + var p = Context.currentPos(); + fields.push ( { name: '___type', doc: null, meta: [], access: [APublic, AStatic], - kind: FVar(TPath({pack: [], name: 'Int', params: [], sub: null}), {expr: EConst(CInt(Std.string(counter++))), pos: p}), + kind: FVar(TPath({pack: [], name: 'Int', params: [], sub: null}), {expr: EConst(CInt(Std.string(type))), pos: p}), pos: p } ); - - return f; } + + static function onGenerate(types:Array):Void + { + if (!changed) return; + var fout = sys.io.File.write(CACHE_PATH, false); + fout.writeString(cache); + fout.close(); + } + #end } \ No newline at end of file From 0022aa526db4d9089092313ed25d1b0883b263f8 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 19 Jan 2013 21:37:00 +0100 Subject: [PATCH 25/34] add Mathematics.int --- src/de/polygonal/core/math/Mathematics.hx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/de/polygonal/core/math/Mathematics.hx b/src/de/polygonal/core/math/Mathematics.hx index ff13adf..6b7403d 100644 --- a/src/de/polygonal/core/math/Mathematics.hx +++ b/src/de/polygonal/core/math/Mathematics.hx @@ -598,4 +598,16 @@ class Mathematics { return (x ? 1 : 0); } + + /** + * Casts a float to an integer. For cpp, this is faster than Std.int(). + */ + inline public static function int(f:Float):Int + { + #if cpp + return cast f; + #else + return Std.int(f); + #end + } } \ No newline at end of file From 138e8be2360bbafa6f3f1ffd6b9039c6ccee2cea Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sat, 19 Jan 2013 21:38:37 +0100 Subject: [PATCH 26/34] rename Observable.mute -> muteType, Observable.unmute -> unmuteType to prevent name clash with Entity class --- src/de/polygonal/core/event/Observable.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de/polygonal/core/event/Observable.hx b/src/de/polygonal/core/event/Observable.hx index b419c68..ea8650a 100644 --- a/src/de/polygonal/core/event/Observable.hx +++ b/src/de/polygonal/core/event/Observable.hx @@ -540,7 +540,7 @@ class Observable extends HashableItem, implements IObservable * Disables all updates of type x.
    * Improves performance if an event group repeatedly fires frequent updates that are not handled by an application (e.g. mouse move events). */ - public function mute(x:Int):Void + public function muteType(x:Int):Void { _blacklist |= x; } @@ -548,7 +548,7 @@ class Observable extends HashableItem, implements IObservable /** * Removes the update type x from a blacklist of disabled updates, see mute().
    */ - public function unmute(x:Int):Void + public function unmuteType(x:Int):Void { _blacklist = _blacklist & ~x; } From 4706905def6127450391b844a439e3cb46515275 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 20 Jan 2013 18:26:10 +0100 Subject: [PATCH 27/34] some temporary haxe3 fixes --- src/de/polygonal/core/event/ObserverMacro.hx | 7 +++++-- src/de/polygonal/core/util/Assert.hx | 7 ++++++- src/de/polygonal/core/util/IntEnum.hx | 3 ++- src/de/polygonal/core/util/PropertyFile.hx | 3 ++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/de/polygonal/core/event/ObserverMacro.hx b/src/de/polygonal/core/event/ObserverMacro.hx index 577df74..3f9674e 100644 --- a/src/de/polygonal/core/event/ObserverMacro.hx +++ b/src/de/polygonal/core/event/ObserverMacro.hx @@ -105,7 +105,9 @@ class ObserverMacro static var NUM_EVENT_BITS:Int; static var _groupCounter = 0; - @:macro public static function create(e:Expr):Array + + #if haxe3 macro #else @:macro #end + public static function create(e:Expr):Array { var numBits = Context.defined('neko') ? 30 : 32; NUM_EVENT_BITS = numBits - NUM_GROUP_BITS; @@ -154,7 +156,8 @@ class ObserverMacro return fields; } - @:macro public static function guid():Array + #if haxe3 macro #else @:macro #end + public static function guid():Array { if (haxe.macro.Context.defined('display')) return null; var c = haxe.macro.Context.getLocalClass().get(); diff --git a/src/de/polygonal/core/util/Assert.hx b/src/de/polygonal/core/util/Assert.hx index a0db4b9..ce19b42 100644 --- a/src/de/polygonal/core/util/Assert.hx +++ b/src/de/polygonal/core/util/Assert.hx @@ -38,7 +38,8 @@ typedef D = de.polygonal.core.util.Assert; class Assert { - @:macro public static function assert(predicate:Expr, ?info:Expr):Expr + #if haxe3 macro #else @:macro #end + public static function assert(predicate:Expr, ?info:Expr):Expr { if (!Context.defined('debug')) return {expr: EConst(CInt('0')), pos: Context.currentPos()}; @@ -47,7 +48,11 @@ class Assert #if haxe_211 switch (Context.typeof(predicate)) { + #if haxe3 + case TAbstract: + #else case TAbstract(a, b): + #end default: error = true; } diff --git a/src/de/polygonal/core/util/IntEnum.hx b/src/de/polygonal/core/util/IntEnum.hx index f5c0192..0dd395f 100644 --- a/src/de/polygonal/core/util/IntEnum.hx +++ b/src/de/polygonal/core/util/IntEnum.hx @@ -34,7 +34,8 @@ import haxe.macro.Expr; class IntEnum { - @:macro public static function build(e:Expr, bitFlags:Bool = false):Array + #if haxe3 macro #else @:macro #end + public static function build(e:Expr, bitFlags:Bool = false):Array { var pos = Context.currentPos(); var fields = Context.getBuildFields(); diff --git a/src/de/polygonal/core/util/PropertyFile.hx b/src/de/polygonal/core/util/PropertyFile.hx index e6f500c..767e890 100644 --- a/src/de/polygonal/core/util/PropertyFile.hx +++ b/src/de/polygonal/core/util/PropertyFile.hx @@ -37,7 +37,8 @@ import haxe.macro.Expr; class PropertyFile { #if macro - @:macro public static function build(url:String, staticFields:Bool):Array + #if haxe3 macro #else @:macro #end + public static function build(url:String, staticFields:Bool):Array { Context.registerModuleDependency(Std.string(Context.getLocalClass()), url); var pos = Context.currentPos(); From 6539afd4cd20ab47560a39e74efb2682b3d31134 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 11:33:22 +0100 Subject: [PATCH 28/34] Timebase: don't use singleton, instead use statics + observable composition --- src/de/polygonal/core/sys/MainLoop.hx | 29 +----- src/de/polygonal/core/time/Timebase.hx | 129 +++++++++++++------------ src/de/polygonal/core/time/Timeline.hx | 24 ++--- src/de/polygonal/core/tween/Tween.hx | 6 +- 4 files changed, 85 insertions(+), 103 deletions(-) diff --git a/src/de/polygonal/core/sys/MainLoop.hx b/src/de/polygonal/core/sys/MainLoop.hx index cadcf03..8d76847 100644 --- a/src/de/polygonal/core/sys/MainLoop.hx +++ b/src/de/polygonal/core/sys/MainLoop.hx @@ -34,27 +34,20 @@ import de.polygonal.core.sys.Entity; import de.polygonal.core.time.Timebase; import de.polygonal.core.time.TimebaseEvent; import de.polygonal.core.time.Timeline; -import haxe.Timer; class MainLoop extends Entity { - public var tickTimeSeconds:Float; - public var drawTimeSeconds:Float; - public var paused:Bool = true; - var _tickTime:Float; - var _drawTime:Float; - public function new() { super(); - Timebase.get().attach(this); + Timebase.attach(this); } override function onFree():Void { - Timebase.get().detach(this); + Timebase.detach(this); } override public function update(type:Int, source:IObservable, userData:Dynamic):Void @@ -62,51 +55,37 @@ class MainLoop extends Entity switch (type) { case TimebaseEvent.TICK: - tickTimeSeconds = 0; - #if (!no_traces && log) //identify tick step var log = de.polygonal.core.Root.log; if (log != null) for (handler in log.getLogHandler()) - handler.setPrefix(de.polygonal.core.fmt.Sprintf.format('t%03d', [Timebase.get().processedTicks % 1000])); + handler.setPrefix(de.polygonal.core.fmt.Sprintf.format('t%03d', [Timebase.processedTicks % 1000])); #end if (paused) return; - tickTimeSeconds = _tickTime; - _tickTime = Timer.stamp(); - Timeline.get().advance(); commit(); tick(userData); - _tickTime = Timer.stamp() - _tickTime; - #if verbose var s = Entity.printTopologyStats(); if (s != null) de.polygonal.core.Root.debug(s); #end case TimebaseEvent.RENDER: - drawTimeSeconds = 0; - if (paused) return; - drawTimeSeconds = _drawTime; - _drawTime = Timer.stamp(); - #if (!no_traces && log) //identify draw step var log = de.polygonal.core.Root.log; if (log != null) for (handler in log.getLogHandler()) - handler.setPrefix(de.polygonal.core.fmt.Sprintf.format('r%03d', [Timebase.get().processedFrames % 1000])); + handler.setPrefix(de.polygonal.core.fmt.Sprintf.format('r%03d', [Timebase.processedFrames % 1000])); #end draw(userData); - - _drawTime = Timer.stamp() - _drawTime; } } } \ No newline at end of file diff --git a/src/de/polygonal/core/time/Timebase.hx b/src/de/polygonal/core/time/Timebase.hx index 67557fc..6575173 100644 --- a/src/de/polygonal/core/time/Timebase.hx +++ b/src/de/polygonal/core/time/Timebase.hx @@ -29,6 +29,7 @@ */ package de.polygonal.core.time; +import de.polygonal.core.event.IObserver; import de.polygonal.core.event.Observable; import de.polygonal.core.fmt.Sprintf; import de.polygonal.core.math.Mathematics; @@ -36,12 +37,17 @@ import de.polygonal.core.math.Mathematics; /** * A Timebase is a constantly ticking source of time. */ -class Timebase extends Observable +class Timebase { - static var _instance:Timebase = null; - inline public static function get():Timebase + public static function attach(o:IObserver, mask:Int = 0):Void { - return _instance == null ? (_instance = new Timebase()) : _instance; + if (observable == null) init(); + observable.attach(o, mask); + } + + public static function detach(o:IObserver, mask:Int = 0):Void + { + observable.detach(o, mask); } /** @@ -49,7 +55,7 @@ class Timebase extends Observable */ inline public static function secondsToTicks(x:Float):Int { - return M.round(x / get().tickRate); + return M.round(x / tickRate); } /** @@ -57,79 +63,81 @@ class Timebase extends Observable */ inline public static function ticksToSeconds(x:Int):Float { - return x * get().tickRate; + return x * tickRate; } /** * If true, time is consumed using a fixed time step (see Timebase.get().getTickRate()).
    * Default is true. */ - public var useFixedTimeStep:Bool; + public static var useFixedTimeStep:Bool; /** * The update rate measured in seconds per tick.
    * The default update rate is 60 ticks per second (or ~16.6ms per step). */ - public var tickRate(default, null):Float; + public static var tickRate(default, null):Float; /** * Processed time in seconds. */ - public var realTime(default, null):Float; + public static var realTime(default, null):Float; /** * Processed 'virtual' time in seconds (includes scaling). */ - public var gameTime(default, null):Float; + public static var gameTime(default, null):Float; /** * Frame delta time in seconds. */ - public var realTimeDelta(default, null):Float; + public static var realTimeDelta(default, null):Float; /** * 'Virtual' frame delta time in seconds (includes scaling). */ - public var gameTimeDelta(default, null):Float; + public static var gameTimeDelta(default, null):Float; /** * The current time scale.
    * Only positive values are allowed. */ - public var timeScale(default, null):Float; + public static var timeScale(default, null):Float; /** * The total number of processed ticks since the first observer received a TimebaseEvent.TICK update. */ - public var processedTicks(default, null):Int; + public static var processedTicks(default, null):Int; /** * The total number of rendered frames since the first observer received a TimebaseEvent.RENDER update. */ - public var processedFrames(default, null):Int; + public static var processedFrames(default, null):Int; /** * Frames per second (how many frames were rendered in 1 second). */ - public var fps(default, null):Int; + public static var fps(default, null):Int; - var _freezeDelay:Float; - var _halted:Bool; + public static var observable(default, null):Observable; - var _accumulator:Float; - var _accumulatorLimit:Float; + static var _freezeDelay:Float; + static var _halted:Bool; - var _fpsTicks:Int; - var _fpsTime:Float; - var _past:Float; + static var _accumulator:Float; + static var _accumulatorLimit:Float; + + static var _fpsTicks:Int; + static var _fpsTime:Float; + static var _past:Float; #if js - var _requestAnimFrame:Dynamic; + static var _requestAnimFrame:Dynamic; #end - function new() + static function init():Void { - super(100); + observable = new Observable(100); useFixedTimeStep = true; tickRate = 1 / 60; @@ -146,10 +154,10 @@ class Timebase extends Observable _accumulatorLimit = tickRate * 10; _fpsTicks = 0; _fpsTime = 0; - _past = _stamp(); + _past = stamp(); #if (flash || cpp) - flash.Lib.current.addEventListener(flash.events.Event.ENTER_FRAME, _onEnterFrame); + flash.Lib.current.addEventListener(flash.events.Event.ENTER_FRAME, onEnterFrame); #elseif js _requestAnimFrame = function(cb:Dynamic):Void { @@ -173,7 +181,7 @@ class Timebase extends Observable function(x) { w.setTimeout(x, tickRate * 1000); }; f(cb); } - _step(); + step(); #end } @@ -181,15 +189,14 @@ class Timebase extends Observable * Destroys the system by removing all registered observers and explicitly nullifying all references for GC'ing used resources. * The system is automatically reinitialized once an observer is attached. */ - override public function free() + public static function free():Void { - if (_instance == null) return; - _instance = null; - - super.free(); + if (observable == null) return; + observable.free(); + observable = null; #if (flash || cpp) - flash.Lib.current.removeEventListener(flash.events.Event.ENTER_FRAME, _onEnterFrame); + flash.Lib.current.removeEventListener(flash.events.Event.ENTER_FRAME, onEnterFrame); #elseif js _requestAnimFrame = null; #end @@ -199,7 +206,7 @@ class Timebase extends Observable * Sets the update rate measured in ticks per second, e.g. a value of 60 indicates that TimebaseEvent.TICK is fired 60 times per second (or every ~16.6ms). * @param max The accumulator limit in seconds. If omitted, max is set to ten times ticksPerSecond. */ - public function setTickRate(ticksPerSecond:Int, max = -1.):Void + public static function setTickRate(ticksPerSecond:Int, max = -1.):Void { tickRate = 1 / ticksPerSecond; _accumulator = 0; @@ -210,12 +217,12 @@ class Timebase extends Observable * Stops the flow of time.
    * Triggers a TimebaseEvent.HALT update. */ - public function halt():Void + public static function halt():Void { if (!_halted) { _halted = true; - notify(TimebaseEvent.HALT); + observable.notify(TimebaseEvent.HALT); } } @@ -223,14 +230,14 @@ class Timebase extends Observable * Resumes the flow of time.
    * Triggers a TimebaseEvent.RESUME update. */ - public function resume():Void + public static function resume():Void { if (_halted) { _halted = false; _accumulator = 0.; - _past = _stamp(); - notify(TimebaseEvent.RESUME); + _past = stamp(); + observable.notify(TimebaseEvent.RESUME); } } @@ -238,7 +245,7 @@ class Timebase extends Observable * Toggles (halt/resume) the flow of time.
    * Triggers a TimebaseEvent.HALT or em>TimebaseEvent.RESUME update. */ - public function haltToggle():Void + public static function haltToggle():Void { _halted ? resume() : halt(); } @@ -247,17 +254,17 @@ class Timebase extends Observable * Freezes the flow of time for x seconds.
    * Triggers a TimebaseEvent.FREEZE_BEGIN update. */ - public function freeze(x:Float):Void + public static function freeze(x:Float):Void { _freezeDelay = x; _accumulator = 0; - notify(TimebaseEvent.FREEZE_BEGIN); + observable.notify(TimebaseEvent.FREEZE_BEGIN); } /** * Performs a manual update step. */ - public function manualStep():Void + public static function manualStep():Void { realTimeDelta = tickRate; realTime += realTimeDelta; @@ -265,23 +272,23 @@ class Timebase extends Observable gameTimeDelta = tickRate * timeScale; gameTime += gameTimeDelta; - notify(TimebaseEvent.TICK, tickRate); + observable.notify(TimebaseEvent.TICK, tickRate); processedTicks++; - notify(TimebaseEvent.RENDER, 1); + observable.notify(TimebaseEvent.RENDER, 1); processedFrames++; } - function _step() + static function step():Void { #if js if (_requestAnimFrame == null) return; - _requestAnimFrame(_step); + _requestAnimFrame(step); #end if (_halted) return; - var now = _stamp(); + var now = stamp(); var dt = (now - _past); _past = now; @@ -300,11 +307,11 @@ class Timebase extends Observable if (_freezeDelay > 0.) { _freezeDelay -= realTimeDelta; - notify(TimebaseEvent.TICK , 0.); - notify(TimebaseEvent.RENDER, 1.); + observable.notify(TimebaseEvent.TICK , 0.); + observable.notify(TimebaseEvent.RENDER, 1.); if (_freezeDelay <= 0.) - notify(TimebaseEvent.FREEZE_END); + observable.notify(TimebaseEvent.FREEZE_END); return; } @@ -318,7 +325,7 @@ class Timebase extends Observable #if verbose Root.warn(Sprintf.format('accumulator clamped from %.2f to %.2f seconds', [_accumulator, _accumulatorLimit])); #end - notify(TimebaseEvent.CLAMP, _accumulator); + observable.notify(TimebaseEvent.CLAMP, _accumulator); _accumulator = _accumulatorLimit; } @@ -327,12 +334,12 @@ class Timebase extends Observable { _accumulator -= tickRate; gameTime += gameTimeDelta; - notify(TimebaseEvent.TICK, tickRate); + observable.notify(TimebaseEvent.TICK, tickRate); processedTicks++; } var alpha = _accumulator / tickRate; - notify(TimebaseEvent.RENDER, alpha); + observable.notify(TimebaseEvent.RENDER, alpha); processedFrames++; } else @@ -340,19 +347,19 @@ class Timebase extends Observable _accumulator = 0; gameTimeDelta = dt * timeScale; gameTime += gameTimeDelta; - notify(TimebaseEvent.TICK, gameTimeDelta); - notify(TimebaseEvent.RENDER, 1.); + observable.notify(TimebaseEvent.TICK, gameTimeDelta); + observable.notify(TimebaseEvent.RENDER, 1.); } } #if (flash || cpp) - function _onEnterFrame(e:flash.events.Event):Void + static function onEnterFrame(e:flash.events.Event):Void { - _step(); + step(); } #end - inline function _stamp():Float + inline static function stamp():Float { return #if flash diff --git a/src/de/polygonal/core/time/Timeline.hx b/src/de/polygonal/core/time/Timeline.hx index 118a427..1b4ed7f 100644 --- a/src/de/polygonal/core/time/Timeline.hx +++ b/src/de/polygonal/core/time/Timeline.hx @@ -34,8 +34,8 @@ import de.polygonal.core.event.IObserver; import de.polygonal.core.event.Observable; import de.polygonal.core.fmt.Sprintf; import de.polygonal.core.math.Mathematics; -import de.polygonal.core.util.Assert; import de.polygonal.core.time.Timeline; +import de.polygonal.core.util.Assert; import de.polygonal.ds.ArrayedQueue; import de.polygonal.ds.Cloneable; import de.polygonal.ds.Collection; @@ -74,12 +74,11 @@ class Timeline extends Observable, implements IObserver public static function bindToTimebase(x:Bool):Void { if (x) - Timebase.get().attach(Timeline.get(), TimebaseEvent.TICK); + Timebase.attach(Timeline.get(), TimebaseEvent.TICK); else - Timebase.get().detach(Timeline.get()); + Timebase.detach(Timeline.get()); } - var _timebase:Timebase; var _idCounter:Int; var _currTick:Int; @@ -102,9 +101,8 @@ class Timeline extends Observable, implements IObserver { reserve(100); - _timebase = Timebase.get(); _idCounter = 0; - _currTick = _timebase.processedTicks; + _currTick = Timebase.processedTicks; _currSubTick = 0; _currInterval = null; _runningIntervals = new DLL(); @@ -130,13 +128,12 @@ class Timeline extends Observable, implements IObserver { for (i in _all) for (j in i) j.onCancel(); - _timebase.detach(this); + Timebase.detach(this); _runningIntervals.free(); _pendingAdditions.free(); _intervalHeap.free(); _intervalPool.free(); - _timebase = null; _runningIntervals = null; _pendingAdditions = null; _intervalHeap = null; @@ -165,9 +162,9 @@ class Timeline extends Observable, implements IObserver D.assert(repeatInterval >= 0, 'repeatInterval >= 0'); if (_tickRate == 0) - _tickRate = _timebase.tickRate; + _tickRate = Timebase.tickRate; else - if (_timebase.tickRate != _tickRate) + if (Timebase.tickRate != _tickRate) { var c = _pendingAdditions.size() + _intervalHeap.size() + _runningIntervals.size(); D.assert(c == 0, 'tick rate changed'); @@ -177,7 +174,7 @@ class Timeline extends Observable, implements IObserver if (repeatCount != 0 && repeatInterval == .0) repeatInterval = delay; //use delay as interval - var delayTicks = M.round(delay / _timebase.tickRate); + var delayTicks = M.round(delay / Timebase.tickRate); var ageTicks = _currTick + delayTicks; var interval = _getInterval(); @@ -204,7 +201,6 @@ class Timeline extends Observable, implements IObserver public function cancel(id:Int):Bool { if (id < 0) return false; - for (collection in _all) { for (interval in collection) @@ -325,7 +321,7 @@ class Timeline extends Observable, implements IObserver */ public function advance():Void { - _currTick = _timebase.processedTicks; + _currTick = Timebase.processedTicks; _currSubTick = 0; var interval, node; @@ -445,7 +441,7 @@ class Timeline extends Observable, implements IObserver if (_intervalPool.isEmpty()) { #if debug - Root.log.warn('TimeInterval pool exhausted'); + //Root.log.warn('TimeInterval pool exhausted'); #end return new TimeInterval(this); } diff --git a/src/de/polygonal/core/tween/Tween.hx b/src/de/polygonal/core/tween/Tween.hx index 12189b3..b13543a 100644 --- a/src/de/polygonal/core/tween/Tween.hx +++ b/src/de/polygonal/core/tween/Tween.hx @@ -198,7 +198,7 @@ class Tween implements IObservable, implements IObserver, implements TimelineLis if (_activeTweens != null) _activeTweens.remove(this); _timeline.detach(this); _timeline.cancel(_id); - if (_interpolate) Timebase.get().detach(this); + if (_interpolate) Timebase.detach(this); if (_key != null && _map != null) _map.remove(_key); if (_observable != null) _observable.free(); _id = -1; @@ -305,7 +305,7 @@ class Tween implements IObservable, implements IObserver, implements TimelineLis { _timeline.cancel(_id); _id = 1; - if (_interpolate) Timebase.get().detach(this); + if (_interpolate) Timebase.detach(this); return this; } @@ -338,7 +338,7 @@ class Tween implements IObservable, implements IObserver, implements TimelineLis { if (_activeTweens == null) _activeTweens = new DA(); _activeTweens.pushBack(this); - if (_interpolate) Timebase.get().attach(this, TimebaseEvent.RENDER); + if (_interpolate) Timebase.attach(this, TimebaseEvent.RENDER); _a = _b = _min; if (!_interpolate) _target.set(_b); notify(TweenEvent.START, _min); From bd5edef8cc35869635611373e76086ba4c8c96f2 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 11:34:22 +0100 Subject: [PATCH 29/34] haxe3 fix --- src/de/polygonal/core/util/Assert.hx | 8 ++------ src/de/polygonal/core/util/StringConstants.hx | 7 ++++--- src/de/polygonal/core/util/Version.hx | 9 +++++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/de/polygonal/core/util/Assert.hx b/src/de/polygonal/core/util/Assert.hx index ce19b42..c7ccb31 100644 --- a/src/de/polygonal/core/util/Assert.hx +++ b/src/de/polygonal/core/util/Assert.hx @@ -45,14 +45,10 @@ class Assert var error = false; - #if haxe_211 + #if haxe3 switch (Context.typeof(predicate)) { - #if haxe3 - case TAbstract: - #else - case TAbstract(a, b): - #end + case TAbstract(_, _): default: error = true; } diff --git a/src/de/polygonal/core/util/StringConstants.hx b/src/de/polygonal/core/util/StringConstants.hx index 0a82de2..16ae3a2 100644 --- a/src/de/polygonal/core/util/StringConstants.hx +++ b/src/de/polygonal/core/util/StringConstants.hx @@ -34,7 +34,8 @@ import haxe.macro.Expr; class StringConstants { - @:macro public static function build(e:Expr):Array + #if haxe3 macro #else @:macro #end + public static function build(e:Expr):Array { var pos = Context.currentPos(); var fields = Context.getBuildFields(); @@ -49,8 +50,8 @@ class StringConstants case EConst(c): switch (c) { - case CType(c), CIdent(c): - fields.push({name: c, doc: null, meta: [], access: [AStatic, APublic, AInline], kind: FVar(TPath({pack: [], name: 'String', params: [], sub: null}), {expr: EConst(CString(c)), pos: pos}), pos: pos}); + case CIdent(s): + fields.push({name: s, doc: null, meta: [], access: [AStatic, APublic, AInline], kind: FVar(TPath({pack: [], name: 'String', params: [], sub: null}), {expr: EConst(CString(s)), pos: pos}), pos: pos}); default: Context.error('unsupported declaration', pos); } default: Context.error('unsupported declaration', pos); diff --git a/src/de/polygonal/core/util/Version.hx b/src/de/polygonal/core/util/Version.hx index c605f8d..5b9e2e4 100644 --- a/src/de/polygonal/core/util/Version.hx +++ b/src/de/polygonal/core/util/Version.hx @@ -34,7 +34,8 @@ import haxe.macro.Expr; class Version { - @:macro public static function build(url:String):Array + #if haxe3 macro #else @:macro #end + public static function build(url:String):Array { Context.registerModuleDependency(Std.string(Context.getLocalClass()), url); @@ -47,7 +48,7 @@ class Version var s; try { - s = neko.io.File.getContent(url); + s = sys.io.File.getContent(url); var v = s.split('.'); major = Std.parseInt(v[0]); @@ -65,10 +66,10 @@ class Version s = '0.0.0'; } - var fout = neko.io.File.write(url, false); + var fout = sys.io.File.write(url, false); fout.close(); - var fout = neko.io.File.append(url, false); + var fout = sys.io.File.append(url, false); fout.writeString(s); fout.close(); From c16e6f6a6c14cbe378e8d581642aafd915ec177f Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 19:22:24 +0100 Subject: [PATCH 30/34] use 32 bits for neko 2 --- src/de/polygonal/core/math/Limits.hx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/de/polygonal/core/math/Limits.hx b/src/de/polygonal/core/math/Limits.hx index 5da7e86..46ee2aa 100644 --- a/src/de/polygonal/core/math/Limits.hx +++ b/src/de/polygonal/core/math/Limits.hx @@ -103,7 +103,9 @@ class Limits * Equals 31 when targeting neko, otherwise 32. */ inline public static var INT_BITS = - #if neko + #if (neko && neko_v2) + 32; + #elseif neko 31; #else 32; From 8efbc4bd69de61f99da67164019ee96601623d96 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 20:34:20 +0100 Subject: [PATCH 31/34] entity system: -register entities with global manager to send messages via Entity.sendMsg -faster Entity.is() for flash skip try..catch -if a removed entity is added again, just update flags --- src/de/polygonal/core/sys/Entity.hx | 47 ++++++++++++++---- src/de/polygonal/core/sys/EntityManager.hx | 58 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 src/de/polygonal/core/sys/EntityManager.hx diff --git a/src/de/polygonal/core/sys/Entity.hx b/src/de/polygonal/core/sys/Entity.hx index ab8f92a..ac99b06 100644 --- a/src/de/polygonal/core/sys/Entity.hx +++ b/src/de/polygonal/core/sys/Entity.hx @@ -43,6 +43,7 @@ import de.polygonal.ds.TreeNode; import de.polygonal.core.util.Assert; //descendant: ignore ghosts +//onAddChild, onRemoveChild @:build(de.polygonal.core.sys.EntityType.gen()) @:autoBuild(de.polygonal.core.sys.EntityType.gen()) @@ -213,6 +214,8 @@ class Entity implements IObserver, implements IObservable, implements Hashable s = Type.getSuperClass(s); } } + + EntityManager.registerEntity(this); } /** @@ -358,16 +361,17 @@ class Entity implements IObserver, implements IObservable, implements Hashable return; } - //early out + //nothing changed - early out if (!isDirty()) { clrf(BIT_INITIATOR | BIT_RECOMMIT); return; } - //lock + //lock; this node carries out all changes setf(BIT_INITIATOR); + //preorder traversal: for all nodes: replace PENDING bit with PROCESS bit prepareAdditions(); registerHi(); registerLo(); @@ -439,6 +443,15 @@ class Entity implements IObserver, implements IObservable, implements Hashable return c; } + if (c.hasf(BIT_PENDING_REMOVE)) + { + //marked for removal, just update flags + c.clrf(BIT_PENDING_REMOVE); + c.setf(BIT_PENDING_ADD); + if (c.priority != priority) c.priority = priority; + return c; + } + #if debug D.assert(!treeNode.contains(c), 'given entity is a child of this entity'); #end @@ -804,7 +817,11 @@ class Entity implements IObserver, implements IObservable, implements Hashable */ inline public function is(x:Class):Bool { + #if flash + return untyped __is__(this, x); + #else return Std.is(this, x); + #end } /** @@ -820,7 +837,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable return false; } - public function sleep(deep = false) + public function sleep(deep = false):Void { clrf(BIT_TICK_BEFORE_SLEEP | BIT_DRAW_BEFORE_SLEEP); if (hasf(BIT_TICK)) setf(BIT_TICK_BEFORE_SLEEP); @@ -832,7 +849,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable clrf(BIT_TICK | BIT_DRAW); } - public function wakeup(deep = false) + public function wakeup(deep = false):Void { if (hasf(BIT_TICK_BEFORE_SLEEP)) setf(BIT_TICK); if (hasf(BIT_DRAW_BEFORE_SLEEP)) setf(BIT_DRAW); @@ -877,6 +894,16 @@ class Entity implements IObserver, implements IObservable, implements Hashable public function update(type:Int, source:IObservable, userData:Dynamic):Void {} + public function sendMsg(receiverId:String, msg:String, userData:Dynamic = null):Void + { + EntityManager.sendMsg(this, receiverId, msg, userData); + } + + /** + * Hook; invoked after sender has sent a message msg to this entity, passing userData. + */ + public function onMsg(msg:String, sender:Entity, userData:Dynamic):Void {} + /** * Hook; invoked by free() on all children, * giving each one the opportunity to perform some cleanup. @@ -933,11 +960,6 @@ class Entity implements IObserver, implements IObservable, implements Hashable */ function onDraw(alpha:Float, parent:Entity):Void {} - /** - * Hook; invoked after sender has sent a message msg to this entity, passing userData. - */ - function onMsg(msg:String, sender:Entity, userData:Dynamic):Void {} - function prepareAdditions():Void { //preorder: change BIT_PENDING_ADD to BIT_PROCESS @@ -979,6 +1001,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable function propagateOnAddAncestor(x:Entity):Void { + //only for non-pending nodes if (getf(BIT_PENDING | BIT_ADD_ANCESTOR) == BIT_ADD_ANCESTOR) { #if verbose @@ -988,9 +1011,9 @@ class Entity implements IObserver, implements IObservable, implements Hashable onAddAncestor(x); } - //propagate to children? if (hasf(BIT_ADD_ANCESTOR)) { + //call onAddAncestor() on all descendants var n = treeNode.children; while (n != null) { @@ -1351,6 +1374,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable { var c = e._c; e.onTick(timeDelta, parent); + if (c < e._c) e._c--; else @@ -1419,6 +1443,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable } e.treeNode = null; e.onFree(); + EntityManager.unregisterEntity(e); return true; }); tmp.free(); @@ -1445,7 +1470,7 @@ class Entity implements IObserver, implements IObservable, implements Hashable #end } - inline function isGhost() + inline function isGhost():Bool { return hasf(BIT_PENDING | BIT_COMMIT_SUICIDE); } diff --git a/src/de/polygonal/core/sys/EntityManager.hx b/src/de/polygonal/core/sys/EntityManager.hx new file mode 100644 index 0000000..b9bef3e --- /dev/null +++ b/src/de/polygonal/core/sys/EntityManager.hx @@ -0,0 +1,58 @@ +package de.polygonal.core.sys; + +import de.polygonal.core.util.Assert; + +class EntityManager +{ + static var _initialized = false; + static var _keyLookup:Hash = null; + static var _nextKey = 0; + static var _scratchArr:Array = null; + + static var _entitiesById:IntHash> = null; + + public static function registerEntity(e:Entity):Void + { + if (!_initialized) + { + _initialized = true; + _entitiesById = new IntHash(); + _keyLookup = new Hash(); + _scratchArr = []; + } + + if (_keyLookup.exists(e.id)) + { + //resolve integer key from entity id + var key = _keyLookup.get(e.id); + _entitiesById.get(key).push(e); + } + else + { + //generate integer key for entity id + var key = ++_nextKey; + _keyLookup.set(e.id, key); + _entitiesById.set(key, [e]); + } + } + + public static function unregisterEntity(e:Entity):Void + { + if (!_keyLookup.exists(e.id)) return; + var key = _keyLookup.get(e.id); + var a = _entitiesById.get(key); + var success = a.remove(e); + if (!success) throw 'error unregistering entity'; + } + + public static function sendMsg(sender:Entity, receiverId:String, msg:String, userData:Dynamic):Void + { + #if debug + D.assert(_keyLookup.exists(receiverId), 'entity is not registered'); + #end + + var key = _keyLookup.get(receiverId); + for (i in _entitiesById.get(key)) + i.onMsg(msg, sender, userData); + } +} \ No newline at end of file From 12c6f68ae42847b4f7921959150eb0fd1f191764 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 20:49:47 +0100 Subject: [PATCH 32/34] wrap log in #if log --- src/de/polygonal/core/Root.hx | 103 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/de/polygonal/core/Root.hx b/src/de/polygonal/core/Root.hx index e9ddfb2..516edbe 100644 --- a/src/de/polygonal/core/Root.hx +++ b/src/de/polygonal/core/Root.hx @@ -30,10 +30,7 @@ package de.polygonal.core; import de.polygonal.core.fmt.Sprintf; -import de.polygonal.core.log.Log; -import de.polygonal.core.log.LogHandler; import de.polygonal.core.util.Assert; -import haxe.PosInfos; /** *

    The root of an application.

    @@ -43,7 +40,9 @@ class Root /** * The root logger; initialized when calling Root.init(). */ - public static var log(default, null):Log = null; + #if log + public static var log(default, null):de.polygonal.core.log.Log = null; + #end /** * Short for Root.log.debug().
    @@ -56,9 +55,9 @@ class Root inline public static function debug(x:Dynamic):Void { #if log - #if debug - D.assert(log != null, 'call Root.init() first'); - #end + #if debug + D.assert(log != null, 'call Root.initLog() first'); + #end log.debug(x); #end } @@ -74,9 +73,9 @@ class Root inline public static function info(x:Dynamic):Void { #if log - #if debug - D.assert(log != null, 'call Root.init() first'); - #end + #if debug + D.assert(log != null, 'call Root.initLog() first'); + #end log.info(x); #end } @@ -92,9 +91,9 @@ class Root inline public static function warn(x:Dynamic):Void { #if log - #if debug - D.assert(log != null, 'call Root.init() first'); - #end + #if debug + D.assert(log != null, 'call Root.initLog() first'); + #end log.warn(x); #end } @@ -110,9 +109,9 @@ class Root inline public static function error(x:Dynamic):Void { #if log - #if debug - D.assert(log != null, 'call Root.init() first'); - #end + #if debug + D.assert(log != null, 'call Root.initLog() first'); + #end log.error(x); #end } @@ -147,51 +146,49 @@ class Root * @param handlers additional log handler objects that get attached to Root.log upon initialization. * @param keepNativeTrace if true, do not override native trace output. Default is false. */ - public static function init(handlers:Array = null, keepNativeTrace = false) + #if log + public static function initLog(handlers:Array = null, keepNativeTrace = false) + #else + public static function initLog(handlers:Array = null, keepNativeTrace = false) + #end { #if !no_traces - #if log - var nativeTrace = function(v:Dynamic, ?infos:PosInfos) {}; - if (keepNativeTrace) nativeTrace = haxe.Log.trace; - - Log.globalHandler = []; - #if flash - Log.globalHandler.push(new de.polygonal.core.log.handler.TraceHandler()); - #elseif cpp - Log.globalHandler.push(new de.polygonal.core.log.handler.FileHandler('hxcpp_log.txt')); - #elseif js - Log.globalHandler.push(new de.polygonal.core.log.handler.ConsoleHandler()); - #end - - if (handlers != null) - { - for (handler in handlers) - Log.globalHandler.push(handler); - } - - log = Log.getLog(Root); - - haxe.Log.trace = function(x:Dynamic, ?posInfos:PosInfos) - { - if (Std.is(x, String)) + #if log + var nativeTrace = function(v:Dynamic, ?infos:haxe.PosInfos) {}; + if (keepNativeTrace) nativeTrace = haxe.Log.trace; + + de.polygonal.core.log.Log.globalHandler = []; + de.polygonal.core.log.Log.globalHandler.push( + #if flash + new de.polygonal.core.log.handler.TraceHandler() + #elseif cpp + new de.polygonal.core.log.handler.FileHandler('hxcpp_log.txt') + #elseif js + new de.polygonal.core.log.handler.ConsoleHandler() + #end + ); + + if (handlers != null) + { + for (handler in handlers) + de.polygonal.core.log.Log.globalHandler.push(handler); + } + log = de.polygonal.core.log.Log.getLog(Root); + + haxe.Log.trace = function(x:Dynamic, ?posInfos:haxe.PosInfos) { - var s:String = x; if (posInfos.customParams != null) { - if (~/%(([+\- #0])*)?((\d+)|(\*))?(\.(\d?|(\*)))?[hlL]?[bcdieEfgGosuxX]/g.match(s)) - s = Sprintf.format(s, posInfos.customParams); + if (~/%(([+\- #0])*)?((\d+)|(\*))?(\.(\d?|(\*)))?[hlL]?[bcdieEfgGosuxX]/g.match(x)) + x = Sprintf.format(Std.string(x), posInfos.customParams); else - s += ',' + posInfos.customParams.join(','); + x = x + ',' + posInfos.customParams.join(','); } - - x = s; + Root.log.debug(x, posInfos); + nativeTrace(x, posInfos); } - - Root.log.debug(x, posInfos); - nativeTrace(x, posInfos); - } - trace('log initialized.'); - #end + trace('log initialized.'); + #end #end } } \ No newline at end of file From 831193946d9a53bc0727d0d3434b8a1607941911 Mon Sep 17 00:00:00 2001 From: Michael Baczynski Date: Sun, 27 Jan 2013 20:51:07 +0100 Subject: [PATCH 33/34] update README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 527a410..a3bdfc3 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,14 @@ If you want to test the latest beta build, you should pull the dev branch and ad * modified: change LogMessage.data type to Dynamic * added: ClassUtil class + * added: Mathematics.int() + * fixed: EntityType + compilation server + * modified: Observable.mute -> muteType, unmute -> unmuteType (name clash with Entity) + * added: Mat33.setRotateX(), setRotateY() + * fixed: Timebase.gameTime + * fixed: some minor fixes for -D haxe3 + * modified: restore draw/tick state when calling Entity.wakeup() after Entity.sleep() + * Timebase: use statics instead of singleton pattern ### 1.01 (released 2012-11-15) From 235bf44db994bc948b7869742adadc03ee35de45 Mon Sep 17 00:00:00 2001 From: profelis Date: Wed, 30 Jan 2013 16:38:15 +0200 Subject: [PATCH 34/34] ie10 console.debug fix --- src/de/polygonal/core/log/handler/ConsoleHandler.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/polygonal/core/log/handler/ConsoleHandler.hx b/src/de/polygonal/core/log/handler/ConsoleHandler.hx index 0360bb0..a53fe55 100644 --- a/src/de/polygonal/core/log/handler/ConsoleHandler.hx +++ b/src/de/polygonal/core/log/handler/ConsoleHandler.hx @@ -61,7 +61,7 @@ class ConsoleHandler extends LogHandler var levelName = LogLevel.getName(M.min(_message.outputLevel, LogLevel.ERROR)).toLowerCase(); #if js - untyped console[levelName](message); + untyped if (console[levelName] != null) console[levelName](message); else console.log(message); #elseif flash if (flash.external.ExternalInterface.available) flash.external.ExternalInterface.call('console.' + levelName, message);