Skip to content

Commit 72be654

Browse files
committed
buildConst: support init exprs, safe load
1 parent dc6f41e commit 72be654

File tree

1 file changed

+65
-37
lines changed

1 file changed

+65
-37
lines changed

cdb/Macros.hx

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ using haxe.macro.Tools;
88
using Lambda;
99

1010
typedef FieldBuild = {
11-
type:ComplexType,
12-
vars:Array<Expr>,
13-
init:Expr
11+
var type:ComplexType;
12+
var vars:Array<Expr>;
13+
var load:Expr;
14+
@:optional var init:Null<Expr>;
1415
}
1516

1617
typedef BuildArgs = {
@@ -19,6 +20,9 @@ typedef BuildArgs = {
1920

2021
/** Whether to group consts by separator names */
2122
@:optional var groupIds:Bool;
23+
24+
/** Whether to wrap load expressions in try/catch */
25+
@:optional var safeLoad:Bool;
2226
}
2327
#end
2428

@@ -33,6 +37,7 @@ class Macros {
3337
public static function buildConsts(file:String, path:String, args:BuildArgs = null) {
3438
var moduleName = args?.moduleName ?? "Data";
3539
var groupIds = args?.groupIds ?? false;
40+
var safeLoad = args?.safeLoad ?? false;
3641

3742
var fields = Context.getBuildFields();
3843
var pos = Context.currentPos();
@@ -85,14 +90,14 @@ class Macros {
8590

8691
var module = macro $i{moduleName};
8792

88-
var initExprs = [];
93+
var loadExprs = [];
8994

9095
inline function fullType(tname:String) {
9196
return (moduleName + "." + Module.makeTypeName(tname)).toComplex();
9297
}
9398

9499
function getData(id:String) {
95-
var e = macro $module.$sheetName.get($module.$sheetKind.$id); // TODO: optional
100+
var e = macro $module.$sheetName.get($module.$sheetKind.$id);
96101
for (i in 0...colPath.length-1) {
97102
e = {expr: EField(e, colPath[i]), pos: pos};
98103
}
@@ -123,16 +128,16 @@ class Macros {
123128

124129
inline function simpleType(t:cdb.Data.ColumnType):Null<ComplexType>
125130
return switch (t) {
126-
case TInt: macro :Int;
131+
case TInt | TColor: macro :Int;
127132
case TFloat: macro :Float;
128133
case TBool: macro :Bool;
129134
case TString: macro :String;
130135
case TCurve: macro :cdb.Types.Curve;
131136
default: null;
132137
};
133138

134-
inline function makeVar(name:String, initExpr:Expr):Expr
135-
return {expr: EVars([{name: name, expr: initExpr}]), pos: pos};
139+
inline function makeVar(name:String, loadExpr:Expr):Expr
140+
return {expr: EVars([{name: name, expr: loadExpr}]), pos: pos};
136141

137142
function getPolyVal(polySub:Sheet, colVal:Dynamic):{col:cdb.Data.Column, val:Dynamic} {
138143
for (pc in polySub.columns) {
@@ -148,20 +153,27 @@ class Macros {
148153
return null;
149154
var colName = col.name;
150155
switch (col.type) {
151-
case TInt | TFloat | TBool | TCurve:
156+
case TInt | TColor | TFloat | TBool:
157+
return {
158+
type: simpleType(col.type),
159+
vars: [],
160+
load: macro $rowExpr.$colName,
161+
init: macro $v{colVal}
162+
};
163+
case TCurve:
152164
return {
153165
type: simpleType(col.type),
154166
vars: [],
155-
init: macro $rowExpr.$colName
167+
load: macro $rowExpr.$colName
156168
};
157169
case TString:
158170
var textArgs = extractTextArgs(colVal);
159171
if (textArgs == null)
160-
return {type: macro :String, vars: [], init: macro $rowExpr.$colName};
172+
return {type: macro :String, vars: [], load: macro $rowExpr.$colName};
161173
return {
162174
type: TFunction([TAnonymous(textArgs)], macro :String),
163175
vars: [],
164-
init: macro function(vars) {
176+
load: macro function(vars) {
165177
return cdb.Macros.formatText($rowExpr.$colName, vars);
166178
}
167179
};
@@ -171,14 +183,14 @@ class Macros {
171183
return {
172184
type: refType,
173185
vars: [],
174-
init: col.opt ? macro $module.$refTableName.resolve($rowExpr.$colName.toString()) : macro $rowExpr.$colName == null ? null : $module.$refTableName.resolve($rowExpr.$colName.toString())
186+
load: col.opt ? macro $module.$refTableName.resolve($rowExpr.$colName.toString()) : macro $rowExpr.$colName == null ? null : $module.$refTableName.resolve($rowExpr.$colName.toString())
175187
};
176188
case TProperties:
177189
var subType = fullType(sheet.getSub(col).name);
178190
return {
179191
type: subType,
180192
vars: [],
181-
init: macro $rowExpr.$colName
193+
load: macro $rowExpr.$colName
182194
};
183195
case TPolymorph:
184196
var polySub = sheet.getSub(col);
@@ -204,7 +216,7 @@ class Macros {
204216

205217
var val:Array<Dynamic> = colVal;
206218
var fields = [];
207-
var inits = [];
219+
var loads = [];
208220
var vars = [];
209221

210222
var arrVar = prefix + "_" + colName;
@@ -221,34 +233,34 @@ class Macros {
221233
return continue;
222234
for (d in result.vars)
223235
vars.push(d);
224-
vars.push(makeVar(itemVar, result.init));
236+
vars.push(makeVar(itemVar, result.load));
225237
fields.push({
226238
name: sid,
227239
pos: pos,
228240
kind: FVar(result.type),
229241
access: [AFinal]
230242
});
231-
inits.push({field: sid, expr: macro cast $i{itemVar}});
243+
loads.push({field: sid, expr: macro cast $i{itemVar}});
232244
}
233245
return {
234246
type: TAnonymous(fields),
235247
vars: vars,
236-
init: {expr: EObjectDecl(inits), pos: pos}
248+
load: {expr: EObjectDecl(loads), pos: pos}
237249
};
238250
} else if (subCols.length == 1) {
239251
var et = simpleType(subCols[0].type) ?? fullType(sub.name);
240252
var valCol = subCols[0].name;
241253
return {
242254
type: macro :cdb.Types.ArrayRead<$et>,
243255
vars: [],
244-
init: macro [for (l in ($rowExpr.$colName:Array<Dynamic>)) (l : Dynamic).$valCol]
256+
load: macro [for (l in ($rowExpr.$colName:Array<Dynamic>)) (l : Dynamic).$valCol]
245257
};
246258
} else {
247259
var et = fullType(sub.name);
248260
return {
249261
type: macro :cdb.Types.ArrayRead<$et>,
250262
vars: [],
251-
init: macro $rowExpr.$colName
263+
load: macro $rowExpr.$colName
252264
};
253265
}
254266
default:
@@ -257,6 +269,14 @@ class Macros {
257269
}
258270
};
259271

272+
function safeWrap(id: String, expr:Expr):Expr {
273+
if(safeLoad) {
274+
var err = 'Failed to load "$path.$id"';
275+
return macro try { $expr; } catch (e:Dynamic) { trace($v{err}); throw e; };
276+
}
277+
return expr;
278+
}
279+
260280
if (groupIds) {
261281
// Group fields by separators
262282
var separators = rootSheet.separators;
@@ -271,9 +291,10 @@ class Macros {
271291
var nextSep = (sepi < separators.length - 1) ? separators[sepi + 1] : null;
272292

273293
var groupFields = [];
274-
var groupInits = [];
294+
var initExprs = [];
295+
var groupLoads = [];
275296

276-
groupInits.push(macro var __gobj:Dynamic = {});
297+
groupLoads.push(macro var __gobj:Dynamic = {});
277298

278299
while (i < rootSheet.lines.length) {
279300
var line = rootSheet.lines[i];
@@ -290,12 +311,17 @@ class Macros {
290311
var result = buildField(buildCol, pobj, colSheet, macro __o, id);
291312
if (result == null)
292313
continue;
293-
var block = [];
294-
block.push(macro var __o:Dynamic = ${getData(id)});
295-
for (d in result.vars)
296-
block.push(d);
297-
block.push(macro __gobj.$id = ${result.init});
298-
groupInits.push(macro $b{block});
314+
315+
{
316+
var block = [];
317+
block.push(macro var __o:Dynamic = ${getData(id)});
318+
for (d in result.vars)
319+
block.push(d);
320+
block.push(macro __gobj.$id = ${result.load});
321+
groupLoads.push(safeWrap(id, macro $b{block}));
322+
}
323+
324+
initExprs.push({field: id, expr: result.init ?? macro cast null});
299325

300326
groupFields.push({
301327
name: id,
@@ -305,13 +331,15 @@ class Macros {
305331
});
306332
}
307333

308-
groupInits.push(macro $i{sep.title} = cast __gobj);
309-
initExprs.push(macro $b{groupInits});
334+
groupLoads.push(macro $i{sep.title} = cast __gobj);
335+
loadExprs.push(macro $b{groupLoads});
310336
fields.push({
311337
name: sep.title,
312338
pos: pos,
313339
access: [AStatic, APublic],
314-
kind: FVar(TAnonymous(groupFields), null)
340+
kind: FVar(TAnonymous(groupFields), {
341+
expr: EObjectDecl(initExprs), pos: pos
342+
})
315343
});
316344
}
317345
} else {
@@ -326,17 +354,17 @@ class Macros {
326354
if (result == null)
327355
continue;
328356

329-
var initBlock = [macro var __o:Dynamic = ${getData(id)}];
357+
var loadBlock = [macro var __o:Dynamic = ${getData(id)}];
330358
for (d in result.vars)
331-
initBlock.push(d);
332-
initBlock.push(macro $i{id} = ${result.init});
333-
initExprs.push(macro $b{initBlock});
359+
loadBlock.push(d);
360+
loadBlock.push(macro $i{id} = ${result.load});
361+
loadExprs.push(safeWrap(id, macro $b{loadBlock}));
334362

335363
fields.push({
336364
name: id,
337365
pos: pos,
338366
access: [AStatic, APublic],
339-
kind: FVar(result.type, null)
367+
kind: FVar(result.type, result.init)
340368
});
341369
}
342370
}
@@ -345,7 +373,7 @@ class Macros {
345373
name: "reload",
346374
pos: pos,
347375
access: [AStatic, APublic],
348-
kind: FFun({args: [], ret: macro :Void, expr: macro $b{initExprs}})
376+
kind: FFun({args: [], ret: macro :Void, expr: macro $b{loadExprs}})
349377
});
350378

351379
return fields;

0 commit comments

Comments
 (0)