Fix inherited data members not being saved
* Removed erroneous 'parent instance' from CBotVarClass. * Fixed output of CBVarClass::GetValString()fix-squashed-planets
parent
fabbdda964
commit
993a6adf6e
|
@ -908,13 +908,18 @@ bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar)
|
||||||
|
|
||||||
if (isClass && p == nullptr) // set id for each item in this instance
|
if (isClass && p == nullptr) // set id for each item in this instance
|
||||||
{
|
{
|
||||||
CBotVar* pVars = pNew->GetItemList();
|
CBotClass* pClass = pNew->GetClass();
|
||||||
CBotVar* pv = pNew->GetClass()->GetVar();
|
CBotVar* pVars = (static_cast<CBotVarClass*>(pNew))->m_pVar;
|
||||||
|
while (pClass != nullptr && pVars != nullptr)
|
||||||
|
{
|
||||||
|
CBotVar* pv = pClass->GetVar();
|
||||||
while (pVars != nullptr && pv != nullptr)
|
while (pVars != nullptr && pv != nullptr)
|
||||||
{
|
{
|
||||||
pVars->m_ident = pv->m_ident;
|
pVars->m_ident = pv->m_ident;
|
||||||
pv = pv->GetNext();
|
pVars = pVars->m_next;
|
||||||
pVars = pVars->GetNext();
|
pv = pv->m_next;
|
||||||
|
}
|
||||||
|
pClass = pClass->GetParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type) : C
|
||||||
// official type for this object
|
// official type for this object
|
||||||
|
|
||||||
m_pClass = nullptr;
|
m_pClass = nullptr;
|
||||||
m_pParent = nullptr;
|
|
||||||
m_binit = InitType::UNDEF;
|
m_binit = InitType::UNDEF;
|
||||||
m_bStatic = false;
|
m_bStatic = false;
|
||||||
m_mPrivate = ProtectionLevel::Public;
|
m_mPrivate = ProtectionLevel::Public;
|
||||||
|
@ -63,14 +62,9 @@ CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type) : C
|
||||||
m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum();
|
m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum();
|
||||||
|
|
||||||
// add to the list
|
// add to the list
|
||||||
m_instances.insert(this);
|
if (m_ItemIdent != 0) m_instances.insert(this);
|
||||||
|
|
||||||
CBotClass* pClass = type.GetClass();
|
CBotClass* pClass = type.GetClass();
|
||||||
if ( pClass != nullptr && pClass->GetParent() != nullptr )
|
|
||||||
{
|
|
||||||
// also creates an instance of the parent class
|
|
||||||
m_pParent = new CBotVarClass(name, CBotTypResult(type.GetType(), pClass->GetParent()) ); //, nIdent);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetClass( pClass );
|
SetClass( pClass );
|
||||||
|
|
||||||
|
@ -82,11 +76,8 @@ CBotVarClass::~CBotVarClass( )
|
||||||
if ( m_CptUse != 0 )
|
if ( m_CptUse != 0 )
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
if ( m_pParent ) delete m_pParent;
|
|
||||||
m_pParent = nullptr;
|
|
||||||
|
|
||||||
// removes the class list
|
// removes the class list
|
||||||
m_instances.erase(this);
|
if (m_ItemIdent != 0) m_instances.erase(this);
|
||||||
|
|
||||||
delete m_pVar;
|
delete m_pVar;
|
||||||
}
|
}
|
||||||
|
@ -113,10 +104,6 @@ void CBotVarClass::Copy(CBotVar* pSrc, bool bName)
|
||||||
m_binit = p->m_binit;
|
m_binit = p->m_binit;
|
||||||
//- m_bStatic = p->m_bStatic;
|
//- m_bStatic = p->m_bStatic;
|
||||||
m_pClass = p->m_pClass;
|
m_pClass = p->m_pClass;
|
||||||
if ( p->m_pParent )
|
|
||||||
{
|
|
||||||
assert(0); // "que faire du pParent";
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_next = nullptr;
|
// m_next = nullptr;
|
||||||
m_pUserPtr = p->m_pUserPtr;
|
m_pUserPtr = p->m_pUserPtr;
|
||||||
|
@ -162,9 +149,11 @@ void CBotVarClass::SetClass(CBotClass* pClass)//, int &nIdent)
|
||||||
|
|
||||||
if (pClass == nullptr) return;
|
if (pClass == nullptr) return;
|
||||||
|
|
||||||
CBotVar* pv = pClass->GetVar(); // first on a list
|
CBotVar* pv = nullptr;
|
||||||
while ( pv != nullptr )
|
while (pClass != nullptr)
|
||||||
{
|
{
|
||||||
|
if ( pv == nullptr ) pv = pClass->GetVar();
|
||||||
|
if ( pv == nullptr ) { pClass = pClass->GetParent(); continue; }
|
||||||
// seeks the maximum dimensions of the table
|
// seeks the maximum dimensions of the table
|
||||||
CBotInstr* p = pv->m_LimExpr; // the different formulas
|
CBotInstr* p = pv->m_LimExpr; // the different formulas
|
||||||
if ( p != nullptr )
|
if ( p != nullptr )
|
||||||
|
@ -214,6 +203,7 @@ void CBotVarClass::SetClass(CBotClass* pClass)//, int &nIdent)
|
||||||
if ( m_pVar == nullptr) m_pVar = pn;
|
if ( m_pVar == nullptr) m_pVar = pn;
|
||||||
else m_pVar->AddNext( pn );
|
else m_pVar->AddNext( pn );
|
||||||
pv = pv->GetNext();
|
pv = pv->GetNext();
|
||||||
|
if ( pv == nullptr ) pClass = pClass->GetParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +236,6 @@ CBotVar* CBotVarClass::GetItem(const std::string& name)
|
||||||
p = p->GetNext();
|
p = p->GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_pParent != nullptr ) return m_pParent->GetItem(name);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +250,6 @@ CBotVar* CBotVarClass::GetItemRef(int nIdent)
|
||||||
p = p->GetNext();
|
p = p->GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_pParent != nullptr ) return m_pParent->GetItemRef(nIdent);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,32 +299,46 @@ std::string CBotVarClass::GetValString()
|
||||||
{
|
{
|
||||||
res = m_pClass->GetName() + std::string("( ");
|
res = m_pClass->GetName() + std::string("( ");
|
||||||
|
|
||||||
CBotVarClass* my = this;
|
CBotClass* pClass = m_pClass;
|
||||||
while ( my != nullptr )
|
long prevID = 0;
|
||||||
{
|
{
|
||||||
CBotVar* pv = my->m_pVar;
|
CBotVar* pv = m_pVar;
|
||||||
while ( pv != nullptr )
|
if (pv != nullptr) while (true)
|
||||||
{
|
{
|
||||||
|
if (pv->GetUniqNum() < prevID)
|
||||||
|
{
|
||||||
|
pClass = pClass->GetParent();
|
||||||
|
if (pClass == nullptr) break;
|
||||||
|
res += " ) extends ";
|
||||||
|
res += pClass->GetName();
|
||||||
|
res += "( ";
|
||||||
|
if (pClass->GetVar() == nullptr) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevID = pv->GetUniqNum();
|
||||||
|
|
||||||
res += pv->GetName() + std::string("=");
|
res += pv->GetName() + std::string("=");
|
||||||
|
|
||||||
if ( pv->IsStatic() )
|
if ( pv->IsStatic() )
|
||||||
{
|
{
|
||||||
CBotVar* pvv = my->m_pClass->GetItem(pv->GetName());
|
res += pClass->GetItemRef(prevID)->GetValString();
|
||||||
res += pvv->GetValString();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res += pv->GetValString();
|
res += pv->GetValString();
|
||||||
}
|
}
|
||||||
pv = pv->GetNext();
|
pv = pv->GetNext();
|
||||||
if ( pv != nullptr ) res += ", ";
|
if ( pv == nullptr ) break;
|
||||||
|
if ( pv->GetUniqNum() > prevID ) res += ", ";
|
||||||
}
|
}
|
||||||
my = my->m_pParent;
|
|
||||||
if ( my != nullptr )
|
if (pClass != nullptr) while (true)
|
||||||
{
|
{
|
||||||
res += ") extends ";
|
pClass = pClass->GetParent();
|
||||||
res += my->m_pClass->GetName();
|
if (pClass == nullptr) break;
|
||||||
res += " (";
|
res += " ) extends ";
|
||||||
|
res += pClass->GetName();
|
||||||
|
res += "( ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,6 @@ private:
|
||||||
static std::set<CBotVarClass*> m_instances;
|
static std::set<CBotVarClass*> m_instances;
|
||||||
//! Class definition
|
//! Class definition
|
||||||
CBotClass* m_pClass;
|
CBotClass* m_pClass;
|
||||||
//! Parent class instance
|
|
||||||
CBotVarClass* m_pParent;
|
|
||||||
//! Class members
|
//! Class members
|
||||||
CBotVar* m_pVar;
|
CBotVar* m_pVar;
|
||||||
//! Reference counter
|
//! Reference counter
|
||||||
|
|
|
@ -747,6 +747,48 @@ TEST_F(CBotUT, ToString)
|
||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ClassToString_2()\n"
|
||||||
|
"{\n"
|
||||||
|
" string s = new TestClass;\n"
|
||||||
|
" ASSERT(s == \"Pointer to TestClass( )\");\n"
|
||||||
|
"}\n"
|
||||||
|
"public class TestClass { /* no fields */ }\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ClassInheritanceToString()\n"
|
||||||
|
"{\n"
|
||||||
|
" string s = new SubClass;\n"
|
||||||
|
" ASSERT(s == \"Pointer to SubClass( c=7, d=8, e=9 ) extends MidClass( b=4, c=5, d=6 ) extends BaseClass( a=1, b=2, c=3 )\");\n"
|
||||||
|
"}\n"
|
||||||
|
"public class BaseClass { int a = 1, b = 2, c = 3; }\n"
|
||||||
|
"public class MidClass extends BaseClass { int b = 4, c = 5, d = 6; }\n"
|
||||||
|
"public class SubClass extends MidClass { int c = 7, d = 8, e = 9; }\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ClassInheritanceToString_2()\n"
|
||||||
|
"{\n"
|
||||||
|
" string s = new SubClass;\n"
|
||||||
|
" ASSERT(s == \"Pointer to SubClass( c=7, d=8, e=9 ) extends MidClass( ) extends BaseClass( a=1, b=2, c=3 )\");\n"
|
||||||
|
"}\n"
|
||||||
|
"public class BaseClass { int a = 1, b = 2, c = 3; }\n"
|
||||||
|
"public class MidClass extends BaseClass { /* no fields */ }\n"
|
||||||
|
"public class SubClass extends MidClass { int c = 7, d = 8, e = 9; }\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void ClassInheritanceToString_3()\n"
|
||||||
|
"{\n"
|
||||||
|
" string s = new SubClass;\n"
|
||||||
|
" ASSERT(s == \"Pointer to SubClass( c=7, d=8, e=9 ) extends MidClass( ) extends BaseClass( )\");\n"
|
||||||
|
"}\n"
|
||||||
|
"public class BaseClass { /* no fields */ }\n"
|
||||||
|
"public class MidClass extends BaseClass { /* no fields */ }\n"
|
||||||
|
"public class SubClass extends MidClass { int c = 7, d = 8, e = 9; }\n"
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: IntrinsicClassToString ? (e.g. point)
|
// TODO: IntrinsicClassToString ? (e.g. point)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3197,3 +3239,25 @@ TEST_F(CBotUT, ClassTestPrivateMethod)
|
||||||
CBotErrPrivate
|
CBotErrPrivate
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CBotUT, ClassTestSaveInheritedMembers)
|
||||||
|
{
|
||||||
|
auto publicProgram = ExecuteTest(
|
||||||
|
"public class TestClass { int a = 123; }\n"
|
||||||
|
"public class TestClass2 extends TestClass { int b = 456; }\n"
|
||||||
|
);
|
||||||
|
// Note: Use --CBotUT_TestSaveState command line arg.
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void TestSaveInheritedMembers()\n"
|
||||||
|
"{\n"
|
||||||
|
" TestClass2 t();\n"
|
||||||
|
" ASSERT(t.a == 123);\n"
|
||||||
|
" ASSERT(t.b == 456);\n"
|
||||||
|
" t.a = 789; t.b = 1011;\n"
|
||||||
|
" ASSERT(t.a == 789);\n"
|
||||||
|
" ASSERT(t.b == 1011);\n"
|
||||||
|
" ASSERT(789 == t.a);\n"
|
||||||
|
" ASSERT(1011 == t.b);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue