- put PObjectPointer to some use.

- fixed: There was no check for compatible class pointers.
This commit is contained in:
Christoph Oelckers 2017-04-12 11:40:40 +02:00
parent bc486904cd
commit b17ab7a133
3 changed files with 17 additions and 6 deletions

View file

@ -428,6 +428,7 @@ public:
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
PClass *PointedClass() const;
};

View file

@ -56,6 +56,8 @@
#include "w_wad.h"
#include "math/cmath.h"
inline PClass *PObjectPointer::PointedClass() const { return static_cast<PClass*>(PointedType); }
extern FRandom pr_exrandom;
FMemArena FxAlloc(65536);
int utf8_decode(const char *src, int *size);
@ -294,10 +296,18 @@ static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompar
// A type is always compatible to itself.
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 (fromtype->PointedType->IsKindOf(RUNTIME_CLASS(PClass)) && totype->PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
if (source->IsA(RUNTIME_CLASS(PObjectPointer)) && dest->IsA(RUNTIME_CLASS(PObjectPointer)))
{
auto fromcls = static_cast<PClass *>(fromtype->PointedType);
auto tocls = static_cast<PClass *>(totype->PointedType);
auto fromcls = static_cast<PObjectPointer*>(source)->PointedClass();
auto tocls = static_cast<PObjectPointer*>(dest)->PointedClass();
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
return (fromcls->IsDescendantOf(tocls));
}
// The same rules apply to class pointers. A child type can be assigned to a variable of a parent type.
if (source->IsA(RUNTIME_CLASS(PClassPointer)) && dest->IsA(RUNTIME_CLASS(PClassPointer)))
{
auto fromcls = static_cast<PClassPointer*>(source)->ClassRestriction;
auto tocls = static_cast<PClassPointer*>(dest)->ClassRestriction;
if (forcompare && tocls->IsDescendantOf(fromcls)) return true;
return (fromcls->IsDescendantOf(tocls));
}
@ -6958,8 +6968,8 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
if (membervar->SymbolName == NAME_Default)
{
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))
|| !static_cast<PPointer *>(classx->ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(AActor)))
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PObjectPointer))
|| !static_cast<PObjectPointer *>(classx->ValueType)->PointedClass()->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type");
delete this;

View file

@ -333,7 +333,7 @@ public:
bool IsPointer() const { return ValueType->GetRegType() == REGT_POINTER; }
bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3; };
bool IsBoolCompat() const { return ValueType->GetRegCount() == 1 && (ValueType->GetRegType() == REGT_INT || ValueType->GetRegType() == REGT_FLOAT || ValueType->GetRegType() == REGT_POINTER); }
bool IsObject() const { return ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && !ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)) && ValueType != TypeNullPtr && static_cast<PPointer*>(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PClass)); }
bool IsObject() const { return ValueType->IsKindOf(RUNTIME_CLASS(PObjectPointer)); }
bool IsArray() const { return ValueType->IsKindOf(RUNTIME_CLASS(PArray)) || (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PArray))); }
bool IsResizableArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PStaticArray))); } // can only exist in pointer form.
bool IsDynamicArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PDynArray))); }