Make sure rope script functions are only called from rope contexts

rope
Armin Burgmeier 2012-06-07 23:41:21 +02:00
parent cd67961aa6
commit ecec556395
2 changed files with 57 additions and 22 deletions

View File

@ -19,67 +19,67 @@
#include <C4Rope.h>
#include <C4AulDefFunc.h>
static C4Void FnRemove(C4PropList* Rope)
static C4Void FnRemove(C4Rope* Rope)
{
Game.Ropes.RemoveRope(static_cast<C4Rope*>(Rope));
Game.Ropes.RemoveRope(Rope);
return C4Void();
}
static C4Object* FnGetFront(C4PropList* Rope)
static C4Object* FnGetFront(C4Rope* Rope)
{
return static_cast<C4Rope*>(Rope)->GetFront()->GetObject();
return Rope->GetFront()->GetObject();
}
static C4Object* FnGetBack(C4PropList* Rope)
static C4Object* FnGetBack(C4Rope* Rope)
{
return static_cast<C4Rope*>(Rope)->GetBack()->GetObject();
return Rope->GetBack()->GetObject();
}
static C4Void FnSetFront(C4PropList* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
static C4Void FnSetFront(C4Rope* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
{
static_cast<C4Rope*>(Rope)->SetFront(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
Rope->SetFront(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
return C4Void();
}
static C4Void FnSetBack(C4PropList* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
static C4Void FnSetBack(C4Rope* Rope, C4Object* obj, Nillable<int> x, Nillable<int> y)
{
static_cast<C4Rope*>(Rope)->SetBack(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
Rope->SetBack(obj, x.IsNil() ? Fix0 : itofix(x), y.IsNil() ? Fix0 : itofix(y));
return C4Void();
}
static C4Void FnSetFrontAutoSegmentation(C4PropList* Rope, int max)
static C4Void FnSetFrontAutoSegmentation(C4Rope* Rope, int max)
{
static_cast<C4Rope*>(Rope)->SetFrontAutoSegmentation(itofix(max));
Rope->SetFrontAutoSegmentation(itofix(max));
return C4Void();
}
static C4Void FnSetBackAutoSegmentation(C4PropList* Rope, int max)
static C4Void FnSetBackAutoSegmentation(C4Rope* Rope, int max)
{
static_cast<C4Rope*>(Rope)->SetBackAutoSegmentation(itofix(max));
Rope->SetBackAutoSegmentation(itofix(max));
return C4Void();
}
static C4Void FnSetFrontFixed(C4PropList* Rope, bool fixed)
static C4Void FnSetFrontFixed(C4Rope* Rope, bool fixed)
{
static_cast<C4Rope*>(Rope)->SetFrontFixed(fixed);
Rope->SetFrontFixed(fixed);
return C4Void();
}
static C4Void FnSetBackFixed(C4PropList* Rope, bool fixed)
static C4Void FnSetBackFixed(C4Rope* Rope, bool fixed)
{
static_cast<C4Rope*>(Rope)->SetBackFixed(fixed);
Rope->SetBackFixed(fixed);
return C4Void();
}
static C4Void FnPullFront(C4PropList* Rope, int force)
static C4Void FnPullFront(C4Rope* Rope, int force)
{
static_cast<C4Rope*>(Rope)->PullFront(itofix(force));
Rope->PullFront(itofix(force));
return C4Void();
}
static C4Void FnPullBack(C4PropList* Rope, int force)
static C4Void FnPullBack(C4Rope* Rope, int force)
{
static_cast<C4Rope*>(Rope)->PullBack(itofix(force));
Rope->PullBack(itofix(force));
return C4Void();
}

View File

@ -25,6 +25,7 @@
#include <C4Object.h>
#include <C4Effect.h>
#include <C4DefList.h>
#include <C4Rope.h>
inline const static char *FnStringPar(C4String *pString)
{
@ -97,6 +98,14 @@ public:
NeedObjectContext(const char *function) : C4AulExecError(FormatString("%s: must be called from object context", function).getData()) {}
};
// Other functions are callable in rope context only.
// This exception gets thrown if they are called from anywhere else.
class NeedRopeContext : public C4AulExecError
{
public:
NeedRopeContext(const char *function) : C4AulExecError(FormatString("%s: must be called from rope context", function).getData()) {}
};
// Then there's functions that don't care, but need either defn or object context.
// This exception gets thrown if those are called from global scripts.
class NeedNonGlobalContext : public C4AulExecError
@ -312,6 +321,27 @@ public C4AulDefFuncHelper { \
Func pFunc; \
}; \
template <typename RType LIST(N, TYPENAMES)> \
class C4AulDefRopeFunc##N: \
public C4AulDefFuncHelper { \
public: \
/* A pointer to the function which this class wraps */ \
typedef RType (*Func)(C4Rope * LIST(N, PARS)); \
virtual int GetParCount() { return N; } \
virtual C4V_Type GetRetType() \
{ return C4ValueConv<RType>::Type(); } \
/* Constructor, using the base class to create the ParType array */ \
C4AulDefRopeFunc##N(C4AulScript *pOwner, const char *pName, Func pFunc, bool Public): \
C4AulDefFuncHelper(pOwner, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
/* Extracts the parameters from C4Values and wraps the return value in a C4Value */ \
virtual C4Value Exec(C4PropList * _this, C4Value pPars[], bool fPassErrors) \
{ \
C4Rope * Rope; if (!_this || !(Rope = dynamic_cast<C4Rope*>(_this))) throw new NeedRopeContext(GetName()); \
return C4ValueConv<RType>::ToC4V(pFunc(Rope LIST(N, CONV_FROM_C4V))); \
} \
protected: \
Func pFunc; \
}; \
template <typename RType LIST(N, TYPENAMES)> \
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4PropList * LIST(N, PARS)), bool Public=true) \
{ \
new C4AulDefFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
@ -320,6 +350,11 @@ template <typename RType LIST(N, TYPENAMES)> \
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4Object * LIST(N, PARS)), bool Public=true) \
{ \
new C4AulDefObjectFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
} \
template <typename RType LIST(N, TYPENAMES)> \
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4Rope * LIST(N, PARS)), bool Public=true) \
{ \
new C4AulDefRopeFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
}
TEMPLATE(0)