Merge pull request #1440 from melex750/dev-insect-from-egg

Fix saving/loading programs for insects from AlienEgg
fix-squashed-planets
Mateusz Przybył 2021-12-04 10:04:49 +01:00 committed by GitHub
commit ae179d9005
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 206 additions and 4 deletions

View File

@ -342,7 +342,11 @@ bool WriteStream(std::ostream &ostr, std::istream& istr)
if (!WriteLong(ostr, size)) return false; if (!WriteLong(ostr, size)) return false;
if (!istr.seekg(0, istr.beg)) return false; if (!istr.seekg(0, istr.beg)) return false;
if (!(ostr << istr.rdbuf())) return false; while (size > 0)
{
size -= 1;
if (!ostr.put(istr.get())) return false;
}
return true; return true;
} }
@ -355,7 +359,7 @@ bool ReadStream(std::istream& istr, std::ostream &ostr)
while (length-- > 0) while (length-- > 0)
{ {
if (!(ostr << istr.get())) return false; if (!ostr.put(istr.get())) return false;
} }
return true; return true;
} }

View File

@ -24,6 +24,7 @@
#include "graphics/engine/pyro_manager.h" #include "graphics/engine/pyro_manager.h"
#include "level/parser/parser.h"
#include "level/parser/parserline.h" #include "level/parser/parserline.h"
#include "level/parser/parserparam.h" #include "level/parser/parserparam.h"
@ -194,7 +195,9 @@ bool CAutoEgg::EventProcess(const Event &event)
CProgramStorageObject* programStorage = dynamic_cast<CProgramStorageObject*>(alien); CProgramStorageObject* programStorage = dynamic_cast<CProgramStorageObject*>(alien);
Program* program = programStorage->AddProgram(); Program* program = programStorage->AddProgram();
programStorage->ReadProgram(program, m_alienProgramName.c_str()); programStorage->ReadProgram(program, InjectLevelPathsForCurrentLevel(m_alienProgramName, "ai"));
program->readOnly = true;
program->filename = m_alienProgramName;
programmable->RunProgram(program); programmable->RunProgram(program);
} }
Init(); Init();

View File

@ -1226,7 +1226,7 @@ void COldObject::Read(CLevelParserLine* line)
std::string op = "autoValue" + boost::lexical_cast<std::string>(i+1); // autoValue1..autoValue5 std::string op = "autoValue" + boost::lexical_cast<std::string>(i+1); // autoValue1..autoValue5
m_auto->SetValue(i, line->GetParam(op)->AsFloat(0.0f)); m_auto->SetValue(i, line->GetParam(op)->AsFloat(0.0f));
} }
m_auto->SetString(const_cast<char*>(line->GetParam("autoString")->AsPath("ai", "").c_str())); m_auto->SetString(const_cast<char*>(line->GetParam("autoString")->AsString("").c_str()));
int i = line->GetParam("run")->AsInt(-1); int i = line->GetParam("run")->AsInt(-1);
if (i != -1) if (i != -1)

View File

@ -20,6 +20,7 @@
#include "CBot/CBot.h" #include "CBot/CBot.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <limits>
#include <stdexcept> #include <stdexcept>
extern bool g_cbotTestSaveState; extern bool g_cbotTestSaveState;
@ -319,6 +320,200 @@ protected:
} }
}; };
TEST_F(CBotUT, TestSaveStateIOFunctions)
{
std::stringstream sstr("");
std::string teststring;
for (char c = std::numeric_limits<char>::min() ;; ++c)
{
teststring.push_back(c);
if ( c == std::numeric_limits<char>::max() ) break;
}
auto CallWriteFunctions = [&sstr, &teststring]() -> bool
{
if (!WriteWord(sstr, static_cast<unsigned short>(0))) return false;
if (!WriteWord(sstr, std::numeric_limits<unsigned short>::max() / 2)) return false;
if (!WriteWord(sstr, std::numeric_limits<unsigned short>::max())) return false;
if (!WriteByte(sstr, std::numeric_limits<char>::min())) return false;
if (!WriteByte(sstr, std::numeric_limits<char>::max())) return false;
if (!WriteShort(sstr, std::numeric_limits<short>::min())) return false;
if (!WriteShort(sstr, std::numeric_limits<short>::min() / 2)) return false;
if (!WriteShort(sstr, -1)) return false;
if (!WriteShort(sstr, 0)) return false;
if (!WriteShort(sstr, std::numeric_limits<short>::max() / 2)) return false;
if (!WriteShort(sstr, std::numeric_limits<short>::max())) return false;
if (!WriteUInt32(sstr, static_cast<uint32_t>(0))) return false;
if (!WriteUInt32(sstr, std::numeric_limits<uint32_t>::max() / 2)) return false;
if (!WriteUInt32(sstr, std::numeric_limits<uint32_t>::max())) return false;
if (!WriteInt(sstr, std::numeric_limits<int>::min())) return false;
if (!WriteInt(sstr, std::numeric_limits<int>::min() / 2)) return false;
if (!WriteInt(sstr, -1)) return false;
if (!WriteInt(sstr, 0)) return false;
if (!WriteInt(sstr, std::numeric_limits<int>::max() / 2)) return false;
if (!WriteInt(sstr, std::numeric_limits<int>::max())) return false;
if (!WriteLong(sstr, std::numeric_limits<long>::min())) return false;
if (!WriteLong(sstr, std::numeric_limits<long>::min() / 2L)) return false;
if (!WriteLong(sstr, -1L)) return false;
if (!WriteLong(sstr, 0L)) return false;
if (!WriteLong(sstr, std::numeric_limits<long>::max() / 2L)) return false;
if (!WriteLong(sstr, std::numeric_limits<long>::max())) return false;
// test with padding bytes (not currently used anywhere)
if (!WriteLong(sstr, 1234567890L, 10)) return false;
if (!WriteFloat(sstr, std::numeric_limits<float>::min())) return false;
if (!WriteFloat(sstr, 0.0f)) return false;
if (!WriteFloat(sstr, std::numeric_limits<float>::max())) return false;
if (!WriteDouble(sstr, std::numeric_limits<double>::min())) return false;
if (!WriteDouble(sstr, 0.0)) return false;
if (!WriteDouble(sstr, std::numeric_limits<double>::max())) return false;
if (!WriteString(sstr, "")) return false;
if (!WriteString(sstr, teststring)) return false;
return true;
};
if ( !CallWriteFunctions() )
{
ADD_FAILURE() << "failed in CallWriteFunctions()" << std::endl;
return;
}
std::stringstream savestream("");
if ( !WriteStream(savestream, sstr) )
{
ADD_FAILURE() << "CBot::WriteStream() failed" << std::endl;
return;
}
std::stringstream newstream("");
if ( !ReadStream(savestream, newstream) )
{
ADD_FAILURE() << "CBot:ReadStream() failed" << std::endl;
return;
}
auto CallReadFunctions = [&teststring, &newstream]() -> bool
{
unsigned short w = 1;
if (!ReadWord(newstream, w)) return false;
if (w != static_cast<unsigned short>(0)) return false;
if (!ReadWord(newstream, w)) return false;
if (w != std::numeric_limits<unsigned short>::max() / 2) return false;
if (!ReadWord(newstream, w)) return false;
if (w != std::numeric_limits<unsigned short>::max()) return false;
char c = 1;
if (!ReadByte(newstream, c)) return false;
if (c != std::numeric_limits<char>::min()) return false;
if (!ReadByte(newstream, c)) return false;
if (c != std::numeric_limits<char>::max()) return false;
short s = 1;
if (!ReadShort(newstream, s)) return false;
if (s != std::numeric_limits<short>::min()) return false;
if (!ReadShort(newstream, s)) return false;
if (s != std::numeric_limits<short>::min() / 2) return false;
if (!ReadShort(newstream, s)) return false;
if (s != -1) return false;
if (!ReadShort(newstream, s)) return false;
if (s != 0) return false;
if (!ReadShort(newstream, s)) return false;
if (s != std::numeric_limits<short>::max() / 2) return false;
if (!ReadShort(newstream, s)) return false;
if (s != std::numeric_limits<short>::max()) return false;
uint32_t u = 1;
if (!ReadUInt32(newstream, u)) return false;
if (u != static_cast<uint32_t>(0)) return false;
if (!ReadUInt32(newstream, u)) return false;
if (u != std::numeric_limits<uint32_t>::max() / 2) return false;
if (!ReadUInt32(newstream, u)) return false;
if (u != std::numeric_limits<uint32_t>::max()) return false;
int i = 1;
if (!ReadInt(newstream, i)) return false;
if (i != std::numeric_limits<int>::min()) return false;
if (!ReadInt(newstream, i)) return false;
if (i != std::numeric_limits<int>::min() / 2) return false;
if (!ReadInt(newstream, i)) return false;
if (i != -1) return false;
if (!ReadInt(newstream, i)) return false;
if (i != 0) return false;
if (!ReadInt(newstream, i)) return false;
if (i != std::numeric_limits<int>::max() / 2) return false;
if (!ReadInt(newstream, i)) return false;
if (i != std::numeric_limits<int>::max()) return false;
long l = 1L;
if (!ReadLong(newstream, l)) return false;
if (l != std::numeric_limits<long>::min()) return false;
if (!ReadLong(newstream, l)) return false;
if (l != std::numeric_limits<long>::min() / 2L) return false;
if (!ReadLong(newstream, l)) return false;
if (l != -1L) return false;
if (!ReadLong(newstream, l)) return false;
if (l != 0L) return false;
if (!ReadLong(newstream, l)) return false;
if (l != std::numeric_limits<long>::max() / 2L) return false;
if (!ReadLong(newstream, l)) return false;
if (l != std::numeric_limits<long>::max()) return false;
if (!ReadLong(newstream, l)) return false;
if (l != 1234567890L) return false;
float f = 1.0f;
if (!ReadFloat(newstream, f)) return false;
if (f != std::numeric_limits<float>::min()) return false;
if (!ReadFloat(newstream, f)) return false;
if (f != 0.0f) return false;
if (!ReadFloat(newstream, f)) return false;
if (f != std::numeric_limits<float>::max()) return false;
double d = 1.0;
if (!ReadDouble(newstream, d)) return false;
if (d != std::numeric_limits<double>::min()) return false;
if (!ReadDouble(newstream, d)) return false;
if (d != 0.0) return false;
if (!ReadDouble(newstream, d)) return false;
if (d != std::numeric_limits<double>::max()) return false;
std::string newstring = "should be empty string after next read";
if (!ReadString(newstream, newstring)) return false;
if (newstring != "") return false;
if (!ReadString(newstream, newstring)) return false;
if (newstring != teststring) return false;
return true;
};
if ( !CallReadFunctions() )
{
ADD_FAILURE() << "failed in CallReadFunctions()" << std::endl;
return;
}
}
TEST_F(CBotUT, EmptyTest) TEST_F(CBotUT, EmptyTest)
{ {
ExecuteTest( ExecuteTest(