I create a type in a macro which depends on other type ( i create the World type) The issue is that the world type depends on other types (Store and Entity) which are in the same typeblock. It seems that i cannot call the create macro inside the type block to create the type. When i call the gen macro above or below the type block there are types missing. Any idea how i can do this?
type
# i want to create the world type
World = ref object
guids: GUID
storeHealthAble: Store[CompHealthAble]
storeDrawAble: Store[CompDrawAble]
storeNameAble: Store[CompNameAble]
Entity = object
id: GUID
world: World
Store[T] = Table[Entity,T]
# Following for completeness.
Component = enum
DrawAble, HealthAble, NameAble
the type creation macro which creates World:
macro genWorld() =
var typeTree = newNimNode(nnkRecList)
typeTree.add nnkIdentDefs.newTree(
newIdentNode("guids"),
newIdentNode("GUID"),
newEmptyNode()
)
for component in Component:
typeTree.add nnkIdentDefs.newTree(
newIdentNode("store" & $component ),
nnkBracketExpr.newTree(
newIdentNode("Store"),
newIdentNode("Comp" & $component)
),
newEmptyNode()
)
result = nnkStmtList.newTree(
nnkTypeSection.newTree(
nnkTypeDef.newTree(
newIdentNode("World"),
newEmptyNode(),
nnkRefTy.newTree(
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
typeTree
)
)
)
)
)
Got it! :)
at first i dumped the ast:
World {.dumpAstGen.} = ref object
guids: GUID
storeHealthAble: Store[CompHealthAble]
storeDrawAble: Store[CompDrawAble]
storeNameAble: Store[CompNameAble]
this works because the ast that generates this type is passed to the dumpAstGen. Then i copied the ast into a new macro and added my generation code. The only thing was that i had to put Components into its own type section.:
type
Component = enum
DrawAble, HealthAble, NameAble, FOOAble
macro genWorld(left: typed, componentEnum: untyped) =
var typeTree = newNimNode(nnkRecList)
typeTree.add nnkIdentDefs.newTree(
newIdentNode("guids"),
newIdentNode("GUID"),
newEmptyNode()
)
for component in Component:
typeTree.add nnkIdentDefs.newTree(
newIdentNode("store" & $component ),
nnkBracketExpr.newTree(
newIdentNode("Store"),
newIdentNode("Comp" & $component)
),
newEmptyNode()
)
return nnkTypeDef.newTree(
nnkPragmaExpr.newTree(
newIdentNode("World"),
nnkPragma.newTree(
)
),
newEmptyNode(),
nnkRefTy.newTree(
nnkObjectTy.newTree(
newEmptyNode(),
newEmptyNode(),
typeTree
)
)
)
# another type section
type
World {.genWorld: Component.}