mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- created an export for P_SpawnMissile so that I can do some tests with functions.
- allow class extensions. These are separate blocks in different files that get concatenated to one class body for processing. The reason is to allow spreading the many functions in Actor over multiple files, so that they remain manageable. For example, all the Doom action functions should be in their respective files, but their symbols need to be in Actor. To extend a class, both files need to be in the same translation unit, so it won't allow user-side extension of internal classes.
This commit is contained in:
parent
f9cd2c9af7
commit
a2116fc7bf
9 changed files with 60 additions and 6 deletions
|
@ -5824,6 +5824,15 @@ AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor
|
|||
return P_SpawnMissileXYZ (source->PosPlusZ(32 + source->GetBobOffset()), source, dest, type, true, owner);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, P_SpawnMissile)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(dest, AActor);
|
||||
PARAM_CLASS(type, AActor);
|
||||
PARAM_OBJECT_OPT(owner, AActor) { owner = self; }
|
||||
ACTION_RETURN_OBJECT(P_SpawnMissile(self, dest, type, owner));
|
||||
}
|
||||
|
||||
AActor *P_SpawnMissileZ (AActor *source, double z, AActor *dest, PClassActor *type)
|
||||
{
|
||||
if (source == NULL)
|
||||
|
|
|
@ -151,7 +151,7 @@ std2:
|
|||
'transient' { RET(TK_Transient); }
|
||||
'final' { RET(TK_Final); }
|
||||
'throws' { RET(TK_Throws); }
|
||||
'extends' { RET(TK_Extends); }
|
||||
'extend' { RET(TK_Extend); }
|
||||
'public' { RET(TK_Public); }
|
||||
'protected' { RET(TK_Protected); }
|
||||
'private' { RET(TK_Private); }
|
||||
|
|
|
@ -89,7 +89,7 @@ xx(TK_Transient, "'transient'")
|
|||
xx(TK_Volatile, "'volatile'")
|
||||
xx(TK_Final, "'final'")
|
||||
xx(TK_Throws, "'throws'")
|
||||
xx(TK_Extends, "'extends'")
|
||||
xx(TK_Extend, "'extend'")
|
||||
xx(TK_Public, "'public'")
|
||||
xx(TK_Protected, "'protected'")
|
||||
xx(TK_Private, "'private'")
|
||||
|
|
|
@ -1013,6 +1013,7 @@ struct AFuncDesc
|
|||
|
||||
|
||||
#define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_STATE); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_OBJECT); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_FLOAT(v) do { double u = v; if (numret > 0) { assert(ret != nullptr); ret->SetFloat(u); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_INT(v) do { int u = v; if (numret > 0) { assert(ret != NULL); ret->SetInt(u); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_BOOL(v) ACTION_RETURN_INT(v)
|
||||
|
|
|
@ -171,6 +171,18 @@ class_definition(X) ::= class_head(A) class_body(B).
|
|||
X = A; /*X-overwrites-A*/
|
||||
}
|
||||
|
||||
class_head(X) ::= EXTEND CLASS(T) IDENTIFIER(A).
|
||||
{
|
||||
NEW_AST_NODE(Class,head,T);
|
||||
head->NodeName = A.Name();
|
||||
head->ParentName = nullptr;
|
||||
head->Flags = ZCC_Extension;
|
||||
head->Replaces = nullptr;
|
||||
head->Type = nullptr;
|
||||
head->Symbol = nullptr;
|
||||
X = head;
|
||||
}
|
||||
|
||||
class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C).
|
||||
{
|
||||
NEW_AST_NODE(Class,head,T);
|
||||
|
|
|
@ -61,8 +61,29 @@
|
|||
|
||||
void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
||||
{
|
||||
Classes.Push(new ZCC_ClassWork(static_cast<ZCC_Class *>(cnode), treenode));
|
||||
auto cls = Classes.Last();
|
||||
ZCC_ClassWork *cls = nullptr;
|
||||
// If this is a class extension, put the new node directly into the existing class.
|
||||
if (cnode->Flags == ZCC_Extension)
|
||||
{
|
||||
for (auto clss : Classes)
|
||||
{
|
||||
if (clss->NodeName() == cnode->NodeName)
|
||||
{
|
||||
cls = clss;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cls == nullptr)
|
||||
{
|
||||
Error(cnode, "Class %s cannot be found in the current translation unit.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Classes.Push(new ZCC_ClassWork(static_cast<ZCC_Class *>(cnode), treenode));
|
||||
cls = Classes.Last();
|
||||
}
|
||||
|
||||
auto node = cnode->Body;
|
||||
PSymbolTreeNode *childnode;
|
||||
|
@ -220,6 +241,12 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
|
|||
switch (node->NodeType)
|
||||
{
|
||||
case AST_Class:
|
||||
// a class extension should not check the tree node symbols.
|
||||
if (static_cast<ZCC_Class *>(node)->Flags == ZCC_Extension)
|
||||
{
|
||||
ProcessClass(static_cast<ZCC_Class *>(node), tnode);
|
||||
break;
|
||||
}
|
||||
case AST_Struct:
|
||||
case AST_ConstantDef:
|
||||
case AST_Enum:
|
||||
|
|
|
@ -198,6 +198,7 @@ static void InitTokenMap()
|
|||
TOKENDEF (TK_Offset, ZCC_OFFSET);
|
||||
TOKENDEF (TK_CanRaise, ZCC_CANRAISE);
|
||||
TOKENDEF (TK_Light, ZCC_LIGHT);
|
||||
TOKENDEF (TK_Extend, ZCC_EXTEND);
|
||||
|
||||
ZCC_InitOperators();
|
||||
ZCC_InitConversions();
|
||||
|
|
|
@ -32,6 +32,7 @@ enum
|
|||
ZCC_ReadOnly = 1 << 9,
|
||||
ZCC_FuncConst = 1 << 10,
|
||||
ZCC_Abstract = 1 << 11,
|
||||
ZCC_Extension = 1 << 12,
|
||||
};
|
||||
|
||||
// Function parameter modifiers
|
||||
|
|
|
@ -47,6 +47,9 @@ class Actor : Thinker native
|
|||
}
|
||||
|
||||
// Functions
|
||||
native Actor P_SpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
||||
|
||||
// DECORATE compatible functions
|
||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||
native bool IsPointerEqual(int ptr_select1, int ptr_select2);
|
||||
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
||||
|
@ -112,8 +115,8 @@ class Actor : Thinker native
|
|||
native void A_BetaSkullAttack();
|
||||
native void A_Metal();
|
||||
native void A_SpidRefire();
|
||||
native void A_BabyMetal();
|
||||
native void A_BspiAttack();
|
||||
//native void A_BabyMetal();
|
||||
//native void A_BspiAttack();
|
||||
native void A_Hoof();
|
||||
native void A_CyberAttack();
|
||||
native void A_PainAttack(class<Actor> spawntype = "LostSoul", float angle = 0, int flags = 0, int limit = -1);
|
||||
|
|
Loading…
Reference in a new issue