diff --git a/hGameTest/project.xml b/hGameTest/project.xml
index e52a3878..19b2ff25 100644
--- a/hGameTest/project.xml
+++ b/hGameTest/project.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/hGameTest/src/engine/ConVar.hx b/hGameTest/src/engine/ConVar.hx
index c5987b62..8eaaa370 100644
--- a/hGameTest/src/engine/ConVar.hx
+++ b/hGameTest/src/engine/ConVar.hx
@@ -67,6 +67,10 @@ class ConVar{
}
public static inline function setCVar(_name:String, _value:Dynamic):Void
{
+ if(CVarMap == null){
+ Console.devMsg("CVarMap is null");
+ return;
+ }
var cv = getCVar(_name);
if(cv != null){
switch(cv.type){
diff --git a/hGameTest/src/engine/ConVars_Engine.hx b/hGameTest/src/engine/ConVars_Engine.hx
index 8b86f665..8ff62f79 100644
--- a/hGameTest/src/engine/ConVars_Engine.hx
+++ b/hGameTest/src/engine/ConVars_Engine.hx
@@ -6,14 +6,14 @@ import engine.typedefs.console.CVar;
import engine.typedefs.console.CCmd;
import engine.enums.console.CVarType;
import engine.enums.console.CVarFlag;
-import engine.macros.CCmdDecorator;
+import engine.macros.ConVarDecorators;
import game.ui.console.Console;
@:keep
// @:build(engine.macros.CCmdDecorator.build()) // No longer needed because we added the build macro to the project.xml
class ConVars_Engine {
- @:ConCmd("list")
+ @:concmd("list")
public static function listCommands(args:Array) {
var CVarMap:Map = ConVar.getCVarMap();
var keys:Array = ConVar.getCVarNames();
@@ -27,7 +27,7 @@ class ConVars_Engine {
}
}
- @:ConCmd("test")
+ @:concmd("test")
public static function testCommand() {
// Command implementation
trace("Test Output");
diff --git a/hGameTest/src/engine/enums/console/CVarFlag.hx b/hGameTest/src/engine/enums/console/CVarFlag.hx
index 56ee8e16..11426847 100644
--- a/hGameTest/src/engine/enums/console/CVarFlag.hx
+++ b/hGameTest/src/engine/enums/console/CVarFlag.hx
@@ -1,6 +1,7 @@
package engine.enums.console;
enum CVarFlag{
+ FCVAR_NONE;
FCVAR_ARCHIVE;
FCVAR_CHEAT;
FVCAR_REPLICATED;
diff --git a/hGameTest/src/engine/macros/CCmdDecorator.hx b/hGameTest/src/engine/macros/CCmdDecorator.hx
deleted file mode 100644
index 129f9878..00000000
--- a/hGameTest/src/engine/macros/CCmdDecorator.hx
+++ /dev/null
@@ -1,46 +0,0 @@
-package engine.macros;
-
-import haxe.macro.Expr;
-import haxe.macro.Context;
-
-class CCmdDecorator {
- public static macro function build():Array {
- var fields = Context.getBuildFields();
- var pos = Context.currentPos();
-
- for (field in fields) {
- var meta = field.meta != null ? Lambda.find(field.meta, function(m) return m.name == ":ConCMD") : null;
- if (meta != null) {
- trace(meta);
- switch field.kind {
- case FFun(f):
- var name = meta.params.length > 0
- ? switch(meta.params[0].expr) {
- case EConst(CString(s)): s;
- case _: field.name;
- }
- : field.name;
-
- // Create a static initializer field
- var initField = {
- name: "__init__" + name,
- access: [AStatic, APrivate],
- kind: FVar(null, macro {
- engine.ConVar.registerCCmd($v{name}, function(args:Array) {
- ${f.expr};
- });
- }),
- pos: pos,
- doc: null,
- meta: []
- };
-
- // Add the initializer field
- fields.push(initField);
- case _:
- }
- }
- }
- return fields;
- }
-}
\ No newline at end of file
diff --git a/hGameTest/src/engine/macros/ConVarDecorators.hx b/hGameTest/src/engine/macros/ConVarDecorators.hx
new file mode 100644
index 00000000..131a5160
--- /dev/null
+++ b/hGameTest/src/engine/macros/ConVarDecorators.hx
@@ -0,0 +1,136 @@
+package engine.macros;
+
+import haxe.macro.Expr;
+import haxe.macro.Context;
+import haxe.macro.Expr.Field;
+
+private typedef CVarMetadata = {
+ name: Expr,
+ type: String,
+ value: Expr,
+ flags: Expr,
+ help: Expr,
+ ?callback: Expr
+}
+
+class ConVarDecorators {
+ static function extractCVarMetadata(params:Array):CVarMetadata {
+ var metadata:CVarMetadata = null;
+
+ switch (params[0].expr) {
+ case EObjectDecl(fields):
+ metadata = {
+ name: macro "",
+ type: "CString",
+ value: macro 0,
+ flags: macro "FCVAR_NONE",
+ help: macro "",
+ callback: macro null
+ };
+
+ for (field in fields) {
+ switch (field.field) {
+ case "name": metadata.name = field.expr;
+ case "type": metadata.type = switch(field.expr.expr) {
+ case EConst(CString(s)): s;
+ case _: "CString";
+ }
+ case "value": metadata.value = field.expr;
+ case "flags": metadata.flags = field.expr;
+ case "help": metadata.help = field.expr;
+ case "callback": metadata.callback = field.expr;
+ case _:
+ }
+ }
+ case _:
+ }
+ return metadata;
+ }
+
+ public static macro function build():Array {
+ var fields = Context.getBuildFields();
+ var pos = Context.currentPos();
+
+ for (field in fields) {
+ var cmdMeta = field.meta != null ? Lambda.find(field.meta, function(m) return m.name == ":concmd") : null;
+ var cvarMeta = field.meta != null ? Lambda.find(field.meta, function(m) return m.name == ":convar") : null;
+
+ if (cmdMeta != null) {
+ switch field.kind {
+ case FFun(f):
+ var name = cmdMeta.params.length > 0 ? switch (cmdMeta.params[0].expr) {
+ case EConst(CString(s)): s;
+ case _: field.name;
+ } : field.name;
+
+ var fnExpr = macro function(args:Array) ${f.expr};
+
+ var initExpr = macro {
+ var cmd = engine.ConVar.registerCCmd($v{name}, $fnExpr);
+ cmd; // Return the command reference
+ };
+
+ // Generate a safe initialization field name
+ var initName = "__init__" + name;
+
+ fields.push({
+ name: initName,
+ access: [AStatic],
+ kind: FVar(null, initExpr),
+ pos: pos,
+ doc: null,
+ meta: [{
+ name: ":keep",
+ params: [],
+ pos: pos
+ }]
+ });
+ case _:
+ }
+ } else if (cvarMeta != null && cvarMeta.params.length > 0) {
+ switch (field.kind) {
+ case FVar(t, e):
+ var meta = extractCVarMetadata(cvarMeta.params);
+ if (meta == null) continue;
+
+ // Extract name from metadata expression
+ var cvarName = switch(meta.name.expr) {
+ case EConst(CString(s)): s;
+ case _: field.name;
+ };
+
+ var initExpr = macro {
+ var cvar = $i{field.name} = engine.ConVar.registerCVar(
+ ${meta.name},
+ ${Context.parse('engine.enums.console.CVarType.' + meta.type, pos)},
+ ${meta.value},
+ ${Context.parse('engine.enums.console.CVarFlag.' + switch(meta.flags.expr) {
+ case EConst(CString(s)): s;
+ case _: "FCVAR_NONE";
+ }, pos)},
+ ${meta.help},
+ ${meta.callback ?? macro null}
+ );
+ trace($v{"Registered CVar: "} + $e{meta.name});
+ cvar; // Return the CVar reference
+ };
+
+ fields.push({
+ name: "__init__" + cvarName,
+ access: [AStatic],
+ kind: FVar(null, initExpr),
+ pos: pos,
+ doc: null,
+ meta: [{
+ name: ":keep",
+ params: [],
+ pos: pos
+ }]
+ });
+ case _:
+ }
+ }
+ }
+ return fields;
+ }
+}
diff --git a/hGameTest/src/game/Input.hx b/hGameTest/src/game/Input.hx
index 1e1cdf6c..079431ca 100644
--- a/hGameTest/src/game/Input.hx
+++ b/hGameTest/src/game/Input.hx
@@ -18,7 +18,19 @@ class Input{
public static var keys:Map = [];
public static var keysLast:Map = [];
public static var bindMap:Map = ["~" => "toggleconsole", "\\" => "toggleconsole", "1" => "echo kak", "2" => "+attack"];
- public static var cv_debugKeys = ConVar.registerCVar("cl_debuginput", CInt, 0, null, "print debug messages related to input to console", null, false, true, 0, 0, false);
+ @:convar({
+ name: "cl_debuginput",
+ type: CVarType.CInt,
+ value: 0,
+ flags: CVarFlag.None,
+ help: "print debug messages related to input to console",
+ callback: function() {
+ trace("Debug input changed");
+ }
+ })
+ public static var cv_debugKeys:CVar;
+
+ // public static var cv_debugKeys = ConVar.registerCVar("cl_debuginput", CInt, 0, null, "print debug messages related to input to console", null, false, true, 0, 0, false);
public static var keyNameMap:Map = [
Kb.HOME => "HOME", Kb.END => "END", Kb.INSERT => "INSERT", Kb.DELETE => "DELETE", Kb.PAGE_UP => "PGUP", Kb.PAGE_DOWN => "PGDN",
Kb.ESCAPE => "ESC", Kb.F1 => "F1", Kb.F2 => "F2", Kb.F3 => "F3", Kb.F4 => "F4", Kb.F5 => "F5",
diff --git a/hGameTest/src/game/video/Mode.hx b/hGameTest/src/game/video/Mode.hx
index 54afc3ed..42a64551 100644
--- a/hGameTest/src/game/video/Mode.hx
+++ b/hGameTest/src/game/video/Mode.hx
@@ -15,7 +15,7 @@ class Mode
public static function setVideoMode(width:Int, height:Int, fs:Int = null){
getWindow().resize(width,height);
}
- @:ConCmd("mat_setvideomode")
+ @:concmd("mat_setvideomode")
public static function cCmdMatSetVideoMode(args:Array){
Mode.setVideoMode(Std.parseInt(args[0]), Std.parseInt(args[1]), Std.parseInt(args[2]));
}