一次性定义结构并创建相关数据项列表?
Define a struct and create a list of related data items in one pass?
我想实现一个系统,通过该系统我可以使用一组宏(或模板)一次性创建一个结构和一些数据。它会像这样使用(语法不固定,任何有效的都可以):
def_vert(MyVertex)
{
element(float, 3, Position, POSITION, 0);
element(float, 3, Normal, NORMAL, 0);
element(float, 2, UVa, TEXCOORD, 0);
element(float, 2, UVb TEXCOORD, 1);
element(float, 4, DiffuseColor, COLOR, 0);
}
end_def()
并且会输出:
struct MyVertex
{
float3 Position;
float3 Normal;
float2 UVa;
float2 UVb;
float4 DiffuseColor;
};
还有:
field_definition MyVertex_field_defs[] =
{
{ "POSITION", 0, float_type, 3 },
{ "NORMAL", 0, float_type, 3 },
{ "TEXCOORD", 0, float_type, 2 },
{ "TEXCOORD", 1, float_type, 2 },
{ "COLOR", 0, float_type, 4 }
};
我看不到使用宏或 TMP 来执行此操作(创建 2 个单独的输出块)的方法 - 有人知道这是否可行吗?我无法直接使用 boost,但了解它是否能提供解决方案会很有用。
一个严峻的选择是使用像这样的包含文件:
MyVertex.h包含定义
def_makestruct.h 包含创建结构的宏
def_makefields.h 包含创建字段的宏
然后:
#include "def_makestruct.h"
#include "MyVertex.h"
#include "def_makefields.h"
#include "MyVertex.h"
所以我至少只需要在一个地方编辑定义,但它必须在它自己的文件中。有没有更好的方法?
我遇到了类似的问题,为了避免写两次相同的字符串,我使用了后续的技术。
定义将在文件上使用的宏:
在名为 data.cpp
的文件中只写入一次所需数据
mcr(NORMAL,3,Normal)
mcr(TEXCOORD,2,UVa)
mcr(TEXCOORD,2,UVb)
mcr(COLOR,4,DiffuseColor)
在另一个文件中写入
#define mcr(a,b,c,etc) define_as_needed
struct MyVertex
{
#include "data.cpp"
}
#undef mcr
#define mcr(a,b,c,etc) define_as_needed
而不是重新定义宏
#define mcr(a,b,c,etc) define_as_needed
field_definition MyVertex_field_defs[] =
{
#include "data.cpp"
};
#undef mcr
在我的例子中,根据每次需要更改宏定义的内容,我将上述重定义进行了 3 次,共 4 次。
根据您的需要调整代码。
特别是对于结构中常量和关联字符串和数据的定义,它非常方便。
您要实现的目标称为 X Macro。
如果您不想在每个扩展站点包含任何文件或提供 element/def_vert/end_vert 定义,您可以将它们作为额外参数传递给 MyVertexDef 宏。
#define MyVertexDef(def_vert, element, end_def) \
def_vert(MyVertex) \
element(float, 3, Position, POSITION, 0) \
element(float, 3, Normal, NORMAL, 0) \
element(float, 2, UVa, TEXCOORD, 0) \
element(float, 2, UVb, TEXCOORD, 1) \
element(float, 4, DiffuseColor, COLOR, 0) \
end_def()
#define struct_def_vert(name) struct name {
#define struct_end_def() };
#define struct_element(type, size, name, meaning, index) type name;
#define array_def_vert(name) field_definition name##_field_defs[] = {
#define array_end_def() };
#define array_element(type, size, name, meaning, index) {#name, index, type##_type, size},
#define GenerateStruct(T) T(struct_def_vert, struct_element, struct_end_def)
#define GenerateArray(T) T(array_def_vert, array_element, array_end_def)
...
//Where you want your struct MyVertex
GenerateStruct(MyVertexDef)
...
//Where you want MyVertex_field_defs
GenerateArray(MyVertexDef)
我想实现一个系统,通过该系统我可以使用一组宏(或模板)一次性创建一个结构和一些数据。它会像这样使用(语法不固定,任何有效的都可以):
def_vert(MyVertex)
{
element(float, 3, Position, POSITION, 0);
element(float, 3, Normal, NORMAL, 0);
element(float, 2, UVa, TEXCOORD, 0);
element(float, 2, UVb TEXCOORD, 1);
element(float, 4, DiffuseColor, COLOR, 0);
}
end_def()
并且会输出:
struct MyVertex
{
float3 Position;
float3 Normal;
float2 UVa;
float2 UVb;
float4 DiffuseColor;
};
还有:
field_definition MyVertex_field_defs[] =
{
{ "POSITION", 0, float_type, 3 },
{ "NORMAL", 0, float_type, 3 },
{ "TEXCOORD", 0, float_type, 2 },
{ "TEXCOORD", 1, float_type, 2 },
{ "COLOR", 0, float_type, 4 }
};
我看不到使用宏或 TMP 来执行此操作(创建 2 个单独的输出块)的方法 - 有人知道这是否可行吗?我无法直接使用 boost,但了解它是否能提供解决方案会很有用。
一个严峻的选择是使用像这样的包含文件:
MyVertex.h包含定义
def_makestruct.h 包含创建结构的宏
def_makefields.h 包含创建字段的宏
然后:
#include "def_makestruct.h"
#include "MyVertex.h"
#include "def_makefields.h"
#include "MyVertex.h"
所以我至少只需要在一个地方编辑定义,但它必须在它自己的文件中。有没有更好的方法?
我遇到了类似的问题,为了避免写两次相同的字符串,我使用了后续的技术。
定义将在文件上使用的宏:
在名为 data.cpp
的文件中只写入一次所需数据mcr(NORMAL,3,Normal)
mcr(TEXCOORD,2,UVa)
mcr(TEXCOORD,2,UVb)
mcr(COLOR,4,DiffuseColor)
在另一个文件中写入
#define mcr(a,b,c,etc) define_as_needed
struct MyVertex
{
#include "data.cpp"
}
#undef mcr
#define mcr(a,b,c,etc) define_as_needed
而不是重新定义宏
#define mcr(a,b,c,etc) define_as_needed
field_definition MyVertex_field_defs[] =
{
#include "data.cpp"
};
#undef mcr
在我的例子中,根据每次需要更改宏定义的内容,我将上述重定义进行了 3 次,共 4 次。
根据您的需要调整代码。 特别是对于结构中常量和关联字符串和数据的定义,它非常方便。
您要实现的目标称为 X Macro。
如果您不想在每个扩展站点包含任何文件或提供 element/def_vert/end_vert 定义,您可以将它们作为额外参数传递给 MyVertexDef 宏。
#define MyVertexDef(def_vert, element, end_def) \
def_vert(MyVertex) \
element(float, 3, Position, POSITION, 0) \
element(float, 3, Normal, NORMAL, 0) \
element(float, 2, UVa, TEXCOORD, 0) \
element(float, 2, UVb, TEXCOORD, 1) \
element(float, 4, DiffuseColor, COLOR, 0) \
end_def()
#define struct_def_vert(name) struct name {
#define struct_end_def() };
#define struct_element(type, size, name, meaning, index) type name;
#define array_def_vert(name) field_definition name##_field_defs[] = {
#define array_end_def() };
#define array_element(type, size, name, meaning, index) {#name, index, type##_type, size},
#define GenerateStruct(T) T(struct_def_vert, struct_element, struct_end_def)
#define GenerateArray(T) T(array_def_vert, array_element, array_end_def)
...
//Where you want your struct MyVertex
GenerateStruct(MyVertexDef)
...
//Where you want MyVertex_field_defs
GenerateArray(MyVertexDef)