mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
Fix readonly for SpecialBounceHit virtual
This commit is contained in:
parent
144caa0902
commit
d848a57bac
6 changed files with 32 additions and 16 deletions
|
@ -669,7 +669,7 @@ PClass *PClass::FindClassTentative(FName name)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType)
|
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType, bool ignorePointerReadOnly)
|
||||||
{
|
{
|
||||||
auto proto = variant->Proto;
|
auto proto = variant->Proto;
|
||||||
for (unsigned i = 0; i < Virtuals.Size(); i++)
|
for (unsigned i = 0; i < Virtuals.Size(); i++)
|
||||||
|
@ -689,8 +689,22 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
|
||||||
{
|
{
|
||||||
if (proto->ArgumentTypes[a] != vproto->ArgumentTypes[a])
|
if (proto->ArgumentTypes[a] != vproto->ArgumentTypes[a])
|
||||||
{
|
{
|
||||||
fail = true;
|
if(ignorePointerReadOnly && proto->ArgumentTypes[a]->isPointer() && vproto->ArgumentTypes[a]->isPointer())
|
||||||
break;
|
{
|
||||||
|
PPointer *ppa = proto->ArgumentTypes[a]->toPointer();
|
||||||
|
PPointer *ppb = vproto->ArgumentTypes[a]->toPointer();
|
||||||
|
|
||||||
|
if(ppa->PointedType != ppb->PointedType)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fail) continue;
|
if (fail) continue;
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
void InitializeSpecials(void* addr, void* defaults, TArray<FTypeAndOffset> PClass::* Inits);
|
void InitializeSpecials(void* addr, void* defaults, TArray<FTypeAndOffset> PClass::* Inits);
|
||||||
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
||||||
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
||||||
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType);
|
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType, bool ignorePointerReadOnly);
|
||||||
PSymbol *FindSymbol(FName symname, bool searchparents) const;
|
PSymbol *FindSymbol(FName symname, bool searchparents) const;
|
||||||
PField *AddField(FName name, PType *type, uint32_t flags, int fileno = 0);
|
PField *AddField(FName name, PType *type, uint32_t flags, int fileno = 0);
|
||||||
void InitializeDefaults();
|
void InitializeDefaults();
|
||||||
|
|
|
@ -291,23 +291,21 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
|
||||||
if (!forcompare && fromtype->IsConst && !totype->IsConst) return false;
|
if (!forcompare && fromtype->IsConst && !totype->IsConst) return false;
|
||||||
// A type is always compatible to itself.
|
// A type is always compatible to itself.
|
||||||
if (fromtype == totype) return true;
|
if (fromtype == totype) return true;
|
||||||
// Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type.
|
|
||||||
if (source->isObjectPointer() && dest->isObjectPointer())
|
if (source->isObjectPointer() && dest->isObjectPointer())
|
||||||
{
|
{ // Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type.
|
||||||
auto fromcls = static_cast<PObjectPointer*>(source)->PointedClass();
|
auto fromcls = static_cast<PObjectPointer*>(source)->PointedClass();
|
||||||
auto tocls = static_cast<PObjectPointer*>(dest)->PointedClass();
|
auto tocls = static_cast<PObjectPointer*>(dest)->PointedClass();
|
||||||
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
||||||
return (fromcls->IsDescendantOf(tocls));
|
return (fromcls->IsDescendantOf(tocls));
|
||||||
}
|
}
|
||||||
// The same rules apply to class pointers. A child type can be assigned to a variable of a parent type.
|
else if (source->isClassPointer() && dest->isClassPointer())
|
||||||
if (source->isClassPointer() && dest->isClassPointer())
|
{ // The same rules apply to class pointers. A child type can be assigned to a variable of a parent type.
|
||||||
{
|
|
||||||
auto fromcls = static_cast<PClassPointer*>(source)->ClassRestriction;
|
auto fromcls = static_cast<PClassPointer*>(source)->ClassRestriction;
|
||||||
auto tocls = static_cast<PClassPointer*>(dest)->ClassRestriction;
|
auto tocls = static_cast<PClassPointer*>(dest)->ClassRestriction;
|
||||||
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
|
||||||
return (fromcls->IsDescendantOf(tocls));
|
return (fromcls->IsDescendantOf(tocls));
|
||||||
}
|
}
|
||||||
if(source->isFunctionPointer() && dest->isFunctionPointer())
|
else if(source->isFunctionPointer() && dest->isFunctionPointer())
|
||||||
{
|
{
|
||||||
auto from = static_cast<PFunctionPointer*>(source);
|
auto from = static_cast<PFunctionPointer*>(source);
|
||||||
auto to = static_cast<PFunctionPointer*>(dest);
|
auto to = static_cast<PFunctionPointer*>(dest);
|
||||||
|
@ -315,6 +313,10 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
|
||||||
|
|
||||||
return to->PointedType == TypeVoid || (AreCompatibleFnPtrTypes((PPrototype *)to->PointedType, (PPrototype *)from->PointedType) && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope));
|
return to->PointedType == TypeVoid || (AreCompatibleFnPtrTypes((PPrototype *)to->PointedType, (PPrototype *)from->PointedType) && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope));
|
||||||
}
|
}
|
||||||
|
else if(source->isRealPointer() && dest->isRealPointer())
|
||||||
|
{
|
||||||
|
return fromtype->PointedType == totype->PointedType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2764,7 +2764,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
// [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed.
|
// [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed.
|
||||||
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
|
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exactReturnType = mVersion < MakeVersion(4, 4);
|
bool exactReturnType = mVersion < MakeVersion(4, 4);
|
||||||
PClass *clstype = forclass? static_cast<PClassType *>(c->Type())->Descriptor : nullptr;
|
PClass *clstype = forclass? static_cast<PClassType *>(c->Type())->Descriptor : nullptr;
|
||||||
if (varflags & VARF_Virtual)
|
if (varflags & VARF_Virtual)
|
||||||
|
@ -2785,7 +2785,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
|
|
||||||
auto parentfunc = clstype->ParentClass? dyn_cast<PFunction>(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr;
|
auto parentfunc = clstype->ParentClass? dyn_cast<PFunction>(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr;
|
||||||
|
|
||||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType);
|
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12));
|
||||||
// specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types.
|
// specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types.
|
||||||
if (varflags & VARF_Override)
|
if (varflags & VARF_Override)
|
||||||
{
|
{
|
||||||
|
@ -2867,7 +2867,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
}
|
}
|
||||||
else if (forclass)
|
else if (forclass)
|
||||||
{
|
{
|
||||||
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType);
|
int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12));
|
||||||
if (virtindex != -1)
|
if (virtindex != -1)
|
||||||
{
|
{
|
||||||
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());
|
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());
|
||||||
|
|
|
@ -565,7 +565,7 @@ class Actor : Thinker native
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called when a missile bounces off something.
|
// This is called when a missile bounces off something.
|
||||||
virtual int SpecialBounceHit(Actor bounceMobj, Line bounceLine, SecPlane bouncePlane)
|
virtual int SpecialBounceHit(Actor bounceMobj, Line bounceLine, readonly<SecPlane> bouncePlane)
|
||||||
{
|
{
|
||||||
return MHIT_DEFAULT;
|
return MHIT_DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -847,7 +847,7 @@ class Actor : Thinker native
|
||||||
native void PlayPushSound();
|
native void PlayPushSound();
|
||||||
native bool BounceActor(Actor blocking, bool onTop);
|
native bool BounceActor(Actor blocking, bool onTop);
|
||||||
native bool BounceWall(Line l = null);
|
native bool BounceWall(Line l = null);
|
||||||
native bool BouncePlane(SecPlane plane);
|
native bool BouncePlane(readonly<SecPlane> plane);
|
||||||
native void PlayBounceSound(bool onFloor);
|
native void PlayBounceSound(bool onFloor);
|
||||||
native bool ReflectOffActor(Actor blocking);
|
native bool ReflectOffActor(Actor blocking);
|
||||||
|
|
||||||
|
|
|
@ -270,7 +270,7 @@ struct SecPlane native play
|
||||||
native clearscope int PointOnSide(Vector3 pos) const;
|
native clearscope int PointOnSide(Vector3 pos) const;
|
||||||
native clearscope double ZatPoint (Vector2 v) const;
|
native clearscope double ZatPoint (Vector2 v) const;
|
||||||
native clearscope double ZatPointDist(Vector2 v, double dist) const;
|
native clearscope double ZatPointDist(Vector2 v, double dist) const;
|
||||||
native clearscope bool isEqual(Secplane other) const;
|
native clearscope bool isEqual(readonly<Secplane> other) const;
|
||||||
//native void ChangeHeight(double hdiff);
|
//native void ChangeHeight(double hdiff);
|
||||||
native clearscope double GetChangedHeight(double hdiff) const;
|
native clearscope double GetChangedHeight(double hdiff) const;
|
||||||
native clearscope double HeightDiff(double oldd, double newd = 1e37) const;
|
native clearscope double HeightDiff(double oldd, double newd = 1e37) const;
|
||||||
|
|
Loading…
Reference in a new issue