diff --git a/src/object/brain.cpp b/src/object/brain.cpp index c21bca1a..c3614bdd 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -108,12 +108,6 @@ CBrain::CBrain(COldObject* object) CBrain::~CBrain() { - for(auto x : m_program) - { - delete x->script; - x->script = nullptr; - delete x; - } m_program.clear(); delete m_primaryTask; @@ -320,7 +314,7 @@ bool CBrain::EventProcess(const Event &event) { if(m_selScript < m_program.size()) { - RunProgram(m_program[m_selScript]); + RunProgram(m_program[m_selScript].get()); } } else @@ -333,7 +327,7 @@ bool CBrain::EventProcess(const Event &event) m_main->SaveOneScript(m_object); if(m_selScript < m_program.size()) { - RunProgram(m_program[m_selScript]); + RunProgram(m_program[m_selScript].get()); } } if ( action == EVENT_OBJECT_PROGSTOP ) @@ -353,7 +347,7 @@ bool CBrain::EventProcess(const Event &event) if( action == EVENT_STUDIO_CLONE ) { StopEditScript(false); - Program* newProgram = CloneProgram(m_program[m_selScript]); + Program* newProgram = CloneProgram(m_program[m_selScript].get()); m_selScript = m_program.size()-1; m_main->SaveOneScript(m_object); @@ -445,7 +439,7 @@ bool CBrain::EventProcess(const Event &event) { if(m_selScript < m_program.size()) { - StartEditScript(m_program[m_selScript], m_main->GetScriptName()); + StartEditScript(m_program[m_selScript].get(), m_main->GetScriptName()); } } @@ -473,7 +467,7 @@ bool CBrain::EventProcess(const Event &event) { if(m_selScript < m_program.size()) { - RemoveProgram(m_program[m_selScript]); + RemoveProgram(m_program[m_selScript].get()); if(m_selScript >= m_program.size()) m_selScript = m_program.size()-1; m_main->SaveOneScript(m_object); @@ -492,7 +486,7 @@ bool CBrain::EventProcess(const Event &event) { if(m_selScript < m_program.size()) { - CloneProgram(m_program[m_selScript]); + CloneProgram(m_program[m_selScript].get()); m_selScript = m_program.size()-1; m_main->SaveOneScript(m_object); @@ -602,7 +596,7 @@ bool CBrain::EventProcess(const Event &event) { if(m_selScript < m_program.size()) { - StartEditScript(m_program[m_selScript], m_main->GetScriptName()); + StartEditScript(m_program[m_selScript].get(), m_main->GetScriptName()); } } @@ -611,7 +605,7 @@ bool CBrain::EventProcess(const Event &event) StopProgram(); // stops the current program if(m_selScript < m_program.size()) { - RunProgram(m_program[m_selScript]); + RunProgram(m_program[m_selScript].get()); } UpdateInterface(); } @@ -1056,7 +1050,7 @@ void CBrain::StartEditScript(Program* program, char* name) CreateInterface(false); // removes the control buttons m_studio = new Ui::CStudio(); - m_studio->StartEditScript(program->script, name, program); + m_studio->StartEditScript(program->script.get(), name, program); } // End of editing a program. @@ -2778,7 +2772,7 @@ int CBrain::GetProgram() for(unsigned int i = 0; i < m_program.size(); i++) { - if(m_program[i] == m_currentProgram) + if(m_program[i].get() == m_currentProgram) { return i; } @@ -2822,10 +2816,10 @@ bool CBrain::ReadSoluce(char* filename) for(unsigned int i = 0; i < m_program.size(); i++) { - if(m_program[i] == prog) continue; + if(m_program[i].get() == prog) continue; //TODO: This is bad. It's very sensitive to things like \n vs \r\n etc. - if ( m_program[i]->script->Compare(prog->script) ) // the same already? + if ( m_program[i]->script->Compare(prog->script.get()) ) // the same already? { m_program[i]->readOnly = true; // Mark is as read-only RemoveProgram(prog); @@ -2910,7 +2904,7 @@ bool CBrain::WriteStack(FILE *file) } -const std::vector& CBrain::GetPrograms() +std::vector>& CBrain::GetPrograms() { return m_program; } @@ -3096,19 +3090,16 @@ bool CBrain::TraceRecordPut(std::stringstream& buffer, TraceOper oper, float par Program* CBrain::AddProgram() { Program* program = new Program(); - program->script = new CScript(m_object, &m_secondaryTask); + program->script.reset(new CScript(m_object, &m_secondaryTask)); program->readOnly = false; program->runnable = true; - AddProgram(program); + AddProgram(std::move(std::unique_ptr{program})); return program; } -bool CBrain::AddProgram(Program* program) +void CBrain::AddProgram(std::unique_ptr program) { - if(std::find(m_program.begin(), m_program.end(), program) != m_program.end()) - return false; - - m_program.push_back(program); + m_program.push_back(std::move(program)); if(m_object->GetSelect()) { @@ -3119,7 +3110,6 @@ bool CBrain::AddProgram(Program* program) UpdateScript(pw); } } - return true; } void CBrain::RemoveProgram(Program* program) @@ -3128,10 +3118,10 @@ void CBrain::RemoveProgram(Program* program) { StopProgram(); } - m_program.erase(std::remove(m_program.begin(), m_program.end(), program), m_program.end()); - delete program->script; - program->script = nullptr; - delete program; + m_program.erase( + std::remove_if(m_program.begin(), m_program.end(), + [program](std::unique_ptr& prog) { return prog.get() == program; }), + m_program.end()); if(m_object->GetSelect()) { @@ -3162,7 +3152,7 @@ int CBrain::GetProgramIndex(Program* program) { for(unsigned int i = 0; i < m_program.size(); i++) { - if(m_program[i] == program) + if(m_program[i].get() == program) { return i; } @@ -3175,7 +3165,7 @@ Program* CBrain::GetProgram(int index) if(index < 0 || index >= static_cast(m_program.size())) return nullptr; - return m_program[index]; + return m_program[index].get(); } Program* CBrain::GetOrAddProgram(int index) @@ -3184,7 +3174,7 @@ Program* CBrain::GetOrAddProgram(int index) return nullptr; if(index < static_cast(m_program.size())) - return m_program[index]; + return m_program[index].get(); for(int i = m_program.size(); i < index; i++) { diff --git a/src/object/brain.h b/src/object/brain.h index 3021ccf1..50e6d2e8 100644 --- a/src/object/brain.h +++ b/src/object/brain.h @@ -35,6 +35,7 @@ #include #include +#include class COldObject; class CPhysics; @@ -78,7 +79,7 @@ struct TraceRecord struct Program { - CScript* script; + std::unique_ptr script; std::string filename; bool readOnly; bool runnable; @@ -128,7 +129,7 @@ public: bool WriteProgram(Program* program, const char* filename); bool ReadStack(FILE *file); bool WriteStack(FILE *file); - const std::vector& GetPrograms(); + std::vector>& GetPrograms(); Error StartTaskTake(); Error StartTaskManip(TaskManipOrder order, TaskManipArm arm); @@ -148,7 +149,7 @@ public: void UpdateInterface(); Program* AddProgram(); - bool AddProgram(Program* program); + void AddProgram(std::unique_ptr program); void RemoveProgram(Program* program); Program* CloneProgram(Program* program); @@ -207,7 +208,7 @@ protected: CTaskManager* m_primaryTask; CTaskManager* m_secondaryTask; - std::vector m_program; + std::vector> m_program; Program* m_currentProgram; unsigned int m_selScript; // rank of the selected script diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 41c3a2ff..ffee6eff 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -4537,9 +4537,10 @@ void CRobotMain::CompileScript(bool soluce) if (! obj->Implements(ObjectInterfaceType::Programmable)) continue; CBrain* brain = dynamic_cast(obj)->GetBrain(); - for (Program* program : brain->GetPrograms()) + for (std::unique_ptr& prog : brain->GetPrograms()) { - //? if (brain->GetCompile(j)) continue; + Program* program = prog.get(); + if (program->filename.empty()) continue; std::string name = "ai/" + program->filename; @@ -4677,7 +4678,7 @@ void CRobotMain::SaveOneScript(CObject *obj) char* name = m_dialog->GetSceneName(); int rank = m_dialog->GetSceneRank(); - auto programs = brain->GetPrograms(); + auto& programs = brain->GetPrograms(); // TODO: Find a better way to do that for (unsigned int i = 0; i <= 999; i++) { @@ -4686,7 +4687,7 @@ void CRobotMain::SaveOneScript(CObject *obj) GetSavegameDir(), m_gamerName.c_str(), name[0], rank, objRank, i); if (i < programs.size()) { - brain->WriteProgram(programs[i], filename); + brain->WriteProgram(programs[i].get(), filename); } else { @@ -4712,14 +4713,14 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank) dirname = dirname.substr(0, dirname.find_last_of("/")); char fn[MAX_FNAME]; //TODO: Refactor to std::string - auto programs = brain->GetPrograms(); + auto& programs = brain->GetPrograms(); // TODO: Find a better way to do that for (unsigned int i = 0; i <= 999; i++) { sprintf(fn, "%s/prog%.3d%.3d.txt", dirname.c_str(), objRank, i); if (i < programs.size()) { - brain->WriteProgram(programs[i], fn); + brain->WriteProgram(programs[i].get(), fn); } else { @@ -4879,7 +4880,7 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj) line->AddParam("run", CLevelParserParamUPtr{new CLevelParserParam(run+1)}); } - auto programs = brain->GetPrograms(); + auto& programs = brain->GetPrograms(); for (unsigned int i = 0; i < programs.size(); i++) { if (programs[i]->readOnly)