假设我们有一个Local类:
class Local {
static inline public var logLevel:Int = 3;
}
还有一些功能:
Tool.debug(s:String) // compiled if logLevel >= 0
Tool.moreinfo(s:String)// compiled if logLevel >= 1
Tool.info(s:String) // compiled if logLevel >= 2
Tool.trace(s:String) // compiled if logLevel >= 3
Tool.warn(s:String) // compiled if logLevel >= 4
Tool.err(s:String) // compiled if logLevel >= 5
我们可以使用-D和代码中的一些#if来实现这一点。
然而,这意味着始终修改hxml文件。即使只是一个值,这对我来说并不理想,因为我的所有配置都在我的Local类中。
如果我们使用简单的if()来测试值,那么代码会随着所有if和字符串变大,即使它从未使用过(因为logLevel意味着'常量')。
是否可以使用宏来克服这两个问题?
答案 0 :(得分:4)
修改强>
如果用例如此简单,那么@ stroncium的答案会更容易:使所有内联内联,编译器将进行优化,不需要宏。请参阅http://try.haxe.org/#C44Ec,并查看已编译的JS。假设Local
是普通课程(您手动编写,不用宏或其他任何东西构建),那么您可以在宏调用中访问Local.logLevel
。
这样的一些代码可以使用
class Tool {
public static macro function debug( s:ExprOf<String> ):Expr {
if ( Local.logLevel>=0 ) {
// Insert a trace statement into our code.
// You could insert any other kind of statement or { block; of; statements; } also.
return macro trace( $s );
}
else {
// You need to return an expression of some kind.
// This is the equivalent of writing the line "null;" - it does nothing whatsoever.
return macro null;
}
}
}
或者同样的事情,写得更简洁一点,以及所有功能:
class Tool {
public static macro function debug( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=0 ) macro trace( "debug: " + $s );
else return macro null;
}
public static macro function moreInfo( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=1 ) macro trace( "moreInfo: " + $s );
else return macro null;
}
public static macro function info( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=2 ) macro trace( "info: " + $s );
else return macro null;
}
public static macro function trace( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=3 ) macro trace( "trace: " + $s );
else return macro null;
}
public static macro function warn( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=4 ) macro trace( "warn: " + $s );
else return macro null;
}
public static macro function err( s:ExprOf<String> ):Expr {
return
if ( Local.logLevel>=5 ) macro trace( "err: " + $s );
else return macro null;
}
}
答案 1 :(得分:2)
您可以直接设置日志记录功能。编译器将内联它们并在编译时检查条件,删除无法执行的分支。
答案 2 :(得分:0)
制作源文件或配置文件的风格很差,因此每次编译时都需要编辑。
如果您使用像FlashDevelop这样的IDE,那么问题就会消失,因为您可以在编译时传入参数。毕竟,这就是IDE的用途。
我将在这里使用FD作为示例,但您可以针对您使用的任何IDE进行调整。
FlashDevelop在顶部有两个下拉列表:配置和目标。例如,在我的项目中,我有通常的两个配置(Debug,Release)和三个目标(standalone,webalone,webinline)。您可以拥有“log0”,“log1”等目标。
[不幸的是,FlashDevelop目前有一个错误,它不会在会话之间存储配置名称,所以我经常在编译之前输入我想要的那个。]
在项目属性中 - &gt;预建命令行,我把:
haxe.exe $(BuildConfig).hxml $(TargetBuild).hxml $(ProjectName).hxml
您可以为haxe构建指定多个hxml文件,因此您可以拥有一个名为log1.hxml,log2.hxml等的集合,其中只包含您不断更改的那一行。
你可以离开它。它完成了你所要求的一切。您甚至可以将“target”字段用作“loglevel”字段,只需输入一个数字。您的编译命令行可能看起来像:
haxe.exe $(ProjectName).hxml -D loglevel=$(TargetBuild)
就个人而言,为了进行调试,我需要为每个目标使用不同的调试环境(浏览器,flash播放器等),因此我将调试操作作为批处理文件:
"D:\svn\src\haxe\debug.bat" $(TargetBuild) "$(OutputFile)"
该批处理文件包含:
@echo off
goto %1%
goto end
:webinline
start "" "D:\svn\src\haxe\bin\index-flashvar.html"
goto end
:webalone
start "" "D:\svn\src\haxe\bin\index.html"
goto end
:standalone
start "" "D:\Program Files (x86)\FlashDevelop\Tools\flexlibs\runtimes\player\11.9\win\FlashPlayerDebugger.exe" %2%
goto end
:end
简而言之:每次编译时,使用IDE的强大功能从简单的下拉列表中执行所需的操作。