CProgrammableObject interface

master
Piotr Dziwinski 2015-07-10 20:38:44 +02:00
parent 17ae31e639
commit 5d30de0d09
11 changed files with 137 additions and 63 deletions

View File

@ -26,6 +26,7 @@
#include "object/brain.h"
#include "object/object_manager.h"
#include "object/interface/programmable_object.h"
#include "object/interface/transportable_object.h"
#include "object/level/parserline.h"
#include "object/level/parserparam.h"
@ -182,9 +183,11 @@ bool CAutoEgg::EventProcess(const Event &event)
CObject* alien = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, m_type);
alien->SetActivity(false);
CBrain* brain = alien->GetBrain();
if(brain != nullptr)
if (alien->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(alien)->GetBrain();
Program* program = brain->AddProgram();
brain->ReadProgram(program, m_string);
brain->RunProgram(program);

View File

@ -29,6 +29,7 @@
#include "object/robotmain.h"
#include "object/level/parserline.h"
#include "object/level/parserparam.h"
#include "object/interface/programmable_object.h"
#include "object/interface/transportable_object.h"
#include "physics/physics.h"
@ -488,9 +489,10 @@ bool CAutoFactory::EventProcess(const Event &event)
if ( m_program != nullptr )
{
CBrain* brain = m_vehicle->GetBrain();
if ( brain != nullptr )
if (m_vehicle->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(m_vehicle)->GetBrain();
Program* program = brain->AddProgram();
program->script->SendScript(const_cast<const char*>(m_program));
brain->RunProgram(program);
@ -649,9 +651,9 @@ bool CAutoFactory::CreateVehicle()
physics->SetFreeze(true); // it doesn't move
}
CBrain* brain = vehicle->GetBrain();
if(brain != nullptr)
if (vehicle->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(vehicle)->GetBrain();
for ( int i=0 ; ; i++ )
{
char* name = m_main->GetNewScriptName(m_type, i);

View File

@ -0,0 +1,48 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "object/object_interface_type.h"
class CBrain;
/**
* \class CProgrammableObject
* \brief Interface for programmable objects
*
* Programmable objects can be programmed in CBOT
*/
class CProgrammableObject
{
public:
explicit CProgrammableObject(ObjectInterfaceTypes& types)
{
types[static_cast<int>(ObjectInterfaceType::Programmable)] = true;
}
virtual ~CProgrammableObject()
{}
//! Returns CBrain
/** If only the object implements ObjectInterfaceType::Programmable,
* returned object will always be non-null*/
virtual CBrain* GetBrain() = 0;
// TODO: CBrain interface can actually be moved here
};

View File

@ -34,6 +34,7 @@ enum class ObjectInterfaceType
{
Interactive, //!< interactive objects can process events from event loop
Transportable, //!< objects that can be carried by robots or astronaut
Programmable, //!< objects that can be programmed in CBOT
Max //!< maximum value (for getting number of items in enum)
};

View File

@ -189,7 +189,11 @@ COldObject::COldObject(int id)
: CObject(id, OBJECT_NULL)
, CInteractiveObject(m_implementedInterfaces)
, CTransportableObject(m_implementedInterfaces)
, CProgrammableObject(m_implementedInterfaces)
{
// A bit of a hack since CBrain is set externally in SetBrain()
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
m_sound = CApplication::GetInstancePointer()->GetSound();
m_engine = Gfx::CEngine::GetInstancePointer();
m_lightMan = m_engine->GetLightManager();
@ -450,6 +454,8 @@ void COldObject::DeleteObject(bool bAll)
void COldObject::Simplify()
{
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
if ( m_brain != nullptr )
{
m_brain->StopProgram();
@ -3410,6 +3416,7 @@ CBrain* COldObject::GetBrain()
void COldObject::SetBrain(std::unique_ptr<CBrain> brain)
{
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = true;
m_brain = std::move(brain);
}

View File

@ -27,6 +27,7 @@
#include "object/object.h"
#include "object/interface/interactive_object.h"
#include "object/interface/programmable_object.h"
#include "object/interface/transportable_object.h"
// The father of all parts must always be the part number zero!
@ -54,7 +55,8 @@ struct ObjectPart
class COldObject : public CObject,
public CInteractiveObject,
public CTransportableObject
public CTransportableObject,
public CProgrammableObject
{
friend class CObjectFactory;
friend class CObjectManager;

View File

@ -273,7 +273,6 @@ public:
virtual CScript* GetRunScript() = 0;
virtual CBotVar* GetBotVar() = 0;
virtual CPhysics* GetPhysics() = 0;
virtual CBrain* GetBrain() = 0;
virtual CMotion* GetMotion() = 0;
virtual CAuto* GetAuto() = 0;

View File

@ -3467,13 +3467,16 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_controller = m_objMan->CreateObject(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f, OBJECT_CONTROLLER, 100.0f);
m_controller->SetMagnifyDamage(100.0f);
m_controller->SetIgnoreBuildCheck(true);
CBrain* brain = m_controller->GetBrain();
if (brain != nullptr && line->GetParam("script")->IsDefined())
if (m_controller->Implements(ObjectInterfaceType::Programmable))
{
Program* program = brain->AddProgram();
program->filename = "../" + line->GetParam("script")->AsPath("ai");
program->readOnly = true;
brain->SetScriptRun(program);
CBrain* brain = dynamic_cast<CProgrammableObject*>(m_controller)->GetBrain();
if (line->GetParam("script")->IsDefined())
{
Program* program = brain->AddProgram();
program->filename = "../" + line->GetParam("script")->AsPath("ai");
program->readOnly = true;
brain->SetScriptRun(program);
}
}
continue;
}
@ -3600,9 +3603,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
int run = -1;
std::map<int, Program*> loadedPrograms;
CBrain* brain = obj->GetBrain();
if (brain != nullptr)
if (obj->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
bool allFilled = true;
for (int i = 0; i < 10 || allFilled; i++)
{
@ -3651,8 +3655,9 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
}
}
if (soluce && brain != nullptr && line->GetParam("soluce")->IsDefined())
brain->SetSoluceName(const_cast<char*>(line->GetParam("soluce")->AsPath("ai").c_str()));
if (soluce && obj->Implements(ObjectInterfaceType::Programmable) && line->GetParam("soluce")->IsDefined())
dynamic_cast<CProgrammableObject*>(obj)->GetBrain()
->SetSoluceName(const_cast<char*>(line->GetParam("soluce")->AsPath("ai").c_str()));
obj->SetResetPosition(obj->GetPosition(0));
obj->SetResetAngle(obj->GetAngle(0));
@ -4522,11 +4527,9 @@ void CRobotMain::CompileScript(bool soluce)
nbError = 0;
for (CObject* obj : m_objMan->GetAllObjects())
{
if (IsObjectBeingTransported(obj)) continue;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) continue;
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
for (Program* program : brain->GetPrograms())
{
//? if (brain->GetCompile(j)) continue;
@ -4550,11 +4553,9 @@ void CRobotMain::CompileScript(bool soluce)
{
for (CObject* obj : m_objMan->GetAllObjects())
{
if (IsObjectBeingTransported(obj)) continue;
CBrain* brain = obj->GetBrain();
if (brain == 0) continue;
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
char* name = brain->GetSoluceName();
if (name[0] != 0)
{
@ -4566,11 +4567,9 @@ void CRobotMain::CompileScript(bool soluce)
// Start all programs according to the command "run".
for (CObject* obj : m_objMan->GetAllObjects())
{
if (IsObjectBeingTransported(obj)) continue;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) continue;
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
Program* program = brain->GetScriptRun();
if (program != nullptr)
{
@ -4582,8 +4581,9 @@ void CRobotMain::CompileScript(bool soluce)
//! Load all programs of the robot
void CRobotMain::LoadOneScript(CObject *obj, int &nbError)
{
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
if (!IsSelectable(obj)) return;
@ -4619,8 +4619,9 @@ void CRobotMain::LoadFileScript(CObject *obj, const char* filename, int objRank,
{
if (objRank == -1) return;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return;
@ -4654,8 +4655,9 @@ void CRobotMain::SaveAllScript()
//! If a program does not exist, the corresponding file is destroyed.
void CRobotMain::SaveOneScript(CObject *obj)
{
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
if (!IsSelectable(obj)) return;
@ -4692,8 +4694,9 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank)
{
if (objRank == -1) return;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return;
@ -4723,8 +4726,9 @@ bool CRobotMain::SaveFileStack(CObject *obj, FILE *file, int objRank)
{
if (objRank == -1) return true;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return true;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return true;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return true;
@ -4737,8 +4741,9 @@ bool CRobotMain::ReadFileStack(CObject *obj, FILE *file, int objRank)
{
if (objRank == -1) return true;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) return true;
if (! obj->Implements(ObjectInterfaceType::Programmable)) return true;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
ObjectType type = obj->GetType();
if (type == OBJECT_HUMAN) return true;
@ -4797,11 +4802,10 @@ bool CRobotMain::IsBusy()
for (CObject* obj : m_objMan->GetAllObjects())
{
CBrain* brain = obj->GetBrain();
if (brain != nullptr)
{
if (brain->IsBusy()) return true;
}
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
if (brain->IsBusy()) return true;
}
return false;
}
@ -4854,9 +4858,10 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj)
if (obj->GetType() == OBJECT_BASE)
line->AddParam("run", CLevelParserParamUPtr{new CLevelParserParam(3)}); // stops and open (PARAM_FIXSCENE)
CBrain* brain = obj->GetBrain();
if (brain != nullptr)
if (obj->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
int run = brain->GetProgram();
if (run != -1)
{
@ -5056,9 +5061,10 @@ CObject* CRobotMain::IOReadObject(CLevelParserLine *line, const char* filename,
automat->Start(run); // starts the film
}
CBrain* brain = obj->GetBrain();
if (brain != nullptr)
if (obj->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
if (run != -1)
{
Program* program = brain->GetOrAddProgram(run-1);
@ -5160,11 +5166,10 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
// Starts scripts
for (CObject* obj : m_objMan->GetAllObjects())
{
if (IsObjectBeingTransported(obj)) continue;
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
if (obj->GetDefRank() == -1) continue;
CBrain* brain = obj->GetBrain();
if (brain == nullptr) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
Program* program = brain->GetScriptRun();
if (program != nullptr)

View File

@ -24,6 +24,7 @@
#include "object/object.h"
#include "object/robotmain.h"
#include "object/interface/programmable_object.h"
// Object's constructor.
@ -41,7 +42,11 @@ CTask::CTask(CObject* object)
m_object = object;
m_physics = m_object->GetPhysics();
m_brain = m_object->GetBrain();
m_brain = nullptr;
if (object->Implements(ObjectInterfaceType::Programmable))
{
m_brain = dynamic_cast<CProgrammableObject*>(m_object)->GetBrain();
}
m_motion = m_object->GetMotion();
}

View File

@ -33,6 +33,7 @@
#include "object/robotmain.h"
#include "object/motion/motionant.h"
#include "object/motion/motionspider.h"
#include "object/interface/programmable_object.h"
#include "physics/physics.h"
@ -339,7 +340,6 @@ bool CTaskTerraform::Abort()
bool CTaskTerraform::Terraform()
{
CBrain* brain;
CMotion* motion;
ObjectType type;
float dist;
@ -357,7 +357,7 @@ bool CTaskTerraform::Terraform()
{
// This was used by Ceebot-Teen to destroy objects hit by the Thumper
// The old Teen objects are removed, but this code might be reused at some point, e.g. to add destruction of resources like empty batteries
dist = Math::Distance(m_terraPos, pObj->GetPosition(0));
if ( dist > 20.0f ) continue;
@ -373,15 +373,17 @@ bool CTaskTerraform::Terraform()
if ( type == OBJECT_ANT )
{
brain = pObj->GetBrain();
if ( brain != 0 ) brain->StopTask();
if (pObj->Implements(ObjectInterfaceType::Programmable))
dynamic_cast<CProgrammableObject*>(pObj)->GetBrain()->StopTask();
motion->SetAction(MAS_BACK1, 0.8f+Math::Rand()*0.3f);
pObj->SetFixed(true); // not moving
}
if ( type == OBJECT_SPIDER )
{
brain = pObj->GetBrain();
if ( brain != 0 ) brain->StopTask();
if (pObj->Implements(ObjectInterfaceType::Programmable))
dynamic_cast<CProgrammableObject*>(pObj)->GetBrain()->StopTask();
motion->SetAction(MSS_BACK1, 0.8f+Math::Rand()*0.3f);
pObj->SetFixed(true); // not moving
}

View File

@ -1765,9 +1765,9 @@ bool CScriptFunctions::rProduce(CBotVar* var, CBotVar* result, int& exception, v
if (name[0] != 0)
{
std::string name2 = CPathManager::InjectLevelDir(name, "ai");
CBrain* brain = object->GetBrain();
if (brain != nullptr)
if (object->Implements(ObjectInterfaceType::Programmable))
{
CBrain* brain = dynamic_cast<CProgrammableObject*>(object)->GetBrain();
Program* program = brain->AddProgram();
brain->ReadProgram(program, name2.c_str());
brain->RunProgram(program);