Never save copy of programs from level files when saving scene

Prevents some possible bugs related to changing level files. This might also slightly improve saving time (which is kinda important with one-threaded autosaves ;))
master
krzys-h 2015-08-16 15:25:46 +02:00
parent 2289d69735
commit 4182be3216
3 changed files with 46 additions and 12 deletions

View File

@ -4301,7 +4301,6 @@ void CRobotMain::SaveAllScript()
} }
//! Saves all programs of the robot. //! Saves all programs of the robot.
//! If a program does not exist, the corresponding file is destroyed.
void CRobotMain::SaveOneScript(CObject *obj) void CRobotMain::SaveOneScript(CObject *obj)
{ {
if (! obj->Implements(ObjectInterfaceType::ProgramStorage)) return; if (! obj->Implements(ObjectInterfaceType::ProgramStorage)) return;

View File

@ -75,6 +75,7 @@ bool CProgramStorageObjectImpl::IntroduceVirus()
int programIndex = rand() % m_program.size(); int programIndex = rand() % m_program.size();
if ( m_program[programIndex]->script->IntroduceVirus() ) // tries to introduce if ( m_program[programIndex]->script->IntroduceVirus() ) // tries to introduce
{ {
m_program[programIndex]->filename = ""; // The program is changed, so force it to save instead of just the filename
m_activeVirus = true; // active virus m_activeVirus = true; // active virus
return true; return true;
} }
@ -108,8 +109,6 @@ Program* CProgramStorageObjectImpl::AddProgram()
assert(m_object->Implements(ObjectInterfaceType::Old)); //TODO assert(m_object->Implements(ObjectInterfaceType::Old)); //TODO
auto program = MakeUnique<Program>(); auto program = MakeUnique<Program>();
program->script = MakeUnique<CScript>(dynamic_cast<COldObject*>(this)); program->script = MakeUnique<CScript>(dynamic_cast<COldObject*>(this));
program->readOnly = false;
program->runnable = true;
Program* prog = program.get(); Program* prog = program.get();
AddProgram(std::move(program)); AddProgram(std::move(program));
@ -246,7 +245,7 @@ void CProgramStorageObjectImpl::SaveAllUserPrograms(const std::string& userSourc
{ {
std::string filename = userSource + StrUtils::Format("%.3d%.3d.txt", m_programStorageIndex, i); std::string filename = userSource + StrUtils::Format("%.3d%.3d.txt", m_programStorageIndex, i);
if (i < m_program.size() && !m_program[i]->loadedFromLevel) if (i < m_program.size() && m_program[i]->filename.empty())
{ {
GetLogger()->Trace("Saving program '%s' into user directory\n", filename.c_str()); GetLogger()->Trace("Saving program '%s' into user directory\n", filename.c_str());
WriteProgram(m_program[i].get(), filename); WriteProgram(m_program[i].get(), filename);
@ -275,7 +274,7 @@ void CProgramStorageObjectImpl::LoadAllProgramsForLevel(CLevelParserLine* levelS
ReadProgram(program, filename); ReadProgram(program, filename);
program->readOnly = levelSource->GetParam(opReadOnly)->AsBool(true); program->readOnly = levelSource->GetParam(opReadOnly)->AsBool(true);
program->runnable = levelSource->GetParam(opRunnable)->AsBool(true); program->runnable = levelSource->GetParam(opRunnable)->AsBool(true);
program->loadedFromLevel = true; program->filename = levelSource->GetParam(op)->AsString();
if (m_object->Implements(ObjectInterfaceType::Programmable) && i == run) if (m_object->Implements(ObjectInterfaceType::Programmable) && i == run)
{ {
@ -296,7 +295,7 @@ void CProgramStorageObjectImpl::LoadAllProgramsForLevel(CLevelParserLine* levelS
ReadProgram(program, filename); ReadProgram(program, filename);
program->readOnly = true; program->readOnly = true;
program->runnable = false; program->runnable = false;
program->loadedFromLevel = true; program->filename = levelSource->GetParam("soluce")->AsString();
} }
if (m_programStorageIndex >= 0) if (m_programStorageIndex >= 0)
@ -319,7 +318,19 @@ void CProgramStorageObjectImpl::LoadAllProgramsForLevel(CLevelParserLine* levelS
void CProgramStorageObjectImpl::SaveAllProgramsForSavedScene(CLevelParserLine* levelSourceLine, const std::string& levelSource) void CProgramStorageObjectImpl::SaveAllProgramsForSavedScene(CLevelParserLine* levelSourceLine, const std::string& levelSource)
{ {
levelSourceLine->AddParam("programStorageIndex", MakeUnique<CLevelParserParam>(m_programStorageIndex)); levelSourceLine->AddParam("programStorageIndex", MakeUnique<CLevelParserParam>(m_programStorageIndex));
assert(m_programStorageIndex != -1);
for (unsigned int i = 0; i < m_program.size(); i++)
{
if (!m_program[i]->filename.empty() && m_program[i]->readOnly)
{
levelSourceLine->AddParam("script" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->filename));
levelSourceLine->AddParam("scriptReadOnly" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->readOnly));
levelSourceLine->AddParam("scriptRunnable" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->runnable));
}
}
if (m_programStorageIndex < 0) return;
if (!m_object->Implements(ObjectInterfaceType::Controllable) || !dynamic_cast<CControllableObject*>(m_object)->GetSelectable() || m_object->GetType() == OBJECT_HUMAN) return;
GetLogger()->Debug("Saving saved scene programs to '%s/prog%.3d___.txt'\n", levelSource.c_str(), m_programStorageIndex); GetLogger()->Debug("Saving saved scene programs to '%s/prog%.3d___.txt'\n", levelSource.c_str(), m_programStorageIndex);
for (int i = 0; i < 999; i++) for (int i = 0; i < 999; i++)
@ -330,21 +341,45 @@ void CProgramStorageObjectImpl::SaveAllProgramsForSavedScene(CLevelParserLine* l
CResourceManager::Remove(filename); CResourceManager::Remove(filename);
continue; continue;
} }
if (!m_program[i]->filename.empty() && m_program[i]->readOnly) continue;
levelSourceLine->AddParam("scriptReadOnly" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->readOnly));
levelSourceLine->AddParam("scriptRunnable" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->runnable));
GetLogger()->Trace("Saving program '%s' to saved scene\n", filename.c_str()); GetLogger()->Trace("Saving program '%s' to saved scene\n", filename.c_str());
WriteProgram(m_program[i].get(), filename); WriteProgram(m_program[i].get(), filename);
levelSourceLine->AddParam("scriptReadOnly" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->readOnly));
levelSourceLine->AddParam("scriptRunnable" + StrUtils::ToString<int>(i+1), MakeUnique<CLevelParserParam>(m_program[i]->runnable));
} }
} }
void CProgramStorageObjectImpl::LoadAllProgramsForSavedScene(CLevelParserLine* levelSourceLine, const std::string& levelSource) void CProgramStorageObjectImpl::LoadAllProgramsForSavedScene(CLevelParserLine* levelSourceLine, const std::string& levelSource)
{ {
int run = levelSourceLine->GetParam("run")->AsInt(0)-1;
m_programStorageIndex = levelSourceLine->GetParam("programStorageIndex")->AsInt(-1); m_programStorageIndex = levelSourceLine->GetParam("programStorageIndex")->AsInt(-1);
if(m_programStorageIndex == -1) return;
for (int i = 0; i <= 999; i++)
{
std::string op = "script" + StrUtils::ToString<int>(i+1); // script1..script10
std::string opReadOnly = "scriptReadOnly" + StrUtils::ToString<int>(i+1); // scriptReadOnly1..scriptReadOnly10
std::string opRunnable = "scriptRunnable" + StrUtils::ToString<int>(i+1); // scriptRunnable1..scriptRunnable10
if (levelSourceLine->GetParam(op)->IsDefined())
{
std::string filename = levelSourceLine->GetParam(op)->AsPath("ai");
GetLogger()->Trace("Loading program '%s' from saved scene\n", filename.c_str());
Program* program = GetOrAddProgram(i);
ReadProgram(program, filename);
program->readOnly = levelSourceLine->GetParam(opReadOnly)->AsBool(true);
program->runnable = levelSourceLine->GetParam(opRunnable)->AsBool(true);
program->filename = levelSourceLine->GetParam(op)->AsString();
if (m_object->Implements(ObjectInterfaceType::Programmable) && i == run)
{
dynamic_cast<CProgrammableObject*>(m_object)->RunProgram(program);
}
}
}
if(m_programStorageIndex < 0) return;
GetLogger()->Debug("Loading saved scene programs from '%s/prog%.3d___.txt'\n", levelSource.c_str(), m_programStorageIndex); GetLogger()->Debug("Loading saved scene programs from '%s/prog%.3d___.txt'\n", levelSource.c_str(), m_programStorageIndex);
int run = levelSourceLine->GetParam("run")->AsInt(0)-1;
for (int i = 0; i <= 999; i++) for (int i = 0; i <= 999; i++)
{ {
std::string opReadOnly = "scriptReadOnly" + StrUtils::ToString<int>(i+1); // scriptReadOnly1..scriptReadOnly10 std::string opReadOnly = "scriptReadOnly" + StrUtils::ToString<int>(i+1); // scriptReadOnly1..scriptReadOnly10

View File

@ -33,7 +33,7 @@ struct Program
std::unique_ptr<CScript> script; std::unique_ptr<CScript> script;
bool readOnly = false; bool readOnly = false;
bool runnable = true; bool runnable = true;
bool loadedFromLevel = false; std::string filename;
}; };
/** /**