Script: Add def and effect parameter types

Günther Brammer 2011-09-24 18:37:28 +02:00
parent dbaa638166
commit c63b66e909
7 changed files with 72 additions and 23 deletions

View File

@ -45,12 +45,6 @@
<col>A general purpose object type. <funclink>GetProperty</funclink> and <funclink>SetProperty</funclink> can get respectively set properties. If the property <code>"Prototype"</code> is set, and a property that is not set is gotten, the prototype is asked.</col>
<col><code>{ foo = 0, &quot;bar baz&quot; = 13, Prototype = Clonk }</code></col>
</row>
<row>
<col><code>object</code></col>
<col>Ingame Object</col>
<col>Reference to an existing object at runtime. No direct representation. See <funclink>FindObject</funclink>()</col>
<col><code>CreateObject(Clonk)</code></col>
</row>
<row>
<col><code>nil</code></col>
<col></col>
@ -64,11 +58,23 @@
<col></col>
</row>
<row>
<col><code>id</code></col>
<col>definition id</col>
<col>ID of an object definition (see <emlink href="definition/index.html#ObjektundEntwicklerIdentifikation">Object Definitions</emlink>).Will be changed into a proplist immediately.</col>
<col><code>def</code></col>
<col><emlink href="definition/index.html">Object Definition</emlink></col>
<col>Represents a DefCore.txt and the associated Script.c. A special kind of proplist.</col>
<col><code>Clonk</code></col>
</row>
<row>
<col><code>object</code></col>
<col>Ingame Object</col>
<col>An instance of an Object Definition. A special kind of proplist.</col>
<col><code><funclink>CreateObject</funclink>(Clonk)</code></col>
</row>
<row>
<col><code>effect</code></col>
<col><emlink href="script/Effects.html">Effect</emlink></col>
<col>A special kind of proplist with associated timers and stacking callbacks.</col>
<col><code><funclink>AddEffect</funclink>("Shiny", nil, 1)</code></col>
</row>
</table>
</text>
<h>Arrays</h>
@ -118,7 +124,7 @@
<li>All values except for <code>false</code>, <code>nil</code> and <code>0</code> are treated as <code>true</code> when a bool is required.</li>
<li><code>nil</code> and <code>false</code> can be converted to <code>0</code>. <code>true</code> can be converted to <code>1</code>.</li>
<li><code>nil</code> can always be used as a function parameter, if the function doesn't implement a separate check.</li>
<li>If an object has been converted into a proplist then it can be converted back to an object. Otherwise proplists cannot be converted into objects.</li>
<li>Objects, Definitions and Effects can be converted to proplists, and then back. Normal proplists cannot be converted into them.</li>
</ul>
</text>
</part>

View File

@ -4431,7 +4431,7 @@ bool C4Object::GetDragImage(C4Object **drag_object, C4ID *drag_id)
// determine drag object/id
C4Object *obj=NULL; C4ID id;
if (parV.CheckConversion(C4V_Object)) obj = parV.getObj();
else if (parV.GetType() == C4V_PropList) id = parV.getC4ID();
else if (parV.CheckConversion(C4V_Def)) id = parV.getC4ID();
if (drag_object) *drag_object = obj;
if (drag_id) *drag_id = id;
// drag possible, even w./o image

View File

@ -195,14 +195,14 @@ template <> struct C4ValueConv<C4PropList *>
};
template <> struct C4ValueConv<C4Effect *>
{
inline static C4V_Type Type() { return C4V_PropList; }
inline static C4V_Type Type() { return C4V_Effect; }
inline static C4Effect *FromC4V(C4Value &v) { C4PropList * p = v.getPropList(); return p ? p->GetEffect() : 0; }
inline static C4Effect *_FromC4V(C4Value &v) { C4PropList * p = v._getPropList(); return p ? p->GetEffect() : 0; }
inline static C4Value ToC4V(C4Effect *v) { return C4VPropList(v); }
};
template <> struct C4ValueConv<C4Def *>
{
inline static C4V_Type Type() { return C4V_PropList; }
inline static C4V_Type Type() { return C4V_Def; }
inline static C4Def *FromC4V(C4Value &v) { C4PropList * p = v.getPropList(); return p ? p->GetDef() : 0; }
inline static C4Def *_FromC4V(C4Value &v) { C4PropList * p = v._getPropList(); return p ? p->GetDef() : 0; }
inline static C4Value ToC4V(C4Def *v) { return C4VPropList(v); }

View File

@ -82,6 +82,8 @@
#define C4AUL_TypeInt "int"
#define C4AUL_TypeBool "bool"
#define C4AUL_TypeC4ID "id"
#define C4AUL_TypeDef "def"
#define C4AUL_TypeEffect "effect"
#define C4AUL_TypeC4Object "object"
#define C4AUL_TypePropList "proplist"
#define C4AUL_TypeString "string"
@ -1496,12 +1498,21 @@ void C4AulParseState::Parse_FuncHead()
// type identifier?
if (SEqual(Idtf, C4AUL_TypeInt)) { Fn->ParType[cpar] = C4V_Int; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeBool)) { Fn->ParType[cpar] = C4V_Bool; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeC4ID)) { Fn->ParType[cpar] = C4V_PropList; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeC4ID)) { Fn->ParType[cpar] = C4V_Def; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeDef)) { Fn->ParType[cpar] = C4V_Def; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeEffect)) { Fn->ParType[cpar] = C4V_Effect; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeC4Object)) { Fn->ParType[cpar] = C4V_Object; Shift(); }
else if (SEqual(Idtf, C4AUL_TypePropList)) { Fn->ParType[cpar] = C4V_PropList; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeString)) { Fn->ParType[cpar] = C4V_String; Shift(); }
else if (SEqual(Idtf, C4AUL_TypeArray)) { Fn->ParType[cpar] = C4V_Array; Shift(); }
if (TokenType != ATT_IDTF)
if (TokenType == ATT_BCLOSE || TokenType == ATT_COMMA)
{
Fn->ParNamed.AddName(Idtf);
++Fn->ParCount;
if (Config.Developer.ExtraWarnings)
Warn(FormatString("'%s' used as parameter name", Idtf).getData());
}
else if (TokenType != ATT_IDTF)
{
UnexpectedToken("parameter name");
}

View File

@ -357,6 +357,8 @@ static long FnAsyncRandom(C4AulContext *cthr, long iRange)
static int FnGetType(C4AulContext *cthr, const C4Value & Value)
{
// dynamic types
if (Value.CheckConversion(C4V_Def)) return C4V_Def;
if (Value.CheckConversion(C4V_Effect)) return C4V_Effect;
if (Value.CheckConversion(C4V_Object)) return C4V_Object;
// static types
return Value.GetType();
@ -604,6 +606,8 @@ C4ScriptConstDef C4ScriptConstMap[]=
{ "C4V_Int", C4V_Int, C4V_Int},
{ "C4V_Bool", C4V_Int, C4V_Bool},
{ "C4V_C4Object", C4V_Int, C4V_Object},
{ "C4V_Effect", C4V_Int, C4V_Effect},
{ "C4V_Def", C4V_Int, C4V_Def},
{ "C4V_String", C4V_Int, C4V_String},
{ "C4V_Array", C4V_Int, C4V_Array},
{ "C4V_PropList", C4V_Int, C4V_PropList},

View File

@ -54,18 +54,15 @@ const char* GetC4VName(const C4V_Type Type)
return "any";
case C4V_Object:
return "object";
case C4V_Def:
return "def";
case C4V_Effect:
return "effect";
default:
return "!Fehler!";
}
}
bool C4Value::FnCnvObject() const
{
// try casting
if (Data.PropList->GetObject()) return true;
return false;
}
C4Value::C4Value(C4Object *pObj): NextRef(NULL), Type(pObj ? C4V_PropList : C4V_Nil)
{
Data.PropList = pObj; AddDataRef();
@ -83,6 +80,27 @@ C4Object * C4Value::_getObj() const
C4Value C4VObj(C4Object *pObj) { return C4Value(static_cast<C4PropList*>(pObj)); }
bool C4Value::FnCnvObject() const
{
// try casting
if (Data.PropList->GetObject()) return true;
return false;
}
bool C4Value::FnCnvDef() const
{
// try casting
if (Data.PropList->GetDef()) return true;
return false;
}
bool C4Value::FnCnvEffect() const
{
// try casting
if (Data.PropList->GetEffect()) return true;
return false;
}
bool C4Value::WarnAboutConversion(C4V_Type Type, C4V_Type vtToType)
{
switch (vtToType)
@ -90,11 +108,13 @@ bool C4Value::WarnAboutConversion(C4V_Type Type, C4V_Type vtToType)
case C4V_Nil: return Type != C4V_Nil && Type != C4V_Any;
case C4V_Int: return Type != C4V_Int && Type != C4V_Nil && Type != C4V_Bool && Type != C4V_Any;
case C4V_Bool: return false;
case C4V_PropList: return Type != C4V_PropList && Type != C4V_Object && Type != C4V_Nil && Type != C4V_Any;
case C4V_PropList: return Type != C4V_PropList && Type != C4V_Effect && Type != C4V_Def && Type != C4V_Object && Type != C4V_Nil && Type != C4V_Any;
case C4V_String: return Type != C4V_String && Type != C4V_Nil && Type != C4V_Any;
case C4V_Array: return Type != C4V_Array && Type != C4V_Nil && Type != C4V_Any;
case C4V_Any: return false;
case C4V_Def: return Type != C4V_Def && Type != C4V_Object && Type != C4V_PropList && Type != C4V_Nil && Type != C4V_Any;
case C4V_Object: return Type != C4V_Object && Type != C4V_PropList && Type != C4V_Nil && Type != C4V_Any;
case C4V_Effect: return Type != C4V_Effect && Type != C4V_PropList && Type != C4V_Nil && Type != C4V_Any;
default: assert(!"C4Value::ConvertTo: impossible conversion target"); return false;
}
}

View File

@ -41,6 +41,8 @@ enum C4V_Type
// for typechecks
C4V_Any,
C4V_Object,
C4V_Def,
C4V_Effect,
};
// last C4V_Type that doesn't vanish in Denumerate
#define C4V_Last ((int) C4V_Array)
@ -157,6 +159,8 @@ public:
case C4V_Array: return Type == C4V_Array || Type == C4V_Nil || (Type == C4V_Int && !*this);
case C4V_Any: return true;
case C4V_Object: return (Type == C4V_PropList && FnCnvObject()) || Type == C4V_Nil || (Type == C4V_Int && !*this);
case C4V_Def: return (Type == C4V_PropList && FnCnvDef()) || Type == C4V_Nil || (Type == C4V_Int && !*this);
case C4V_Effect: return (Type == C4V_PropList && FnCnvEffect()) || Type == C4V_Nil || (Type == C4V_Int && !*this);
default: assert(!"C4Value::CheckParConversion: impossible conversion target"); return false;
}
}
@ -172,6 +176,8 @@ public:
case C4V_Array: return Type == C4V_Array;
case C4V_Any: return true;
case C4V_Object: return Type == C4V_PropList && FnCnvObject();
case C4V_Def: return Type == C4V_PropList && FnCnvDef();
case C4V_Effect: return Type == C4V_PropList && FnCnvEffect();
default: assert(!"C4Value::CheckConversion: impossible conversion target"); return false;
}
}
@ -202,6 +208,8 @@ protected:
void DelDataRef(C4V_Data Data, C4V_Type Type, C4Value *pNextRef);
bool FnCnvObject() const;
bool FnCnvDef() const;
bool FnCnvEffect() const;
void LogDeletedObjectWarning(C4PropList *);
friend class C4PropList;