417 lines
7.2 KiB
C++
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
|