enderalse/source/fs.dll/skse64/skse64/PapyrusNativeFunctionDef_Base.inl

417 lines
7.2 KiB
C++

#if NUM_PARAMS > 10
#error PapyrusNativeFunctionDef: too many params
#endif
template <typename T_Base
#if !VOID_SPEC
, typename T_Result
#endif
#if NUM_PARAMS >= 1
,typename T_Arg0
#endif
#if NUM_PARAMS >= 2
,typename T_Arg1
#endif
#if NUM_PARAMS >= 3
,typename T_Arg2
#endif
#if NUM_PARAMS >= 4
,typename T_Arg3
#endif
#if NUM_PARAMS >= 5
,typename T_Arg4
#endif
#if NUM_PARAMS >= 6
,typename T_Arg5
#endif
#if NUM_PARAMS >= 7
,typename T_Arg6
#endif
#if NUM_PARAMS >= 8
,typename T_Arg7
#endif
#if NUM_PARAMS >= 9
,typename T_Arg8
#endif
#if NUM_PARAMS >= 10
,typename T_Arg9
#endif
>
class CLASS_NAME
#if VOID_SPEC
<T_Base, void
#if NUM_PARAMS >= 1
, T_Arg0
#endif
#if NUM_PARAMS >= 2
, T_Arg1
#endif
#if NUM_PARAMS >= 3
, T_Arg2
#endif
#if NUM_PARAMS >= 4
, T_Arg3
#endif
#if NUM_PARAMS >= 5
, T_Arg4
#endif
#if NUM_PARAMS >= 6
, T_Arg5
#endif
#if NUM_PARAMS >= 7
, T_Arg6
#endif
#if NUM_PARAMS >= 8
, T_Arg7
#endif
#if NUM_PARAMS >= 9
, T_Arg8
#endif
#if NUM_PARAMS >= 10
, T_Arg9
#endif
>
#endif
: public NativeFunction
{
public:
// Callback with short signature
typedef
#if LATENT_SPEC
bool
#elif VOID_SPEC
void
#else
T_Result
#endif
(* CallbackType)(T_Base * base
#if NUM_PARAMS >= 1
, T_Arg0 arg0
#endif
#if NUM_PARAMS >= 2
, T_Arg1 arg1
#endif
#if NUM_PARAMS >= 3
, T_Arg2 arg2
#endif
#if NUM_PARAMS >= 4
, T_Arg3 arg3
#endif
#if NUM_PARAMS >= 5
, T_Arg4 arg4
#endif
#if NUM_PARAMS >= 6
, T_Arg5 arg5
#endif
#if NUM_PARAMS >= 7
, T_Arg6 arg6
#endif
#if NUM_PARAMS >= 8
, T_Arg7 arg7
#endif
#if NUM_PARAMS >= 9
, T_Arg8 arg8
#endif
#if NUM_PARAMS >= 10
, T_Arg9 arg9
#endif
);
// Callback with long signature
typedef
#if LATENT_SPEC
bool
#elif VOID_SPEC
void
#else
T_Result
#endif
(* CallbackType_LongSig)(VMClassRegistry* registry, UInt32 stackId, T_Base * base
#if NUM_PARAMS >= 1
, T_Arg0 arg0
#endif
#if NUM_PARAMS >= 2
, T_Arg1 arg1
#endif
#if NUM_PARAMS >= 3
, T_Arg2 arg2
#endif
#if NUM_PARAMS >= 4
, T_Arg3 arg3
#endif
#if NUM_PARAMS >= 5
, T_Arg4 arg4
#endif
#if NUM_PARAMS >= 6
, T_Arg5 arg5
#endif
#if NUM_PARAMS >= 7
, T_Arg6 arg6
#endif
#if NUM_PARAMS >= 8
, T_Arg7 arg7
#endif
#if NUM_PARAMS >= 9
, T_Arg8 arg8
#endif
#if NUM_PARAMS >= 10
, T_Arg9 arg9
#endif
);
// Short signature
CLASS_NAME(const char * fnName, const char * className, CallbackType callback, VMClassRegistry * registry)
:NativeFunction(fnName, className, IsStaticType <T_Base>::value, NUM_PARAMS)
{
// store callback
m_callback = (void *)callback;
m_bUseLongSignature = false;
InitParams(registry);
}
// Long signature
CLASS_NAME(const char * fnName, const char * className, CallbackType_LongSig callback, VMClassRegistry * registry)
:NativeFunction(fnName, className, IsStaticType <T_Base>::value, NUM_PARAMS)
{
// store callback
m_callback = (void *)callback;
m_bUseLongSignature = true;
InitParams(registry);
}
void InitParams(VMClassRegistry * registry)
{
#if NUM_PARAMS >= 1
m_params.data[0].type = GetTypeID <T_Arg0>(registry);
#endif
#if NUM_PARAMS >= 2
m_params.data[1].type = GetTypeID <T_Arg1>(registry);
#endif
#if NUM_PARAMS >= 3
m_params.data[2].type = GetTypeID <T_Arg2>(registry);
#endif
#if NUM_PARAMS >= 4
m_params.data[3].type = GetTypeID <T_Arg3>(registry);
#endif
#if NUM_PARAMS >= 5
m_params.data[4].type = GetTypeID <T_Arg4>(registry);
#endif
#if NUM_PARAMS >= 6
m_params.data[5].type = GetTypeID <T_Arg5>(registry);
#endif
#if NUM_PARAMS >= 7
m_params.data[6].type = GetTypeID <T_Arg6>(registry);
#endif
#if NUM_PARAMS >= 8
m_params.data[7].type = GetTypeID <T_Arg7>(registry);
#endif
#if NUM_PARAMS >= 9
m_params.data[8].type = GetTypeID <T_Arg8>(registry);
#endif
#if NUM_PARAMS >= 10
m_params.data[9].type = GetTypeID <T_Arg9>(registry);
#endif
#if VOID_SPEC
m_retnType = GetTypeID <void>(registry);
#else
m_retnType = GetTypeID <T_Result>(registry);
#endif
#if LATENT_SPEC
m_isLatent = true;
#endif
}
virtual ~CLASS_NAME() { }
virtual bool Run(VMValue * baseValue, VMClassRegistry * registry, UInt32 stackId, VMValue * resultValue, VMState * state)
{
#if _DEBUG
DebugRunHook(baseValue, registry, stackId, resultValue, state);
#endif
// get argument list
UInt32 argOffset = CALL_MEMBER_FN(state->argList, GetOffset)(state);
T_Base * base = NULL;
// extract base object pointer for non-static types
if (! IsStaticType <T_Base>::value)
{
UnpackValue(&base, baseValue);
if (!base) return false;
}
// extract parameters
#if NUM_PARAMS >= 1
T_Arg0 arg0;
UnpackValue(&arg0, CALL_MEMBER_FN(state->argList, Get)(state, 0, argOffset));
#endif
#if NUM_PARAMS >= 2
T_Arg1 arg1;
UnpackValue(&arg1, CALL_MEMBER_FN(state->argList, Get)(state, 1, argOffset));
#endif
#if NUM_PARAMS >= 3
T_Arg2 arg2;
UnpackValue(&arg2, CALL_MEMBER_FN(state->argList, Get)(state, 2, argOffset));
#endif
#if NUM_PARAMS >= 4
T_Arg3 arg3;
UnpackValue(&arg3, CALL_MEMBER_FN(state->argList, Get)(state, 3, argOffset));
#endif
#if NUM_PARAMS >= 5
T_Arg4 arg4;
UnpackValue(&arg4, CALL_MEMBER_FN(state->argList, Get)(state, 4, argOffset));
#endif
#if NUM_PARAMS >= 6
T_Arg5 arg5;
UnpackValue(&arg5, CALL_MEMBER_FN(state->argList, Get)(state, 5, argOffset));
#endif
#if NUM_PARAMS >= 7
T_Arg6 arg6;
UnpackValue(&arg6, CALL_MEMBER_FN(state->argList, Get)(state, 6, argOffset));
#endif
#if NUM_PARAMS >= 8
T_Arg7 arg7;
UnpackValue(&arg7, CALL_MEMBER_FN(state->argList, Get)(state, 7, argOffset));
#endif
#if NUM_PARAMS >= 9
T_Arg8 arg8;
UnpackValue(&arg8, CALL_MEMBER_FN(state->argList, Get)(state, 8, argOffset));
#endif
#if NUM_PARAMS >= 10
T_Arg9 arg9;
UnpackValue(&arg9, CALL_MEMBER_FN(state->argList, Get)(state, 9, argOffset));
#endif
// long signature
if (m_bUseLongSignature)
{
// call the callback
#if LATENT_SPEC
bool result =
#elif !VOID_SPEC
T_Result result =
#endif
((CallbackType_LongSig)m_callback)(registry, stackId, base
#if NUM_PARAMS >= 1
, arg0
#endif
#if NUM_PARAMS >= 2
, arg1
#endif
#if NUM_PARAMS >= 3
, arg2
#endif
#if NUM_PARAMS >= 4
, arg3
#endif
#if NUM_PARAMS >= 5
, arg4
#endif
#if NUM_PARAMS >= 6
, arg5
#endif
#if NUM_PARAMS >= 7
, arg6
#endif
#if NUM_PARAMS >= 8
, arg7
#endif
#if NUM_PARAMS >= 9
, arg8
#endif
#if NUM_PARAMS >= 10
, arg9
#endif
);
// pack the result
#if LATENT_SPEC
resultValue->SetBool(result);
#elif VOID_SPEC
resultValue->SetNone();
#else
PackValue(resultValue, &result, registry);
#endif
}
// Short signature
else
{
// call the callback
#if LATENT_SPEC
bool result =
#elif !VOID_SPEC
T_Result result =
#endif
((CallbackType)m_callback)(base
#if NUM_PARAMS >= 1
, arg0
#endif
#if NUM_PARAMS >= 2
, arg1
#endif
#if NUM_PARAMS >= 3
, arg2
#endif
#if NUM_PARAMS >= 4
, arg3
#endif
#if NUM_PARAMS >= 5
, arg4
#endif
#if NUM_PARAMS >= 6
, arg5
#endif
#if NUM_PARAMS >= 7
, arg6
#endif
#if NUM_PARAMS >= 8
, arg7
#endif
#if NUM_PARAMS >= 9
, arg8
#endif
#if NUM_PARAMS >= 10
, arg9
#endif
);
// pack the result
#if LATENT_SPEC
resultValue->SetBool(result);
#elif VOID_SPEC
resultValue->SetNone();
#else
PackValue(resultValue, &result, registry);
#endif
}
return true;
}
private:
// hide
CLASS_NAME();
// Temporary workaround until refactoring
bool m_bUseLongSignature;
};
#undef VOID_SPEC