mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 21:11:52 +00:00
- added an option to FindClassTentative to make eventual failure to declare the missing class non-fatal.
Damn those old mods with broken actor references. Thanks to those FxClassTypeCast may not throw fatal errors.
This commit is contained in:
parent
26b657b637
commit
6c92525fcd
4 changed files with 32 additions and 24 deletions
|
@ -2322,12 +2322,19 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
||||||
const PClass *existclass = FindClass(name);
|
const PClass *existclass = FindClass(name);
|
||||||
|
|
||||||
// This is a placeholder so fill it in
|
// This is a placeholder so fill it in
|
||||||
if (existclass != NULL && existclass->Size == (unsigned)-1)
|
if (existclass != NULL && (existclass->Size == TClass_Fatal || existclass->Size == TClass_Nonfatal))
|
||||||
{
|
{
|
||||||
type = const_cast<PClass*>(existclass);
|
type = const_cast<PClass*>(existclass);
|
||||||
if (!IsDescendantOf(type->ParentClass))
|
if (!IsDescendantOf(type->ParentClass))
|
||||||
{
|
{
|
||||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
if (existclass->Size == TClass_Fatal)
|
||||||
|
{
|
||||||
|
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_RED "%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DPrintf("Defining placeholder class %s\n", name.GetChars());
|
DPrintf("Defining placeholder class %s\n", name.GetChars());
|
||||||
notnew = true;
|
notnew = true;
|
||||||
|
@ -2380,7 +2387,7 @@ unsigned int PClass::Extend(unsigned int extension)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
PClass *PClass::FindClassTentative(FName name)
|
PClass *PClass::FindClassTentative(FName name, bool fatal)
|
||||||
{
|
{
|
||||||
if (name == NAME_None)
|
if (name == NAME_None)
|
||||||
{
|
{
|
||||||
|
@ -2400,7 +2407,7 @@ PClass *PClass::FindClassTentative(FName name)
|
||||||
|
|
||||||
type->TypeName = name;
|
type->TypeName = name;
|
||||||
type->ParentClass = this;
|
type->ParentClass = this;
|
||||||
type->Size = -1;
|
type->Size = fatal? TClass_Fatal : TClass_Nonfatal;
|
||||||
type->bRuntimeClass = true;
|
type->bRuntimeClass = true;
|
||||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), (intptr_t)type->Outer, name, bucket);
|
TypeTable.AddType(type, RUNTIME_CLASS(PClass), (intptr_t)type->Outer, name, bucket);
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -599,6 +599,12 @@ public:
|
||||||
|
|
||||||
// Meta-info for every class derived from DObject ---------------------------
|
// Meta-info for every class derived from DObject ---------------------------
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TClass_Fatal = UINT_MAX,
|
||||||
|
TClass_Nonfatal = UINT_MAX - 1
|
||||||
|
};
|
||||||
|
|
||||||
class PClassClass;
|
class PClassClass;
|
||||||
class PClass : public PStruct
|
class PClass : public PStruct
|
||||||
{
|
{
|
||||||
|
@ -661,7 +667,7 @@ public:
|
||||||
static PClassActor *FindActor(const FString &name) { return FindActor(FName(name, true)); }
|
static PClassActor *FindActor(const FString &name) { return FindActor(FName(name, true)); }
|
||||||
static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); }
|
static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); }
|
||||||
static PClassActor *FindActor(FName name);
|
static PClassActor *FindActor(FName name);
|
||||||
PClass *FindClassTentative(FName name); // not static!
|
PClass *FindClassTentative(FName name, bool fatal = true); // not static!
|
||||||
|
|
||||||
static TArray<PClass *> AllClasses;
|
static TArray<PClass *> AllClasses;
|
||||||
|
|
||||||
|
|
|
@ -340,10 +340,15 @@ static void FinishThingdef()
|
||||||
{
|
{
|
||||||
PClassActor *ti = PClassActor::AllActorClasses[i];
|
PClassActor *ti = PClassActor::AllActorClasses[i];
|
||||||
|
|
||||||
if (ti->Size == (unsigned)-1)
|
if (ti->Size == TClass_Fatal || ti->Size == TClass_Nonfatal)
|
||||||
{
|
{
|
||||||
Printf("Class %s referenced but not defined\n", ti->TypeName.GetChars());
|
Printf(TEXTCOLOR_RED "Class %s referenced but not defined\n", ti->TypeName.GetChars());
|
||||||
errorcount++;
|
if (ti->Size == TClass_Fatal) errorcount++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In order to prevent a crash, this class needs to be completed, even though it defines nothing.
|
||||||
|
ti->ParentClass->CreateDerivedClass(ti->TypeName, ti->ParentClass->Size);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3546,23 +3546,13 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
if (clsname != NAME_None)
|
if (clsname != NAME_None)
|
||||||
{
|
{
|
||||||
cls = desttype->FindClassTentative(clsname);
|
// for backwards compatibility with old times it cannot be made a fatal error, if the class is not defined. :(
|
||||||
if (cls == NULL)
|
cls = desttype->FindClassTentative(clsname, false);
|
||||||
|
if (!cls->IsDescendantOf(desttype))
|
||||||
{
|
{
|
||||||
/* lax */
|
ScriptPosition.Message(MSG_ERROR,"class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
|
||||||
// Since this happens in released WADs it must pass without a terminal error... :(
|
delete this;
|
||||||
ScriptPosition.Message(MSG_WARNING,
|
return NULL;
|
||||||
"Unknown class name '%s'",
|
|
||||||
clsname.GetChars(), desttype->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!cls->IsDescendantOf(desttype))
|
|
||||||
{
|
|
||||||
ScriptPosition.Message(MSG_ERROR,"class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
|
|
||||||
delete this;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ScriptPosition.Message(MSG_DEBUG,"resolving '%s' as class name", clsname.GetChars());
|
ScriptPosition.Message(MSG_DEBUG,"resolving '%s' as class name", clsname.GetChars());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue