mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-25 17:43:44 +00:00
Improve Engine API export, robust Default Value logic and allow _ in arg
This commit is contained in:
parent
8bede52d3b
commit
d567bc9735
3 changed files with 86 additions and 43 deletions
|
|
@ -67,18 +67,9 @@ struct EngineFunctionDefaultArguments
|
|||
/// @warn This is @b NOT the size of the memory block returned by getArgs() and also
|
||||
/// not the number of elements it contains.
|
||||
U32 mNumDefaultArgs;
|
||||
|
||||
/// Return a pointer to the variable-sized array of default argument values.
|
||||
///
|
||||
/// @warn The arguments must be stored @b IMMEDIATELY after #mNumDefaultArgs.
|
||||
/// @warn This is a @b FULL frame and not just the default arguments, i.e. it starts with the
|
||||
/// first argument that the function takes and ends with the last argument it takes.
|
||||
/// @warn If the compiler's #pragma pack is buggy, the elements in this structure are allowed
|
||||
/// to be 4-byte aligned rather than byte-aligned as they should be.
|
||||
const U8* getArgs() const
|
||||
{
|
||||
return ( const U8* ) &( mNumDefaultArgs ) + sizeof( mNumDefaultArgs );
|
||||
}
|
||||
|
||||
U32* mOffsets;
|
||||
U8* mFirst;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -130,13 +121,29 @@ private:
|
|||
SelfType::template copyHelper<TailTs...>(argsT, tailT, typename Gens<sizeof...(TailTs)>::type());
|
||||
return argsT;
|
||||
};
|
||||
|
||||
template<size_t I = 0>
|
||||
typename std::enable_if<I == sizeof...(ArgTs)>::type initOffsetsHelper()
|
||||
{ }
|
||||
|
||||
template<size_t I = 0>
|
||||
typename std::enable_if < I < sizeof...(ArgTs)>::type initOffsetsHelper()
|
||||
{
|
||||
mOffsets[I] = fixed_tuple_offset<I>(mArgs);
|
||||
initOffsetsHelper<I + 1>();
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename ...TailTs> _EngineFunctionDefaultArguments(TailTs ...tail)
|
||||
: EngineFunctionDefaultArguments({sizeof...(TailTs)})
|
||||
: EngineFunctionDefaultArguments()
|
||||
{
|
||||
std::tuple<DefVST<ArgTs>...> tmpTup = SelfType::tailInit(tail...);
|
||||
fixed_tuple_mutator<void(DefVST<ArgTs>...), void(DefVST<ArgTs>...)>::copy(tmpTup, mArgs);
|
||||
|
||||
mNumDefaultArgs = sizeof...(TailTs);
|
||||
mOffsets = new U32[sizeof...(ArgTs)];
|
||||
initOffsetsHelper();
|
||||
mFirst = (U8*)& mArgs;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ static const char* getDocString(const EngineExport* exportInfo)
|
|||
}
|
||||
|
||||
template< typename T >
|
||||
inline T getArgValue(const EngineFunctionDefaultArguments* defaultArgs, U32 offset)
|
||||
inline T getArgValue(const EngineFunctionDefaultArguments* defaultArgs, U32 idx)
|
||||
{
|
||||
return *reinterpret_cast< const T* >(defaultArgs->getArgs() + offset);
|
||||
return *(const T*)(defaultArgs->mFirst + defaultArgs->mOffsets[idx]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ static Vector< String > parseFunctionArgumentNames(const EngineFunctionInfo* fun
|
|||
// Parse out name.
|
||||
|
||||
const char* end = ptr + 1;
|
||||
while (ptr > prototype && dIsalnum(*ptr))
|
||||
while (ptr > prototype && (dIsalnum(*ptr) || *ptr == '_'))
|
||||
ptr--;
|
||||
const char* start = ptr + 1;
|
||||
|
||||
|
|
@ -169,20 +169,19 @@ static Vector< String > parseFunctionArgumentNames(const EngineFunctionInfo* fun
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static String getDefaultArgumentValue(const EngineFunctionInfo* function, const EngineTypeInfo* type, U32 offset)
|
||||
static String getValueForType(const EngineTypeInfo* type, void* addr)
|
||||
{
|
||||
String value;
|
||||
const EngineFunctionDefaultArguments* defaultArgs = function->getDefaultArguments();
|
||||
#define ADDRESS_TO_TYPE(tp) *(const tp*)(addr);
|
||||
|
||||
switch (type->getTypeKind())
|
||||
{
|
||||
case EngineTypeKindPrimitive:
|
||||
{
|
||||
#define PRIMTYPE( tp ) \
|
||||
#define PRIMTYPE( tp ) \
|
||||
if( TYPE< tp >() == type ) \
|
||||
{ \
|
||||
tp val = getArgValue< tp >( defaultArgs, offset ); \
|
||||
tp val = ADDRESS_TO_TYPE(tp); \
|
||||
value = String::ToString( val ); \
|
||||
}
|
||||
|
||||
|
|
@ -195,9 +194,9 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
PRIMTYPE(F64);
|
||||
|
||||
//TODO: for now we store string literals in ASCII; needs to be sorted out
|
||||
if (TYPE< const char* >() == type)
|
||||
if (TYPE< String >() == type || TYPE< const UTF8* >() == type)
|
||||
{
|
||||
const char* val = reinterpret_cast<const char*>(defaultArgs->getArgs() + offset);
|
||||
const UTF8* val = *((const UTF8**)(addr));
|
||||
value = val;
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +206,7 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
|
||||
case EngineTypeKindEnum:
|
||||
{
|
||||
S32 val = getArgValue< S32 >(defaultArgs, offset);
|
||||
S32 val = ADDRESS_TO_TYPE(S32);
|
||||
AssertFatal(type->getEnumTable(), "engineXMLExport - Enum type without table!");
|
||||
|
||||
const EngineEnumTable& table = *(type->getEnumTable());
|
||||
|
|
@ -225,7 +224,7 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
|
||||
case EngineTypeKindBitfield:
|
||||
{
|
||||
S32 val = getArgValue< S32 >(defaultArgs, offset);
|
||||
S32 val = ADDRESS_TO_TYPE(S32);
|
||||
AssertFatal(type->getEnumTable(), "engineXMLExport - Bitfield type without table!");
|
||||
|
||||
const EngineEnumTable& table = *(type->getEnumTable());
|
||||
|
|
@ -247,7 +246,24 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
|
||||
case EngineTypeKindStruct:
|
||||
{
|
||||
//TODO: struct type default argument values
|
||||
AssertFatal(type->getFieldTable(), "engineXMLExport - Struct type without table!");
|
||||
const EngineFieldTable* fieldTable = type->getFieldTable();
|
||||
U32 numFields = fieldTable->getNumFields();
|
||||
|
||||
|
||||
for (int i = 0; i < numFields; ++i)
|
||||
{
|
||||
const EngineTypeInfo* fieldType = (*fieldTable)[i].getType();
|
||||
U32 fieldOffset = (*fieldTable)[i].getOffset();
|
||||
AssertFatal((*fieldTable)[i].getNumElements() == 1, "engineXMLExport - numElements != 1 not supported currently.");
|
||||
if (i == 0) {
|
||||
value = getValueForType(fieldType, (void*)((size_t)addr + fieldOffset));
|
||||
}
|
||||
else {
|
||||
value += " " + getValueForType(fieldType, (void*)((size_t)addr + fieldOffset));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +273,7 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
// For these two kinds, we support "null" as the only valid
|
||||
// default value.
|
||||
|
||||
const void* ptr = getArgValue< const void* >(defaultArgs, offset);
|
||||
const void* ptr = ADDRESS_TO_TYPE(void*);
|
||||
if (!ptr)
|
||||
value = "null";
|
||||
break;
|
||||
|
|
@ -267,11 +283,20 @@ static String getDefaultArgumentValue(const EngineFunctionInfo* function, const
|
|||
break;
|
||||
}
|
||||
|
||||
#undef ADDRESS_TO_TYPE
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static String getDefaultArgumentValue(const EngineFunctionInfo* function, const EngineTypeInfo* type, U32 idx)
|
||||
{
|
||||
const EngineFunctionDefaultArguments* defaultArgs = function->getDefaultArguments();
|
||||
return getValueForType(type, (void*)(defaultArgs->mFirst + defaultArgs->mOffsets[idx]));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void exportFunction(const EngineFunctionInfo* function, SimXMLDocument* xml)
|
||||
{
|
||||
if (isExportFiltered(function))
|
||||
|
|
@ -295,9 +320,6 @@ static void exportFunction(const EngineFunctionInfo* function, SimXMLDocument* x
|
|||
Vector< String > argumentNames = parseFunctionArgumentNames(function);
|
||||
const U32 numArgumentNames = argumentNames.size();
|
||||
|
||||
// Accumulated offset in function argument frame vector.
|
||||
U32 argFrameOffset = 0;
|
||||
|
||||
for (U32 i = 0; i < numArguments; ++i)
|
||||
{
|
||||
xml->pushNewElement("EngineFunctionArgument");
|
||||
|
|
@ -313,21 +335,17 @@ static void exportFunction(const EngineFunctionInfo* function, SimXMLDocument* x
|
|||
|
||||
if (i >= firstDefaultArg)
|
||||
{
|
||||
String defaultValue = getDefaultArgumentValue(function, type, argFrameOffset);
|
||||
String defaultValue = getDefaultArgumentValue(function, type, i);
|
||||
xml->setAttribute("defaultValue", defaultValue);
|
||||
}
|
||||
|
||||
// A bit hacky, default arguments have all offsets.
|
||||
if (function->getDefaultArguments() != NULL)
|
||||
{
|
||||
xml->setAttribute("offset", String::ToString(function->getDefaultArguments()->mOffsets[i]));
|
||||
}
|
||||
|
||||
xml->popElement();
|
||||
|
||||
if (type->getTypeKind() == EngineTypeKindStruct)
|
||||
argFrameOffset += type->getInstanceSize();
|
||||
else
|
||||
argFrameOffset += type->getValueSize();
|
||||
|
||||
#ifdef _PACK_BUG_WORKAROUNDS
|
||||
if (argFrameOffset % 4 > 0)
|
||||
argFrameOffset += 4 - (argFrameOffset % 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
xml->popElement();
|
||||
|
|
@ -579,4 +597,4 @@ DefineEngineFunction(exportEngineAPIToXML, SimXMLDocument*, (), ,
|
|||
exportScope(EngineExportScope::getGlobalScope(), xml, true);
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#ifndef _FIXEDTUPLE_H_
|
||||
#define _FIXEDTUPLE_H_
|
||||
|
||||
#include "engineTypes.h"
|
||||
|
||||
/// @name Fixed-layout tuple definition
|
||||
/// These structs and templates serve as a way to pass arguments from external
|
||||
/// applications and into the T3D console system.
|
||||
|
|
@ -113,6 +116,21 @@ struct fixed_tuple_accessor<0>
|
|||
}
|
||||
};
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4267 )
|
||||
template <size_t I, class... Ts>
|
||||
static U32 fixed_tuple_offset(fixed_tuple<Ts...>& t)
|
||||
{
|
||||
return (U32)((size_t)& fixed_tuple_accessor<I>::get(t)) - ((size_t)& t);
|
||||
}
|
||||
|
||||
template <size_t I, class... Ts>
|
||||
static U32 fixed_tuple_offset(const fixed_tuple<Ts...>& t)
|
||||
{
|
||||
return (U32)((size_t)& fixed_tuple_accessor<I>::get(t)) - ((size_t)& t);
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct fixed_tuple_mutator {};
|
||||
|
||||
|
|
@ -150,4 +168,4 @@ struct fixed_tuple_mutator<void(Tdest...), void(Tsrc...)>
|
|||
/// @}
|
||||
|
||||
|
||||
#endif // !_FIXEDTUPLE_H_
|
||||
#endif // !_FIXEDTUPLE_H_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue