diff --git a/source/main/AppContext.cpp b/source/main/AppContext.cpp index 11d8150727..441309d28c 100644 --- a/source/main/AppContext.cpp +++ b/source/main/AppContext.cpp @@ -192,7 +192,7 @@ void AppContext::windowResized(Ogre::RenderWindow* rw) App::GetOverlayWrapper()->windowResized(); if (App::sim_state->getEnum() == RoR::AppState::SIMULATION) { - for (Actor* actor: App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors()) { actor->ar_dashboard->windowResized(); } diff --git a/source/main/Application.h b/source/main/Application.h index 1285dbce04..f2d81a85ea 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -96,11 +96,11 @@ enum MsgType MSG_SIM_UNLOAD_TERRN_REQUESTED, MSG_SIM_SPAWN_ACTOR_REQUESTED, //!< Payload = RoR::ActorSpawnRequest* (owner) MSG_SIM_MODIFY_ACTOR_REQUESTED, //!< Payload = RoR::ActorModifyRequest* (owner) - MSG_SIM_DELETE_ACTOR_REQUESTED, //!< Payload = RoR::Actor* (weak) - MSG_SIM_SEAT_PLAYER_REQUESTED, //!< Payload = RoR::Actor* (weak) | nullptr + MSG_SIM_DELETE_ACTOR_REQUESTED, //!< Payload = RoR::ActorPtr* (owner) + MSG_SIM_SEAT_PLAYER_REQUESTED, //!< Payload = RoR::ActorPtr (owner) | nullptr MSG_SIM_TELEPORT_PLAYER_REQUESTED, //!< Payload = Ogre::Vector3* (owner) - MSG_SIM_HIDE_NET_ACTOR_REQUESTED, //!< Payload = Actor* (weak) - MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED, //!< Payload = Actor* (weak) + MSG_SIM_HIDE_NET_ACTOR_REQUESTED, //!< Payload = ActorPtr* (owner) + MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED, //!< Payload = ActorPtr* (owner) // GUI MSG_GUI_OPEN_MENU_REQUESTED, MSG_GUI_CLOSE_MENU_REQUESTED, diff --git a/source/main/CMakeLists.txt b/source/main/CMakeLists.txt index 67bbd8f28c..ec060d17c6 100644 --- a/source/main/CMakeLists.txt +++ b/source/main/CMakeLists.txt @@ -203,6 +203,8 @@ set(SOURCE_FILES terrain/Terrain.{h,cpp} terrain/TerrainObjectManager.{h,cpp} threadpool/ThreadPool.h + utils/memory/RefCountingObject.h + utils/memory/RefCountingObjectPtr.h utils/ConfigFile.{h,cpp} utils/ErrorUtils.{h,cpp} utils/ForceFeedback.{h,cpp} @@ -344,6 +346,7 @@ target_include_directories(${BINNAME} PRIVATE terrain terrain/map threadpool + utils/memory utils ) diff --git a/source/main/ForwardDeclarations.h b/source/main/ForwardDeclarations.h index a448509898..cbc4ab2b77 100644 --- a/source/main/ForwardDeclarations.h +++ b/source/main/ForwardDeclarations.h @@ -25,6 +25,7 @@ /// @author Petr Ohlidal /// @date 12/2013 +#include "RefCountingObjectPtr.h" #pragma once @@ -141,6 +142,9 @@ namespace RoR struct client_t; struct authorinfo_t; + /// AngelScript-friendly shared pointers + typedef RefCountingObjectPtr ActorPtr; + namespace GUI { class ConsoleView; diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index c1faab371b..0e730787ff 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -144,7 +144,7 @@ void GameContext::UnloadTerrain() // -------------------------------- // Actors (physics and netcode) -Actor* GameContext::SpawnActor(ActorSpawnRequest& rq) +ActorPtr GameContext::SpawnActor(ActorSpawnRequest& rq) { if (rq.asr_origin == ActorSpawnRequest::Origin::USER) { @@ -206,7 +206,7 @@ Actor* GameContext::SpawnActor(ActorSpawnRequest& rq) } #endif //SOCKETW - Actor* fresh_actor = m_actor_manager.CreateNewActor(rq, def); + ActorPtr fresh_actor = m_actor_manager.CreateNewActor(rq, def); // lock slide nodes after spawning the actor? if (def->slide_nodes_connect_instantly) @@ -219,7 +219,7 @@ Actor* GameContext::SpawnActor(ActorSpawnRequest& rq) m_last_spawned_actor = fresh_actor; if (fresh_actor->ar_driveable != NOT_DRIVEABLE) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)fresh_actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(fresh_actor)))); } if (rq.asr_spawnbox == nullptr) { @@ -233,13 +233,13 @@ Actor* GameContext::SpawnActor(ActorSpawnRequest& rq) fresh_actor->ar_num_nodes > 0 && App::diag_preset_veh_enter->getBool()) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)fresh_actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(fresh_actor)))); } if (fresh_actor->ar_driveable != NOT_DRIVEABLE && fresh_actor->ar_num_nodes > 0 && App::cli_preset_veh_enter->getBool()) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)fresh_actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(fresh_actor)))); } } else if (rq.asr_origin == ActorSpawnRequest::Origin::TERRN_DEF) @@ -281,7 +281,7 @@ Actor* GameContext::SpawnActor(ActorSpawnRequest& rq) if (fresh_actor->ar_driveable != NOT_DRIVEABLE && rq.asr_origin != ActorSpawnRequest::Origin::NETWORK) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)fresh_actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(fresh_actor)))); } } @@ -340,7 +340,7 @@ void GameContext::ModifyActor(ActorModifyRequest& rq) } } -void GameContext::DeleteActor(Actor* actor) +void GameContext::DeleteActor(ActorPtr actor) { if (actor == m_player_actor) { @@ -386,9 +386,9 @@ void GameContext::DeleteActor(Actor* actor) m_actor_manager.DeleteActorInternal(actor); } -void GameContext::ChangePlayerActor(Actor* actor) +void GameContext::ChangePlayerActor(ActorPtr actor) { - Actor* prev_player_actor = m_player_actor; + ActorPtr prev_player_actor = m_player_actor; m_player_actor = actor; // hide any old dashes @@ -487,12 +487,12 @@ void GameContext::ChangePlayerActor(Actor* actor) m_actor_manager.UpdateSleepingState(m_player_actor, 0.f); } -Actor* GameContext::FetchPrevVehicleOnList() +ActorPtr GameContext::FetchPrevVehicleOnList() { return m_actor_manager.FetchPreviousVehicleOnList(m_player_actor, m_prev_player_actor); } -Actor* GameContext::FetchNextVehicleOnList() +ActorPtr GameContext::FetchNextVehicleOnList() { return m_actor_manager.FetchNextVehicleOnList(m_player_actor, m_prev_player_actor); } @@ -502,7 +502,7 @@ void GameContext::UpdateActors() m_actor_manager.UpdateActors(m_player_actor); } -Actor* GameContext::FindActorByCollisionBox(std::string const & ev_src_instance_name, std::string const & box_name) +ActorPtr GameContext::FindActorByCollisionBox(std::string const & ev_src_instance_name, std::string const & box_name) { return m_actor_manager.FindActorInsideBox(App::GetSimTerrain()->GetCollisions(), ev_src_instance_name, box_name); @@ -563,7 +563,7 @@ void GameContext::ShowLoaderGUI(int type, const Ogre::String& instance, const Og if (!(App::mp_state->getEnum() == MpState::CONNECTED)) { collision_box_t* spawnbox = App::GetSimTerrain()->GetCollisions()->getBox(instance, box); - for (auto actor : this->GetActorManager()->GetActors()) + for (ActorPtr actor : this->GetActorManager()->GetActors()) { for (int i = 0; i < actor->ar_num_nodes; i++) { @@ -749,7 +749,7 @@ void GameContext::TeleportPlayer(float x, float z) float src_agl = std::numeric_limits::max(); float dst_agl = std::numeric_limits::max(); - for (auto actor : actors) + for (ActorPtr actor : actors) { for (int i = 0; i < actor->ar_num_nodes; i++) { @@ -762,7 +762,7 @@ void GameContext::TeleportPlayer(float x, float z) translation += Ogre::Vector3::UNIT_Y * (std::max(0.0f, src_agl) - dst_agl); - for (auto actor : actors) + for (ActorPtr actor : actors) { actor->resetPosition(actor->ar_nodes[0].AbsPosition + translation, false); } @@ -892,8 +892,8 @@ void GameContext::UpdateSimInputEvents(float dt) { // find the nearest vehicle float mindist = 1000.0; - Actor* nearest_actor = nullptr; - for (auto actor : this->GetActorManager()->GetActors()) + ActorPtr nearest_actor = nullptr; + for (ActorPtr& actor : this->GetActorManager()->GetActors()) { if (!actor->ar_driveable) continue; @@ -916,7 +916,7 @@ void GameContext::UpdateSimInputEvents(float dt) if (mindist < 20.0) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)nearest_actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(nearest_actor)))); } } else // We're in a vehicle -> If moving slowly enough, get out @@ -933,20 +933,20 @@ void GameContext::UpdateSimInputEvents(float dt) // enter next truck if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_ENTER_NEXT_TRUCK, 0.25f)) { - Actor* actor = this->FetchNextVehicleOnList(); + ActorPtr actor = this->FetchNextVehicleOnList(); if (actor != this->GetPlayerActor()) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(actor)))); } } // enter previous truck if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_ENTER_PREVIOUS_TRUCK, 0.25f)) { - Actor* actor = this->FetchPrevVehicleOnList(); + ActorPtr actor = this->FetchPrevVehicleOnList(); if (actor != this->GetPlayerActor()) { - this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + this->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(actor)))); } } @@ -967,9 +967,9 @@ void GameContext::UpdateSimInputEvents(float dt) { // Find nearest actor const Ogre::Vector3 position = App::GetGameContext()->GetPlayerCharacter()->getPosition(); - Actor* nearest_actor = nullptr; + ActorPtr nearest_actor = nullptr; float min_squared_distance = std::numeric_limits::max(); - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { float squared_distance = position.squaredDistance(actor->ar_nodes[0].AbsPosition); if (squared_distance < min_squared_distance) @@ -1106,7 +1106,7 @@ void GameContext::UpdateCommonInputEvents(float dt) // remove current truck if (App::GetInputEngine()->getEventBoolValue(EV_COMMON_REMOVE_CURRENT_TRUCK)) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)m_player_actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(m_player_actor)))); } // blinkers @@ -1128,7 +1128,7 @@ void GameContext::UpdateCommonInputEvents(float dt) if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_TRUCK_REMOVE)) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)m_player_actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(m_player_actor)))); } if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_ROPELOCK)) @@ -1161,7 +1161,7 @@ void GameContext::UpdateCommonInputEvents(float dt) if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_TOGGLE_DEBUG_VIEW)) { m_player_actor->GetGfxActor()->ToggleDebugView(); - for (auto actor : m_player_actor->getAllLinkedActors()) + for (ActorPtr actor : m_player_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_player_actor->GetGfxActor()->GetDebugView()); } @@ -1170,7 +1170,7 @@ void GameContext::UpdateCommonInputEvents(float dt) if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_CYCLE_DEBUG_VIEWS)) { m_player_actor->GetGfxActor()->CycleDebugViews(); - for (auto actor : m_player_actor->getAllLinkedActors()) + for (ActorPtr actor : m_player_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_player_actor->GetGfxActor()->GetDebugView()); } @@ -1190,8 +1190,8 @@ void GameContext::UpdateCommonInputEvents(float dt) App::mp_state->getEnum() != MpState::CONNECTED && m_player_actor->ar_driveable != AIRPLANE) { - Actor* rescuer = nullptr; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + ActorPtr rescuer = nullptr; + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_rescuer_flag) { @@ -1204,7 +1204,7 @@ void GameContext::UpdateCommonInputEvents(float dt) } else { - App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)rescuer)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(rescuer)))); } } @@ -1239,7 +1239,7 @@ void GameContext::UpdateCommonInputEvents(float dt) // toggle physics if (RoR::App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_TOGGLE_PHYSICS)) { - for (auto actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) + for (ActorPtr actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) { actor->ar_physics_paused = !App::GetGameContext()->GetPlayerActor()->ar_physics_paused; } @@ -1686,7 +1686,7 @@ void GameContext::UpdateTruckInputEvents(float dt) } m_player_actor->UpdatePropAnimInputEvents(); - for (Actor* linked_actor : m_player_actor->getAllLinkedActors()) + for (ActorPtr linked_actor : m_player_actor->getAllLinkedActors()) { linked_actor->UpdatePropAnimInputEvents(); } diff --git a/source/main/GameContext.h b/source/main/GameContext.h index 81ad22707e..6d016c7447 100644 --- a/source/main/GameContext.h +++ b/source/main/GameContext.h @@ -114,22 +114,22 @@ class GameContext /// @name Actors /// @{ - Actor* SpawnActor(ActorSpawnRequest& rq); + ActorPtr SpawnActor(ActorSpawnRequest& rq); void ModifyActor(ActorModifyRequest& rq); - void DeleteActor(Actor* actor); + void DeleteActor(ActorPtr actor); void UpdateActors(); ActorManager* GetActorManager() { return &m_actor_manager; } - Actor* FetchPrevVehicleOnList(); - Actor* FetchNextVehicleOnList(); - Actor* FindActorByCollisionBox(std::string const & ev_src_instance_name, std::string const & box_name); + ActorPtr FetchPrevVehicleOnList(); + ActorPtr FetchNextVehicleOnList(); + ActorPtr FindActorByCollisionBox(std::string const & ev_src_instance_name, std::string const & box_name); void RespawnLastActor(); void SpawnPreselectedActor(std::string const& preset_vehicle, std::string const& preset_veh_config); //!< needs `Character` to exist - Actor* GetPlayerActor() { return m_player_actor; } - Actor* GetPrevPlayerActor() { return m_prev_player_actor; } - Actor* GetLastSpawnedActor() { return m_last_spawned_actor; } //!< Last actor spawned by user and still alive. - void SetPrevPlayerActor(Actor* actor) { m_prev_player_actor = actor; } - void ChangePlayerActor(Actor* actor); + ActorPtr GetPlayerActor() { return m_player_actor; } + ActorPtr GetPrevPlayerActor() { return m_prev_player_actor; } + ActorPtr GetLastSpawnedActor() { return m_last_spawned_actor; } //!< Last actor spawned by user and still alive. + void SetPrevPlayerActor(ActorPtr actor) { m_prev_player_actor = actor; } + void ChangePlayerActor(ActorPtr actor); void ShowLoaderGUI(int type, const Ogre::String& instance, const Ogre::String& box); void OnLoaderGuiCancel(); //!< GUI callback @@ -181,9 +181,9 @@ class GameContext // Actors (physics and netcode) ActorManager m_actor_manager; - Actor* m_player_actor = nullptr; //!< Actor (vehicle or machine) mounted and controlled by player - Actor* m_prev_player_actor = nullptr; //!< Previous actor (vehicle or machine) mounted and controlled by player - Actor* m_last_spawned_actor = nullptr; //!< Last actor spawned by user and still alive. + ActorPtr m_player_actor = nullptr; //!< Actor (vehicle or machine) mounted and controlled by player + ActorPtr m_prev_player_actor = nullptr; //!< Previous actor (vehicle or machine) mounted and controlled by player + ActorPtr m_last_spawned_actor = nullptr; //!< Last actor spawned by user and still alive. CacheEntry* m_last_cache_selection = nullptr; //!< Vehicle/load CacheEntry* m_last_skin_selection = nullptr; diff --git a/source/main/audio/SoundScriptManager.cpp b/source/main/audio/SoundScriptManager.cpp index 37543d8920..65955a4aa3 100644 --- a/source/main/audio/SoundScriptManager.cpp +++ b/source/main/audio/SoundScriptManager.cpp @@ -98,7 +98,7 @@ SoundScriptManager::~SoundScriptManager() delete sound_manager; } -void SoundScriptManager::trigOnce(Actor* actor, int trig, int linkType, int linkItemID) +void SoundScriptManager::trigOnce(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return; @@ -126,7 +126,7 @@ void SoundScriptManager::trigOnce(int actor_id, int trig, int linkType, int link } } -void SoundScriptManager::trigStart(Actor* actor, int trig, int linkType, int linkItemID) +void SoundScriptManager::trigStart(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return; @@ -157,7 +157,7 @@ void SoundScriptManager::trigStart(int actor_id, int trig, int linkType, int lin } } -void SoundScriptManager::trigStop(Actor* actor, int trig, int linkType, int linkItemID) +void SoundScriptManager::trigStop(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return; @@ -187,7 +187,7 @@ void SoundScriptManager::trigStop(int actor_id, int trig, int linkType, int link } } -void SoundScriptManager::trigKill(Actor* actor, int trig, int linkType, int linkItemID) +void SoundScriptManager::trigKill(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return; @@ -217,7 +217,7 @@ void SoundScriptManager::trigKill(int actor_id, int trig, int linkType, int link } } -void SoundScriptManager::trigToggle(Actor* actor, int trig, int linkType, int linkItemID) +void SoundScriptManager::trigToggle(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return; @@ -239,7 +239,7 @@ void SoundScriptManager::trigToggle(int actor_id, int trig, int linkType, int li trigStart(actor_id, trig, linkType, linkItemID); } -bool SoundScriptManager::getTrigState(Actor* actor, int trig, int linkType, int linkItemID) +bool SoundScriptManager::getTrigState(ActorPtr actor, int trig, int linkType, int linkItemID) { if (disabled) return false; @@ -258,7 +258,7 @@ bool SoundScriptManager::getTrigState(int actor_id, int trig, int linkType, int return state_map[linkType][linkItemID][actor_id][trig]; } -void SoundScriptManager::modulate(Actor* actor, int mod, float value, int linkType, int linkItemID) +void SoundScriptManager::modulate(ActorPtr actor, int mod, float value, int linkType, int linkItemID) { if (disabled) return; diff --git a/source/main/audio/SoundScriptManager.h b/source/main/audio/SoundScriptManager.h index 9dbaaf08e6..cf2db59982 100644 --- a/source/main/audio/SoundScriptManager.h +++ b/source/main/audio/SoundScriptManager.h @@ -24,6 +24,7 @@ #pragma once #include "Application.h" +#include "Actor.h" #include @@ -266,19 +267,19 @@ class SoundScriptManager : public Ogre::ScriptLoader, public ZeroedMemoryAllocat // functions void trigOnce (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); - void trigOnce (Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); + void trigOnce (ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); void trigStart (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); - void trigStart (Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); + void trigStart (ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); void trigStop (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); - void trigStop (Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); + void trigStop (ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); void trigToggle (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); - void trigToggle (Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); + void trigToggle (ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); void trigKill (int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID = -1); - void trigKill (Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID = -1); + void trigKill (ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID = -1); bool getTrigState(int actor_id, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); - bool getTrigState(Actor* actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); + bool getTrigState(ActorPtr actor, int trig, int linkType = SL_DEFAULT, int linkItemID=-1); void modulate (int actor_id, int mod, float value, int linkType = SL_DEFAULT, int linkItemID=-1); - void modulate (Actor* actor, int mod, float value, int linkType = SL_DEFAULT, int linkItemID=-1); + void modulate (ActorPtr actor, int mod, float value, int linkType = SL_DEFAULT, int linkItemID=-1); void setEnabled(bool state); diff --git a/source/main/gameplay/Character.cpp b/source/main/gameplay/Character.cpp index eead1d49c3..fd51761891 100644 --- a/source/main/gameplay/Character.cpp +++ b/source/main/gameplay/Character.cpp @@ -159,7 +159,7 @@ void Character::update(float dt) // Submesh "collision" { float depth = 0.0f; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_bounding_box.contains(position)) { @@ -496,7 +496,7 @@ void Character::receiveStreamData(unsigned int& type, int& source, unsigned int& else if (msg->command == CHARACTER_CMD_ATTACH) { auto* attach_msg = reinterpret_cast(buffer); - Actor* beam = App::GetGameContext()->GetActorManager()->GetActorByNetworkLinks(attach_msg->source_id, attach_msg->stream_id); + ActorPtr beam = App::GetGameContext()->GetActorManager()->GetActorByNetworkLinks(attach_msg->source_id, attach_msg->stream_id); if (beam != nullptr) { this->SetActorCoupling(true, beam); @@ -520,7 +520,7 @@ void Character::receiveStreamData(unsigned int& type, int& source, unsigned int& #endif } -void Character::SetActorCoupling(bool enabled, Actor* actor) +void Character::SetActorCoupling(bool enabled, ActorPtr actor) { m_actor_coupling = actor; #ifdef USE_SOCKETW diff --git a/source/main/gameplay/Character.h b/source/main/gameplay/Character.h index 1ed79860fd..21c6071367 100644 --- a/source/main/gameplay/Character.h +++ b/source/main/gameplay/Character.h @@ -21,6 +21,7 @@ #pragma once +#include "Actor.h" #include "ForwardDeclarations.h" #include @@ -51,7 +52,7 @@ class Character std::string const & GetAnimName() const { return m_anim_name; } float GetAnimTime() const { return m_anim_time; } Ogre::Radian getRotation() const { return m_character_rotation; } - Actor* GetActorCoupling() { return m_actor_coupling; } + ActorPtr GetActorCoupling() { return m_actor_coupling; } void setColour(int color) { this->m_color_number = color; } Ogre::Vector3 getPosition(); void setPosition(Ogre::Vector3 position); @@ -60,7 +61,7 @@ class Character void update(float dt); void updateCharacterRotation(); void receiveStreamData(unsigned int& type, int& source, unsigned int& streamid, char* buffer); - void SetActorCoupling(bool enabled, Actor* actor); + void SetActorCoupling(bool enabled, ActorPtr actor); GfxCharacter* SetupGfx(); private: @@ -70,7 +71,7 @@ class Character void SendStreamSetup(); void SetAnimState(std::string mode, float time = 0); - Actor* m_actor_coupling; //!< The vehicle or machine which the character occupies + ActorPtr m_actor_coupling; //!< The vehicle or machine which the character occupies Ogre::Radian m_character_rotation; float m_character_h_speed; float m_character_v_speed; @@ -104,7 +105,7 @@ struct GfxCharacter Ogre::UTFString simbuf_net_username; bool simbuf_is_remote; int simbuf_color_number; - Actor* simbuf_actor_coupling; + ActorPtr simbuf_actor_coupling; std::string simbuf_anim_name; float simbuf_anim_time; // Intentionally left empty = forces initial update. }; diff --git a/source/main/gameplay/CharacterFactory.cpp b/source/main/gameplay/CharacterFactory.cpp index 4a00bbce59..78a2e60665 100644 --- a/source/main/gameplay/CharacterFactory.cpp +++ b/source/main/gameplay/CharacterFactory.cpp @@ -86,7 +86,7 @@ void CharacterFactory::Update(float dt) } } -void CharacterFactory::UndoRemoteActorCoupling(Actor* actor) +void CharacterFactory::UndoRemoteActorCoupling(ActorPtr actor) { for (auto& c : m_remote_characters) { diff --git a/source/main/gameplay/CharacterFactory.h b/source/main/gameplay/CharacterFactory.h index 765bcf5cbf..2ddde2794d 100644 --- a/source/main/gameplay/CharacterFactory.h +++ b/source/main/gameplay/CharacterFactory.h @@ -43,7 +43,7 @@ class CharacterFactory Character* CreateLocalCharacter(); Character* GetLocalCharacter() { return m_local_character.get(); } void DeleteAllCharacters(); - void UndoRemoteActorCoupling(Actor* actor); + void UndoRemoteActorCoupling(ActorPtr actor); void Update(float dt); #ifdef USE_SOCKETW void handleStreamData(std::vector packet); diff --git a/source/main/gameplay/ChatSystem.cpp b/source/main/gameplay/ChatSystem.cpp index 0ad1129926..0097ee7f8a 100644 --- a/source/main/gameplay/ChatSystem.cpp +++ b/source/main/gameplay/ChatSystem.cpp @@ -20,6 +20,7 @@ #include "ChatSystem.h" +#include "Actor.h" #include "Console.h" #include "GUIManager.h" #include "Language.h" diff --git a/source/main/gameplay/EngineSim.cpp b/source/main/gameplay/EngineSim.cpp index 3dee731405..72e5d49bca 100644 --- a/source/main/gameplay/EngineSim.cpp +++ b/source/main/gameplay/EngineSim.cpp @@ -34,7 +34,7 @@ using namespace Ogre; using namespace RoR; -EngineSim::EngineSim(float _min_rpm, float _max_rpm, float torque, std::vector gears, float dratio, Actor* actor) : +EngineSim::EngineSim(float _min_rpm, float _max_rpm, float torque, std::vector gears, float dratio, ActorPtr actor) : m_air_pressure(0.0f) , m_auto_cur_acc(0.0f) , m_auto_mode(AUTOMATIC) diff --git a/source/main/gameplay/EngineSim.h b/source/main/gameplay/EngineSim.h index 4a0f217a1b..b6eac43f1c 100644 --- a/source/main/gameplay/EngineSim.h +++ b/source/main/gameplay/EngineSim.h @@ -22,6 +22,7 @@ #pragma once #include "Application.h" +#include "Actor.h" namespace RoR { @@ -38,7 +39,7 @@ class EngineSim : public ZeroedMemoryAllocator public: - EngineSim(float min_rpm, float max_rpm, float torque, std::vector gears, float dratio, Actor* actor); + EngineSim(float min_rpm, float max_rpm, float torque, std::vector gears, float dratio, ActorPtr actor); ~EngineSim(); /// Sets current engine state; @@ -153,7 +154,7 @@ class EngineSim : public ZeroedMemoryAllocator }; // Vehicle - Actor* m_actor; + ActorPtr m_actor; // Gearbox float m_ref_wheel_revolutions; //!< Gears; estimated wheel revolutions based on current vehicle speed along the longi. axis diff --git a/source/main/gameplay/Landusemap.cpp b/source/main/gameplay/Landusemap.cpp index ad89d7adf3..2fb91ec113 100644 --- a/source/main/gameplay/Landusemap.cpp +++ b/source/main/gameplay/Landusemap.cpp @@ -20,6 +20,7 @@ #include "Landusemap.h" +#include "Actor.h" #include "Application.h" #include "Collisions.h" #include "Console.h" diff --git a/source/main/gameplay/RecoveryMode.cpp b/source/main/gameplay/RecoveryMode.cpp index f2b67a324e..7345acf302 100644 --- a/source/main/gameplay/RecoveryMode.cpp +++ b/source/main/gameplay/RecoveryMode.cpp @@ -115,7 +115,7 @@ void RecoveryMode::UpdateInputEvents(float dt) if (App::sim_soft_reset_mode->getBool()) { - for (auto actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) + for (ActorPtr actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) { actor->requestRotation(rotation, rotation_center); actor->requestTranslation(translation); @@ -129,7 +129,7 @@ void RecoveryMode::UpdateInputEvents(float dt) App::GetGameContext()->GetPlayerActor()->requestAngleSnap(45); if (App::sim_soft_reset_mode->getBool()) { - for (auto actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) + for (ActorPtr actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) { actor->requestAngleSnap(45); } @@ -144,7 +144,7 @@ void RecoveryMode::UpdateInputEvents(float dt) if (App::sim_soft_reset_mode->getBool()) { reset_type = ActorModifyRequest::Type::SOFT_RESET; - for (auto actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) + for (ActorPtr actor : App::GetGameContext()->GetPlayerActor()->getAllLinkedActors()) { ActorModifyRequest* rq = new ActorModifyRequest; rq->amr_actor = actor; diff --git a/source/main/gameplay/Replay.cpp b/source/main/gameplay/Replay.cpp index b2fbc779b2..cd0ddecbc2 100644 --- a/source/main/gameplay/Replay.cpp +++ b/source/main/gameplay/Replay.cpp @@ -32,7 +32,7 @@ using namespace Ogre; using namespace RoR; -Replay::Replay(Actor* actor, int _numFrames) +Replay::Replay(ActorPtr actor, int _numFrames) { m_actor = actor; numFrames = _numFrames; @@ -48,7 +48,9 @@ Replay::Replay(Actor* actor, int _numFrames) outOfMemory = false; - unsigned long bsize = (actor->ar_num_nodes * numFrames * sizeof(node_simple_t) + actor->ar_num_beams * numFrames * sizeof(beam_simple_t) + numFrames * sizeof(unsigned long)) / 1024.0f; + const int numNodes = actor->ar_num_nodes; + const int numBeams = actor->ar_num_beams; + unsigned long bsize = (numNodes * numFrames * sizeof(node_simple_t) + numBeams * numFrames * sizeof(beam_simple_t) + numFrames * sizeof(unsigned long)) / 1024.0f; LOG("replay buffer size: " + TOSTRING(bsize) + " kB"); writeIndex = 0; diff --git a/source/main/gameplay/Replay.h b/source/main/gameplay/Replay.h index b6a8ff3c7c..c6d02f0426 100644 --- a/source/main/gameplay/Replay.h +++ b/source/main/gameplay/Replay.h @@ -39,7 +39,7 @@ struct beam_simple_t class Replay : public ZeroedMemoryAllocator { public: - Replay(Actor* b, int nframes); + Replay(ActorPtr b, int nframes); ~Replay(); void* getWriteBuffer(int type); @@ -56,7 +56,7 @@ class Replay : public ZeroedMemoryAllocator void UpdateInputEvents(); protected: - Actor* m_actor = nullptr; + ActorPtr m_actor = nullptr; float m_replay_timer = 0.f; float ar_replay_precision = 1.f; int ar_replay_pos = 0; diff --git a/source/main/gameplay/SceneMouse.cpp b/source/main/gameplay/SceneMouse.cpp index 8d67cb8e99..adaafb1442 100644 --- a/source/main/gameplay/SceneMouse.cpp +++ b/source/main/gameplay/SceneMouse.cpp @@ -125,7 +125,7 @@ bool SceneMouse::mouseMoved(const OIS::MouseEvent& _arg) // walk all trucks minnode = NODENUM_INVALID; grab_truck = NULL; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_state == ActorState::LOCAL_SIMULATED) { @@ -234,13 +234,13 @@ bool SceneMouse::mousePressed(const OIS::MouseEvent& _arg, OIS::MouseButtonID _i return true; } - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); // Reselect the player actor { Real nearest_ray_distance = std::numeric_limits::max(); - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor != player_actor) { @@ -252,7 +252,7 @@ bool SceneMouse::mousePressed(const OIS::MouseEvent& _arg, OIS::MouseButtonID _i if (ray_distance < nearest_ray_distance) { nearest_ray_distance = ray_distance; - App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(actor)))); } } } diff --git a/source/main/gameplay/SceneMouse.h b/source/main/gameplay/SceneMouse.h index 3684472d12..cacdc95299 100644 --- a/source/main/gameplay/SceneMouse.h +++ b/source/main/gameplay/SceneMouse.h @@ -58,7 +58,7 @@ class SceneMouse NodeNum_t minnode = NODENUM_INVALID; float mindist; - Actor* grab_truck; + ActorPtr grab_truck; Ogre::Vector3 lastgrabpos; int lastMouseX, lastMouseY; diff --git a/source/main/gameplay/TyrePressure.h b/source/main/gameplay/TyrePressure.h index b0301503bd..93b45dc3de 100644 --- a/source/main/gameplay/TyrePressure.h +++ b/source/main/gameplay/TyrePressure.h @@ -41,7 +41,7 @@ namespace RoR { class TyrePressure { public: - TyrePressure(Actor* a): m_actor(a) {} + TyrePressure(ActorPtr a): m_actor(a) {} void AddBeam(int beam_id) { m_pressure_beams.push_back(beam_id); } bool IsEnabled() const { return m_pressure_beams.size() != 0; } @@ -51,7 +51,7 @@ class TyrePressure bool IsPressurizing() const { return m_pressure_pressed; } private: - Actor* m_actor; + ActorPtr m_actor; std::vector m_pressure_beams; bool m_pressure_pressed = false; float m_pressure_pressed_timer = 0.f; diff --git a/source/main/gameplay/VehicleAI.cpp b/source/main/gameplay/VehicleAI.cpp index 30525ad6c4..d1818832d7 100644 --- a/source/main/gameplay/VehicleAI.cpp +++ b/source/main/gameplay/VehicleAI.cpp @@ -39,7 +39,7 @@ using namespace Ogre; using namespace RoR; -VehicleAI::VehicleAI(Actor* b) : +VehicleAI::VehicleAI(ActorPtr b) : is_waiting(false), wait_time(0.0f) { @@ -417,7 +417,7 @@ void VehicleAI::update(float dt, int doUpdate) } // Collision avoidance with other actors - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_driveable == NOT_DRIVEABLE) // Ignore objects that may be actors continue; @@ -488,7 +488,7 @@ void VehicleAI::update(float dt, int doUpdate) } // Collision avoidance with other actors - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_driveable == NOT_DRIVEABLE) // Ignore objects that may be actors continue; diff --git a/source/main/gameplay/VehicleAI.h b/source/main/gameplay/VehicleAI.h index e8a805e7b5..213cab60b2 100644 --- a/source/main/gameplay/VehicleAI.h +++ b/source/main/gameplay/VehicleAI.h @@ -57,7 +57,7 @@ enum Ai_values class VehicleAI : public ZeroedMemoryAllocator { public: - VehicleAI(Actor* b); + VehicleAI(ActorPtr b); ~VehicleAI(); /** * Activates/Deactivates the AI. @@ -133,7 +133,7 @@ class VehicleAI : public ZeroedMemoryAllocator float wait_time;//!<(seconds) The amount of time the AI has to wait on this waypoint. float maxspeed = 50;//!<(KM/H) The max speed the AI is allowed to drive. - Actor* beam;//!< The verhicle the AI is driving. + ActorPtr beam;//!< The verhicle the AI is driving. bool is_enabled = false;//!< True if the AI is driving. Ogre::Vector3 current_waypoint;//!< The coordinates of the waypoint that the AI is driving to. Ogre::Vector3 prev_waypoint;//!< The coordinates of the previous waypoint. diff --git a/source/main/gfx/GfxActor.cpp b/source/main/gfx/GfxActor.cpp index e2d9ec0511..88df17a318 100644 --- a/source/main/gfx/GfxActor.cpp +++ b/source/main/gfx/GfxActor.cpp @@ -53,7 +53,7 @@ #include -RoR::GfxActor::GfxActor(Actor* actor, ActorSpawner* spawner, std::string ogre_resource_group, +RoR::GfxActor::GfxActor(ActorPtr actor, ActorSpawner* spawner, std::string ogre_resource_group, RoR::Renderdash* renderdash): m_actor(actor), m_custom_resource_group(ogre_resource_group), @@ -1797,7 +1797,7 @@ void RoR::GfxActor::UpdateSimDataBuffer() // Linked Actors m_linked_gfx_actors.clear(); - for (auto actor : m_actor->getAllLinkedActors()) + for (ActorPtr actor : m_actor->getAllLinkedActors()) { m_linked_gfx_actors.insert(actor->GetGfxActor()); } diff --git a/source/main/gfx/GfxActor.h b/source/main/gfx/GfxActor.h index 9980121a5e..d2f361fc7f 100644 --- a/source/main/gfx/GfxActor.h +++ b/source/main/gfx/GfxActor.h @@ -55,7 +55,7 @@ class GfxActor public: - GfxActor(Actor* actor, ActorSpawner* spawner, std::string ogre_resource_group, + GfxActor(ActorPtr actor, ActorSpawner* spawner, std::string ogre_resource_group, RoR::Renderdash* renderdash); ~GfxActor(); @@ -139,7 +139,7 @@ class GfxActor DebugViewType GetDebugView() const { return m_debug_view; } std::set GetLinkedGfxActors() { return m_linked_gfx_actors; } Ogre::String GetResourceGroup() { return m_custom_resource_group; } - Actor* GetActor() { return m_actor; } // Watch out for multithreading with this! + ActorPtr GetActor() { return m_actor; } // Watch out for multithreading with this! Ogre::TexturePtr GetHelpTex() { return m_help_tex; } Ogre::MaterialPtr GetHelpMat() { return m_help_mat; } int FetchNumBeams() const ; @@ -156,7 +156,7 @@ class GfxActor static Ogre::Quaternion SpecialGetRotationTo(const Ogre::Vector3& src, const Ogre::Vector3& dest); // Static info - Actor* m_actor = nullptr; + ActorPtr m_actor = nullptr; std::string m_custom_resource_group; int m_driverseat_prop_index = -1; Ogre::SceneNode* m_gfx_beams_parent_scenenode = nullptr; diff --git a/source/main/gfx/GfxData.h b/source/main/gfx/GfxData.h index 5657eae629..121f4931ca 100644 --- a/source/main/gfx/GfxData.h +++ b/source/main/gfx/GfxData.h @@ -228,7 +228,7 @@ struct BeamGfx NodeNum_t rod_node1 = NODENUM_INVALID; //!< Node index - may change during simulation! NodeNum_t rod_node2 = NODENUM_INVALID; //!< Node index - may change during simulation! - Actor* rod_target_actor = nullptr; + ActorPtr rod_target_actor = nullptr; bool rod_is_visible = false; }; diff --git a/source/main/gfx/HydraxWater.cpp b/source/main/gfx/HydraxWater.cpp index c2601d0790..016edba145 100644 --- a/source/main/gfx/HydraxWater.cpp +++ b/source/main/gfx/HydraxWater.cpp @@ -20,6 +20,7 @@ #include "HydraxWater.h" +#include "Actor.h" #include "AppContext.h" #include "CameraManager.h" #include "GfxScene.h" diff --git a/source/main/gfx/Renderdash.cpp b/source/main/gfx/Renderdash.cpp index a8a954829d..76cfed5c21 100644 --- a/source/main/gfx/Renderdash.cpp +++ b/source/main/gfx/Renderdash.cpp @@ -20,6 +20,7 @@ #include "Renderdash.h" +#include "Actor.h" #include "Application.h" #include "GfxScene.h" #include "GUIManager.h" diff --git a/source/main/gfx/ShadowManager.cpp b/source/main/gfx/ShadowManager.cpp index 4ad50f5b04..76643882b3 100644 --- a/source/main/gfx/ShadowManager.cpp +++ b/source/main/gfx/ShadowManager.cpp @@ -20,6 +20,7 @@ #include "ShadowManager.h" +#include "Actor.h" #include "CameraManager.h" #include "GfxScene.h" diff --git a/source/main/gfx/SimBuffers.h b/source/main/gfx/SimBuffers.h index 9c8c6894ef..b76f5e37b6 100644 --- a/source/main/gfx/SimBuffers.h +++ b/source/main/gfx/SimBuffers.h @@ -195,7 +195,7 @@ struct ActorSB struct GameContextSB { - Actor* simbuf_player_actor = nullptr; + ActorPtr simbuf_player_actor; Ogre::Vector3 simbuf_character_pos = Ogre::Vector3::ZERO; bool simbuf_sim_paused = false; float simbuf_sim_speed = 1.f; diff --git a/source/main/gfx/Skidmark.cpp b/source/main/gfx/Skidmark.cpp index a730024fbd..0acee0862f 100644 --- a/source/main/gfx/Skidmark.cpp +++ b/source/main/gfx/Skidmark.cpp @@ -20,6 +20,7 @@ #include "Skidmark.h" +#include "Actor.h" #include "Application.h" #include "SimData.h" #include "ContentManager.h" // RGN_CONFIG diff --git a/source/main/gfx/SkyManager.cpp b/source/main/gfx/SkyManager.cpp index 9df0167b09..6080ea465e 100644 --- a/source/main/gfx/SkyManager.cpp +++ b/source/main/gfx/SkyManager.cpp @@ -23,6 +23,7 @@ #include "SkyManager.h" +#include "Actor.h" #include "AppContext.h" #include "CameraManager.h" #include "GfxScene.h" diff --git a/source/main/gfx/SkyXManager.cpp b/source/main/gfx/SkyXManager.cpp index 4864fc7bdb..b3179cb407 100644 --- a/source/main/gfx/SkyXManager.cpp +++ b/source/main/gfx/SkyXManager.cpp @@ -21,6 +21,7 @@ #include "SkyXManager.h" +#include "Actor.h" #include "AppContext.h" #include "CameraManager.h" #include "GfxScene.h" diff --git a/source/main/gfx/SurveyMapTextureCreator.cpp b/source/main/gfx/SurveyMapTextureCreator.cpp index 768cdfbcfe..e314a462bf 100644 --- a/source/main/gfx/SurveyMapTextureCreator.cpp +++ b/source/main/gfx/SurveyMapTextureCreator.cpp @@ -20,6 +20,7 @@ #include "SurveyMapTextureCreator.h" +#include "Actor.h" #include "Application.h" #include "GfxScene.h" #include "IWater.h" diff --git a/source/main/gfx/Water.cpp b/source/main/gfx/Water.cpp index 1c83e0ce93..f6c5dea32c 100644 --- a/source/main/gfx/Water.cpp +++ b/source/main/gfx/Water.cpp @@ -21,6 +21,7 @@ #include "Water.h" +#include "Actor.h" #include "AppContext.h" #include "CameraManager.h" #include "GfxScene.h" diff --git a/source/main/gfx/camera/CameraManager.cpp b/source/main/gfx/camera/CameraManager.cpp index 4a03e1599e..54966a8b42 100644 --- a/source/main/gfx/camera/CameraManager.cpp +++ b/source/main/gfx/camera/CameraManager.cpp @@ -507,7 +507,7 @@ void CameraManager::switchBehavior(CameraBehaviors new_behavior) this->ActivateNewBehavior(new_behavior, true); } -void CameraManager::SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, Actor* new_vehicle) +void CameraManager::SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, ActorPtr new_vehicle) { if (new_behavior == m_current_behavior) { @@ -626,7 +626,7 @@ void CameraManager::NotifyContextChange() } } -void CameraManager::NotifyVehicleChanged(Actor* new_vehicle) +void CameraManager::NotifyVehicleChanged(ActorPtr new_vehicle) { // Getting out of vehicle if (new_vehicle == nullptr) @@ -1249,7 +1249,7 @@ void CameraManager::CameraBehaviorVehicleSplineCreateSpline() if (m_splinecam_num_linked_beams > 0) { - for (auto actor : linkedBeams) + for (ActorPtr actor : linkedBeams) { if (actor->ar_num_camera_rails <= 0) continue; diff --git a/source/main/gfx/camera/CameraManager.h b/source/main/gfx/camera/CameraManager.h index e520ec44f6..2c4083f7fc 100644 --- a/source/main/gfx/camera/CameraManager.h +++ b/source/main/gfx/camera/CameraManager.h @@ -64,7 +64,7 @@ class CameraManager Ogre::Camera* GetCamera() { return m_camera; } void NotifyContextChange(); - void NotifyVehicleChanged(Actor* new_vehicle); + void NotifyVehicleChanged(ActorPtr new_vehicle); void CameraBehaviorOrbitReset(); bool CameraBehaviorOrbitMouseMoved(const OIS::MouseEvent& _arg); @@ -82,7 +82,7 @@ class CameraManager protected: void switchBehavior(CameraBehaviors new_behavior); - void SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, Actor* new_vehicle); + void SwitchBehaviorOnVehicleChange(CameraBehaviors new_behavior, ActorPtr new_vehicle); void ToggleCameraBehavior(CameraBehaviors new_behavior); //!< Only accepts FREE and FREEFIX modes void ActivateNewBehavior(CameraBehaviors new_behavior, bool reset); void UpdateCurrentBehavior(); @@ -110,7 +110,7 @@ class CameraManager CameraBehaviors m_cam_before_toggled; //!< Toggled modes (FREE, FREEFIX) remember original state. CameraBehaviors m_prev_toggled_cam; //!< Switching toggled modes (FREE, FREEFIX) keeps 1-slot history. // Old `CameraContext` - Actor* m_cct_player_actor; // TODO: duplicates `GameContext::m_player_actor` + ActorPtr m_cct_player_actor; // TODO: duplicates `GameContext::m_player_actor` Ogre::Degree m_cct_rot_scale; Ogre::Real m_cct_dt; Ogre::Real m_cct_trans_scale; diff --git a/source/main/gui/GUIUtils.cpp b/source/main/gui/GUIUtils.cpp index c08536f5ed..a619b81b81 100644 --- a/source/main/gui/GUIUtils.cpp +++ b/source/main/gui/GUIUtils.cpp @@ -19,6 +19,8 @@ #include "GUIUtils.h" +#include "Actor.h" + #include "imgui_internal.h" // ImTextCharFromUtf8 #include #include // sscanf diff --git a/source/main/gui/OverlayWrapper.cpp b/source/main/gui/OverlayWrapper.cpp index 7e7aa58c49..b71f833eb2 100644 --- a/source/main/gui/OverlayWrapper.cpp +++ b/source/main/gui/OverlayWrapper.cpp @@ -370,12 +370,12 @@ void OverlayWrapper::showPressureOverlay(bool show) } } -void OverlayWrapper::ToggleDashboardOverlays(Actor* actor) +void OverlayWrapper::ToggleDashboardOverlays(ActorPtr actor) { showDashboardOverlays(!m_dashboard_visible, actor); } -void OverlayWrapper::showDashboardOverlays(bool show, Actor* actor) +void OverlayWrapper::showDashboardOverlays(bool show, ActorPtr actor) { m_dashboard_visible = show; @@ -500,7 +500,7 @@ bool OverlayWrapper::mouseMoved(const OIS::MouseEvent& _arg) bool res = false; const OIS::MouseState ms = _arg.state; - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); if (!player_actor) return res; @@ -919,7 +919,7 @@ void OverlayWrapper::UpdateAerialHUD(RoR::GfxActor* gfx_actor) m_aerial_dashboard.vs_trim.DisplayFormat("+%i00", simbuf.simbuf_ap_vs_value / 100); } -void OverlayWrapper::UpdateMarineHUD(Actor* vehicle) +void OverlayWrapper::UpdateMarineHUD(ActorPtr vehicle) { // throttles bthro1->setTop(thrtop + thrheight * (0.5 - vehicle->ar_screwprops[0]->getThrottle() / 2.0) - 1.0); diff --git a/source/main/gui/OverlayWrapper.h b/source/main/gui/OverlayWrapper.h index 755861b80f..f2491b880a 100644 --- a/source/main/gui/OverlayWrapper.h +++ b/source/main/gui/OverlayWrapper.h @@ -122,9 +122,9 @@ class OverlayWrapper : public ZeroedMemoryAllocator Ogre::Overlay *o; }; - void ToggleDashboardOverlays(Actor *actor); + void ToggleDashboardOverlays(ActorPtr actor); - void showDashboardOverlays(bool show, Actor *actor); + void showDashboardOverlays(bool show, ActorPtr actor); void windowResized(); void resizeOverlay(LoadedOverlay & overlay); @@ -138,7 +138,7 @@ class OverlayWrapper : public ZeroedMemoryAllocator void update(float dt); void UpdateLandVehicleHUD(RoR::GfxActor* ga); void UpdateAerialHUD(RoR::GfxActor* ga); - void UpdateMarineHUD(Actor * vehicle); + void UpdateMarineHUD(ActorPtr vehicle); void ShowRacingOverlay(); void HideRacingOverlay(); diff --git a/source/main/gui/imgui/OgreImGui.cpp b/source/main/gui/imgui/OgreImGui.cpp index e71542dfa7..6c878d20c6 100644 --- a/source/main/gui/imgui/OgreImGui.cpp +++ b/source/main/gui/imgui/OgreImGui.cpp @@ -25,6 +25,7 @@ #include "OgreImGui.h" +#include "Actor.h" #include "AppContext.h" #include "ContentManager.h" #include "OgreImGuiOverlay.h" diff --git a/source/main/gui/panels/GUI_ConsoleView.cpp b/source/main/gui/panels/GUI_ConsoleView.cpp index 95c39c6864..8787163216 100644 --- a/source/main/gui/panels/GUI_ConsoleView.cpp +++ b/source/main/gui/panels/GUI_ConsoleView.cpp @@ -22,6 +22,7 @@ #include "GUI_ConsoleView.h" +#include "Actor.h" #include "Application.h" #include "Console.h" #include "GUIManager.h" diff --git a/source/main/gui/panels/GUI_ConsoleWindow.cpp b/source/main/gui/panels/GUI_ConsoleWindow.cpp index 541aef5a18..57cf188195 100644 --- a/source/main/gui/panels/GUI_ConsoleWindow.cpp +++ b/source/main/gui/panels/GUI_ConsoleWindow.cpp @@ -21,6 +21,8 @@ #include "GUI_ConsoleWindow.h" + +#include "Actor.h" #include "GUIManager.h" #include "GUI_AngelScriptExamples.h" diff --git a/source/main/gui/panels/GUI_GameAbout.cpp b/source/main/gui/panels/GUI_GameAbout.cpp index 115379d222..6a9df2581f 100644 --- a/source/main/gui/panels/GUI_GameAbout.cpp +++ b/source/main/gui/panels/GUI_GameAbout.cpp @@ -25,6 +25,7 @@ #include "GUI_GameAbout.h" +#include "Actor.h" #include "Application.h" #include "GUIManager.h" #include "Language.h" diff --git a/source/main/gui/panels/GUI_GameChatBox.cpp b/source/main/gui/panels/GUI_GameChatBox.cpp index da226ec6db..d0ac0daf9d 100644 --- a/source/main/gui/panels/GUI_GameChatBox.cpp +++ b/source/main/gui/panels/GUI_GameChatBox.cpp @@ -21,6 +21,7 @@ #include "GUI_GameChatBox.h" +#include "Actor.h" #include "Application.h" #include "ChatSystem.h" #include "Console.h" diff --git a/source/main/gui/panels/GUI_GameControls.cpp b/source/main/gui/panels/GUI_GameControls.cpp index 4a436e38ec..44e407314d 100644 --- a/source/main/gui/panels/GUI_GameControls.cpp +++ b/source/main/gui/panels/GUI_GameControls.cpp @@ -21,6 +21,7 @@ #include "GUI_GameControls.h" +#include "Actor.h" #include "Application.h" #include "Language.h" #include "OgreImGui.h" diff --git a/source/main/gui/panels/GUI_LoadingWindow.cpp b/source/main/gui/panels/GUI_LoadingWindow.cpp index 45827d7380..d1788e5be0 100644 --- a/source/main/gui/panels/GUI_LoadingWindow.cpp +++ b/source/main/gui/panels/GUI_LoadingWindow.cpp @@ -21,6 +21,7 @@ #include "GUI_LoadingWindow.h" #include +#include "Actor.h" #include "GUIManager.h" #include "GUIUtils.h" #include "OgreImGui.h" diff --git a/source/main/gui/panels/GUI_NodeBeamUtils.cpp b/source/main/gui/panels/GUI_NodeBeamUtils.cpp index fce14877e2..65a92c017c 100644 --- a/source/main/gui/panels/GUI_NodeBeamUtils.cpp +++ b/source/main/gui/panels/GUI_NodeBeamUtils.cpp @@ -31,7 +31,7 @@ using namespace GUI; void NodeBeamUtils::Draw() { - Actor* actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr actor = App::GetGameContext()->GetPlayerActor(); if (!actor) { this->SetVisible(false); diff --git a/source/main/gui/panels/GUI_ScriptMonitor.cpp b/source/main/gui/panels/GUI_ScriptMonitor.cpp index d75f4df422..3020167c69 100644 --- a/source/main/gui/panels/GUI_ScriptMonitor.cpp +++ b/source/main/gui/panels/GUI_ScriptMonitor.cpp @@ -16,6 +16,7 @@ #include "GUI_ScriptMonitor.h" +#include "Actor.h" #include "ContentManager.h" #include "ScriptEngine.h" diff --git a/source/main/gui/panels/GUI_SimActorStats.cpp b/source/main/gui/panels/GUI_SimActorStats.cpp index e5ef4c248a..d991eb7a71 100644 --- a/source/main/gui/panels/GUI_SimActorStats.cpp +++ b/source/main/gui/panels/GUI_SimActorStats.cpp @@ -225,7 +225,7 @@ void SimActorStats::Draw(RoR::GfxActor* actorx) ImGui::PopStyleColor(1); // WindowBg } -void SimActorStats::UpdateStats(float dt, Actor* actor) +void SimActorStats::UpdateStats(float dt, ActorPtr actor) { //taken from TruckHUD.cpp (now removed) beam_t* beam = actor->ar_beams; diff --git a/source/main/gui/panels/GUI_SimActorStats.h b/source/main/gui/panels/GUI_SimActorStats.h index dab8931967..7423a84bac 100644 --- a/source/main/gui/panels/GUI_SimActorStats.h +++ b/source/main/gui/panels/GUI_SimActorStats.h @@ -36,7 +36,7 @@ class SimActorStats void SetVisible(bool vis) { m_is_visible = vis; } bool IsVisible() const { return m_is_visible; } - void UpdateStats(float dt, Actor* actor); //!< Caution: touches live data, must be synced with sim. thread + void UpdateStats(float dt, ActorPtr actor); //!< Caution: touches live data, must be synced with sim. thread void Draw(RoR::GfxActor* actorx); private: diff --git a/source/main/gui/panels/GUI_SimPerfStats.cpp b/source/main/gui/panels/GUI_SimPerfStats.cpp index a1290f1b74..57f8cff308 100644 --- a/source/main/gui/panels/GUI_SimPerfStats.cpp +++ b/source/main/gui/panels/GUI_SimPerfStats.cpp @@ -21,6 +21,7 @@ #include "GUI_SimPerfStats.h" +#include "Actor.h" #include "AppContext.h" #include "GUIManager.h" #include "Language.h" diff --git a/source/main/gui/panels/GUI_SurveyMap.cpp b/source/main/gui/panels/GUI_SurveyMap.cpp index d867e31ac8..bd02c509c2 100644 --- a/source/main/gui/panels/GUI_SurveyMap.cpp +++ b/source/main/gui/panels/GUI_SurveyMap.cpp @@ -138,7 +138,7 @@ void SurveyMap::Draw() // Calc. view center smallmap_size = mTerrainSize * (1.0f - mMapZoom); Ogre::Vector2 player_map_pos; - Actor* actor = App::GetGfxScene()->GetSimDataBuffer().simbuf_player_actor; + ActorPtr actor = App::GetGfxScene()->GetSimDataBuffer().simbuf_player_actor; if (actor) { auto& actor_data = actor->GetGfxActor()->GetSimDataBuffer(); @@ -422,7 +422,7 @@ void SurveyMap::setMapZoomRelative(float delta) } -const char* SurveyMap::getTypeByDriveable(ActorType driveable, Actor* actor) +const char* SurveyMap::getTypeByDriveable(ActorType driveable, ActorPtr actor) { switch (driveable) { @@ -443,7 +443,7 @@ const char* SurveyMap::getTypeByDriveable(ActorType driveable, Actor* actor) } } -const char* SurveyMap::getAIType(Actor* actor) +const char* SurveyMap::getAIType(ActorPtr actor) { if (actor->ar_engine) { diff --git a/source/main/gui/panels/GUI_SurveyMap.h b/source/main/gui/panels/GUI_SurveyMap.h index 16c07f330a..232a1632a4 100644 --- a/source/main/gui/panels/GUI_SurveyMap.h +++ b/source/main/gui/panels/GUI_SurveyMap.h @@ -72,8 +72,8 @@ class SurveyMap void setMapZoom(float zoom); void setMapZoomRelative(float dt_sec); - const char* getTypeByDriveable(ActorType driveable, Actor* actor); - const char* getAIType(Actor* actor); + const char* getTypeByDriveable(ActorType driveable, ActorPtr actor); + const char* getAIType(ActorPtr actor); void DrawMapIcon(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 view_origin, std::string const& filename, std::string const& caption, diff --git a/source/main/gui/panels/GUI_TextureToolWindow.cpp b/source/main/gui/panels/GUI_TextureToolWindow.cpp index b1235972af..a982e57dc3 100644 --- a/source/main/gui/panels/GUI_TextureToolWindow.cpp +++ b/source/main/gui/panels/GUI_TextureToolWindow.cpp @@ -23,6 +23,7 @@ #include +#include "Actor.h" #include "Application.h" #include "Console.h" #include "GUIManager.h" diff --git a/source/main/gui/panels/GUI_TopMenubar.cpp b/source/main/gui/panels/GUI_TopMenubar.cpp index 1510026868..b87e7ec439 100644 --- a/source/main/gui/panels/GUI_TopMenubar.cpp +++ b/source/main/gui/panels/GUI_TopMenubar.cpp @@ -109,8 +109,14 @@ void TopMenubar::Update() GUIManager::GuiTheme const& theme = App::GetGuiManager()->GetTheme(); - auto actors = App::GetGameContext()->GetActorManager()->GetActors(); - int num_playable_actors = std::count_if(actors.begin(), actors.end(), [](Actor* a) {return !a->ar_hide_in_actor_list;}); + int num_playable_actors = 0; + for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors()) + { + if (!actor->ar_hide_in_actor_list) + { + num_playable_actors++; + } + } std::string sim_title = _LC("TopMenubar", "Simulation"); std::string actors_title = fmt::format("{} ({})", _LC("TopMenubar", "Vehicles"), num_playable_actors); @@ -245,7 +251,7 @@ void TopMenubar::Update() this->DrawSpecialStateBox(window_target_pos.y + topmenu_final_size.y + 10.f); ImVec2 menu_pos; - Actor* current_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr current_actor = App::GetGameContext()->GetPlayerActor(); switch (m_open_menu) { case TopMenu::TOPMENU_SIM: @@ -284,7 +290,7 @@ void TopMenubar::Update() if (ImGui::Button(_LC("TopMenubar", "Remove current vehicle"))) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)current_actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(current_actor)))); } } } @@ -308,8 +314,8 @@ void TopMenubar::Update() if (ImGui::Button(_LC("TopMenubar", "Remove last spawned vehicle"))) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, - (void*)App::GetGameContext()->GetLastSpawnedActor())); + ActorPtr actor = App::GetGameContext()->GetLastSpawnedActor(); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } @@ -324,12 +330,12 @@ void TopMenubar::Update() ImGui::PushStyleColor(ImGuiCol_Text, ORANGE_TEXT); if (ImGui::Button(_LC("TopMenubar", " [!] Confirm removal"))) { - for (auto actor : App::GetGameContext()->GetActorManager()->GetLocalActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetLocalActors()) { if (!actor->ar_hide_in_actor_list && !actor->isPreloadedWithTerrain() && actor->ar_state != ActorState::NETWORKED_OK) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } m_confirm_remove_all = false; @@ -994,11 +1000,11 @@ void TopMenubar::Update() App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); } - for (auto actor : App::GetGameContext()->GetActorManager()->GetLocalActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetLocalActors()) { if (actor->ar_driveable == AI) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } } @@ -1171,7 +1177,7 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) { // Count actors owned by the player unsigned int num_actors_player = 0; - for (Actor* actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_net_source_id == user.uniqueid) { @@ -1196,7 +1202,7 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) Ogre::TexturePtr tex1 = FetchIcon("control_pause.png"); Ogre::TexturePtr tex2 = FetchIcon("control_play.png"); int i = 0; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if ((!actor->ar_hide_in_actor_list) && (actor->ar_net_source_id == user.uniqueid)) { @@ -1206,14 +1212,14 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) { if (ImGui::ImageButton(reinterpret_cast(tex1->getHandle()), ImVec2(16, 16))) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_HIDE_NET_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_HIDE_NET_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } else if (actor->ar_state == ActorState::NETWORKED_HIDDEN) { if (ImGui::ImageButton(reinterpret_cast(tex2->getHandle()), ImVec2(16, 16))) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } else // Our actor(s) @@ -1222,7 +1228,7 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) ImGui::PushStyleColor(ImGuiCol_Text, RED_TEXT); if (ImGui::Button(text_buf_rem.c_str())) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } ImGui::PopStyleColor(); } @@ -1232,7 +1238,7 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) std::string actortext_buf = fmt::format("{} ({}) ##[{}:{}]", StripColorMarksFromText(actor->ar_design_name).c_str(), actor->ar_filename.c_str(), i++, user.uniqueid); if (ImGui::Button(actortext_buf.c_str())) // Button clicked? { - App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(actor)))); } } } @@ -1240,8 +1246,8 @@ void TopMenubar::DrawMpUserToActorList(RoRnet::UserInfo &user) void TopMenubar::DrawActorListSinglePlayer() { - std::vector actor_list; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + std::vector actor_list; + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (!actor->ar_hide_in_actor_list) { @@ -1257,15 +1263,15 @@ void TopMenubar::DrawActorListSinglePlayer() } else { - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); int i = 0; - for (auto actor : actor_list) + for (ActorPtr actor : actor_list) { std::string text_buf_rem = fmt::format("X ##[{}]", i); ImGui::PushStyleColor(ImGuiCol_Text, RED_TEXT); if (ImGui::Button(text_buf_rem.c_str())) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } ImGui::PopStyleColor(); ImGui::SameLine(); @@ -1290,7 +1296,7 @@ void TopMenubar::DrawActorListSinglePlayer() } if (ImGui::Button(text_buf.c_str())) // Button clicked? { - App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast(new ActorPtr(actor)))); } ImGui::PopStyleColor(); } @@ -1341,7 +1347,7 @@ void TopMenubar::DrawSpecialStateBox(float top_offset) GameContextSB& data = App::GetGfxScene()->GetSimDataBuffer(); GUIManager::GuiTheme const& theme = App::GetGuiManager()->GetTheme(); float distance = 0.0f; - Actor* player_actor = App::GetGfxScene()->GetSimDataBuffer().simbuf_player_actor; + ActorPtr player_actor = App::GetGfxScene()->GetSimDataBuffer().simbuf_player_actor; if (player_actor != nullptr && App::GetGameContext()->GetPlayerActor() && player_actor->GetGfxActor()->GetSimDataBuffer().simbuf_actor_state == ActorState::LOCAL_SIMULATED) { diff --git a/source/main/gui/panels/GUI_VehicleButtons.cpp b/source/main/gui/panels/GUI_VehicleButtons.cpp index b6d5393926..a44a4a09ae 100644 --- a/source/main/gui/panels/GUI_VehicleButtons.cpp +++ b/source/main/gui/panels/GUI_VehicleButtons.cpp @@ -627,7 +627,7 @@ void VehicleButtons::DrawActorPhysicsButton(RoR::GfxActor* actorx) if (ImGui::ImageButton(reinterpret_cast(m_actor_physics_icon->getHandle()), ImVec2(24, 24))) { - for (auto actor : actorx->GetActor()->getAllLinkedActors()) + for (ActorPtr actor : actorx->GetActor()->getAllLinkedActors()) { actor->ar_physics_paused = !actorx->GetActor()->ar_physics_paused; } diff --git a/source/main/gui/panels/GUI_VehicleDescription.cpp b/source/main/gui/panels/GUI_VehicleDescription.cpp index 9350410945..59f08cb2a3 100644 --- a/source/main/gui/panels/GUI_VehicleDescription.cpp +++ b/source/main/gui/panels/GUI_VehicleDescription.cpp @@ -40,7 +40,7 @@ using namespace GUI; void VehicleDescription::Draw() { - Actor* actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr actor = App::GetGameContext()->GetPlayerActor(); if (!actor) { m_is_visible = false; diff --git a/source/main/main.cpp b/source/main/main.cpp index 43ea4c1a54..9b27bfe490 100644 --- a/source/main/main.cpp +++ b/source/main/main.cpp @@ -19,6 +19,7 @@ along with Rigs of Rods. If not, see . */ +#include "Actor.h" #include "Application.h" #include "AppContext.h" #include "CacheSystem.h" @@ -342,6 +343,7 @@ int main(int argc, char *argv[]) } #endif // USE_SOCKETW App::app_state->setVal((int)AppState::SHUTDOWN); + App::GetScriptEngine()->setEventsEnabled(false); // Hack to enable fast shutdown without cleanup. break; case MSG_APP_SCREENSHOT_REQUESTED: @@ -500,7 +502,7 @@ int main(int argc, char *argv[]) // -- Gameplay events -- case MSG_SIM_PAUSE_REQUESTED: - for (Actor* actor: App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors()) { actor->muteAllSounds(); } @@ -508,7 +510,7 @@ int main(int argc, char *argv[]) break; case MSG_SIM_UNPAUSE_REQUESTED: - for (Actor* actor: App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors()) { actor->unmuteAllSounds(); } @@ -655,18 +657,26 @@ int main(int argc, char *argv[]) break; case MSG_SIM_DELETE_ACTOR_REQUESTED: + { + ActorPtr* actor_ptr = static_cast(m.payload); if (App::app_state->getEnum() == AppState::SIMULATION) { - App::GetGameContext()->DeleteActor((Actor*)m.payload); + App::GetGameContext()->DeleteActor(*actor_ptr); } + delete actor_ptr; break; + } case MSG_SIM_SEAT_PLAYER_REQUESTED: + { + ActorPtr* actor_ptr = static_cast(m.payload); if (App::app_state->getEnum() == AppState::SIMULATION) { - App::GetGameContext()->ChangePlayerActor((Actor*)m.payload); + App::GetGameContext()->ChangePlayerActor(*actor_ptr); } + delete actor_ptr; break; + } case MSG_SIM_TELEPORT_PLAYER_REQUESTED: if (App::app_state->getEnum() == AppState::SIMULATION) @@ -678,10 +688,12 @@ int main(int argc, char *argv[]) break; case MSG_SIM_HIDE_NET_ACTOR_REQUESTED: - if (App::mp_state->getEnum() == MpState::CONNECTED && - ((Actor*)m.payload)->ar_state == ActorState::NETWORKED_OK) + { + ActorPtr* actor_ptr = static_cast(m.payload); + if ((App::mp_state->getEnum() == MpState::CONNECTED) && + ((*actor_ptr)->ar_state == ActorState::NETWORKED_OK)) { - Actor* actor = (Actor*)m.payload; + ActorPtr actor = *actor_ptr; actor->ar_state = ActorState::NETWORKED_HIDDEN; // Stop net. updates App::GetGfxScene()->RemoveGfxActor(actor->GetGfxActor()); // Remove visuals (also stops updating SimBuffer) actor->GetGfxActor()->GetSimDataBuffer().simbuf_actor_state = ActorState::NETWORKED_HIDDEN; // Hack - manually propagate the new state to SimBuffer so Character can reflect it. @@ -691,13 +703,17 @@ int main(int argc, char *argv[]) actor->setLightsOff(); // Turn all lights off actor->setSmokeEnabled(false); } + delete actor_ptr; break; + } case MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED: + { + ActorPtr* actor_ptr = static_cast(m.payload); if (App::mp_state->getEnum() == MpState::CONNECTED && - ((Actor*)m.payload)->ar_state == ActorState::NETWORKED_HIDDEN) + ((*actor_ptr)->ar_state == ActorState::NETWORKED_HIDDEN)) { - Actor* actor = (Actor*)m.payload; + ActorPtr actor = *actor_ptr; actor->ar_state = ActorState::NETWORKED_OK; // Resume net. updates App::GetGfxScene()->RegisterGfxActor(actor->GetGfxActor()); // Restore visuals (also resumes updating SimBuffer) actor->GetGfxActor()->SetAllMeshesVisible(true); @@ -705,7 +721,9 @@ int main(int argc, char *argv[]) actor->unmuteAllSounds(); // Unmute sounds actor->setSmokeEnabled(true); } + delete actor_ptr; break; + } // -- GUI events --- @@ -785,11 +803,11 @@ int main(int argc, char *argv[]) // To reload the bundle, it's resource group must be destroyed and re-created. All actors using it must be deleted. CacheEntry* entry = reinterpret_cast(m.payload); bool all_clear = true; - for (Actor* actor: App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->GetGfxActor()->GetResourceGroup() == entry->resource_group) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); all_clear = false; } } @@ -933,7 +951,7 @@ int main(int argc, char *argv[]) if (App::app_state->getEnum() == AppState::SIMULATION) { App::GetGuiManager()->DrawSimulationGui(dt); - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { actor->GetGfxActor()->UpdateDebugView(); } diff --git a/source/main/network/OutGauge.cpp b/source/main/network/OutGauge.cpp index bb373a76e5..8fdb95a65a 100644 --- a/source/main/network/OutGauge.cpp +++ b/source/main/network/OutGauge.cpp @@ -100,7 +100,7 @@ void OutGauge::Connect() #endif // _WIN32 } -bool OutGauge::Update(float dt, Actor* truck) +bool OutGauge::Update(float dt, ActorPtr truck) { #if defined(_WIN32) && defined(USE_SOCKETW) if (!working) diff --git a/source/main/network/OutGauge.h b/source/main/network/OutGauge.h index f9fd913577..1a63be58c4 100644 --- a/source/main/network/OutGauge.h +++ b/source/main/network/OutGauge.h @@ -49,7 +49,7 @@ class OutGauge OutGauge(void); void Connect(); - bool Update(float dt, Actor* truck); + bool Update(float dt, ActorPtr truck); void Close(); private: diff --git a/source/main/physics/Actor.cpp b/source/main/physics/Actor.cpp index b03443e34d..5ffbc3d82f 100644 --- a/source/main/physics/Actor.cpp +++ b/source/main/physics/Actor.cpp @@ -2,7 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer - Copyright 2013-2020 Petr Ohlidal + Copyright 2013-2022 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -79,11 +79,20 @@ static const Ogre::Vector3 BOUNDING_BOX_PADDING(0.05f, 0.05f, 0.05f); Actor::~Actor() { - TRIGGER_EVENT(SE_GENERIC_DELETED_TRUCK, ar_instance_id); + if (ar_state != ActorState::DISPOSED) + { + this->dispose(); + } +} - // TODO: IMPROVE below: delete/destroy prop entities, etc +void Actor::dispose() +{ + TRIGGER_EVENT(SE_GENERIC_DELETED_TRUCK, ar_instance_id); + ar_state = ActorState::DISPOSED; this->DisjoinInterActorBeams(); + ar_hooks.clear(); + ar_ties.clear(); // delete all classes we might have constructed if (ar_dashboard != nullptr) @@ -115,7 +124,7 @@ Actor::~Actor() if (m_fusealge_airfoil) delete m_fusealge_airfoil; - m_fusealge_airfoil = 0; + m_fusealge_airfoil = nullptr; if (m_replay_handler) delete m_replay_handler; @@ -123,9 +132,8 @@ Actor::~Actor() if (ar_vehicle_ai) delete ar_vehicle_ai; - ar_vehicle_ai = 0; + ar_vehicle_ai = nullptr; - // TODO: Make sure we catch everything here // remove all scene nodes if (m_deletion_scene_nodes.size() > 0) { @@ -247,6 +255,7 @@ Actor::~Actor() { delete (*it); } + m_railgroups.clear(); if (m_intra_point_col_detector) { @@ -268,26 +277,37 @@ Actor::~Actor() if (m_axle_diffs[i] != nullptr) delete m_axle_diffs[i]; } + m_num_axle_diffs = 0; for (int i = 0; i < m_num_wheel_diffs; ++i) { if (m_wheel_diffs[i] != nullptr) delete m_wheel_diffs[i]; } - - delete ar_nodes; - delete ar_beams; - delete ar_shocks; - delete ar_rotators; - delete ar_wings; + m_num_wheel_diffs = 0; + + delete[] ar_nodes; + ar_num_nodes = 0; + m_wheel_node_count = 0; + delete[] ar_beams; + ar_num_beams = 0; + delete[] ar_shocks; + ar_num_shocks = 0; + delete[] ar_rotators; + ar_num_rotators = 0; + delete[] ar_wings; + ar_num_wings = 0; } // This method scales actors. Stresses should *NOT* be scaled, they describe // the material type and they do not depend on length or scale. void Actor::scaleTruck(float value) { + if (ar_state == ActorState::DISPOSED) + return; if (value < 0) return; + ar_scale *= value; // scale beams for (int i = 0; i < ar_num_beams; i++) @@ -323,6 +343,9 @@ void Actor::scaleTruck(float value) float Actor::getRotation() { + if (ar_state == ActorState::DISPOSED) + return 0.f; + Vector3 dir = getDirection(); return atan2(dir.dotProduct(Vector3::UNIT_X), dir.dotProduct(-Vector3::UNIT_Z)); @@ -400,7 +423,8 @@ void Actor::pushNetwork(char* data, int size) App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_WARNING, text.ToCStr()); // Remove self - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)this)); + ActorPtr self = App::GetGameContext()->GetActorManager()->GetActorById(ar_instance_id); // Get shared pointer to ourselves so references are added correctly. + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(self)))); m_net_initialized = true; } @@ -738,12 +762,15 @@ void Actor::RecalculateNodeMasses(Real total) float Actor::getTotalMass(bool withLocked) { + if (ar_state == ActorState::DISPOSED) + return 0.f; + if (!withLocked) return m_total_mass; // already computed in RecalculateNodeMasses float mass = m_total_mass; - for (auto actor : m_linked_actors) + for (ActorPtr actor : m_linked_actors) { mass += actor->m_total_mass; } @@ -756,10 +783,10 @@ void Actor::DetermineLinkedActors() //TODO: Refactor this - logic iterating over m_linked_actors.clear(); bool found = true; - std::map lookup_table; - std::pair::iterator, bool> ret; + std::map lookup_table; + std::pair::iterator, bool> ret; - lookup_table.insert(std::pair(this, false)); + lookup_table.insert(std::pair(this, false)); auto inter_actor_links = App::GetGameContext()->GetActorManager()->inter_actor_links; // TODO: Shouldn't this have been a reference?? Also, ugly, see the TODO note above ~ only_a_ptr, 01/2018 @@ -767,18 +794,18 @@ void Actor::DetermineLinkedActors() //TODO: Refactor this - logic iterating over { found = false; - for (std::map::iterator it_beam = lookup_table.begin(); it_beam != lookup_table.end(); ++it_beam) + for (std::map::iterator it_beam = lookup_table.begin(); it_beam != lookup_table.end(); ++it_beam) { if (!it_beam->second) { - auto actor = it_beam->first; + ActorPtr actor = it_beam->first; for (auto it = inter_actor_links.begin(); it != inter_actor_links.end(); it++) { auto actor_pair = it->second; if (actor == actor_pair.first || actor == actor_pair.second) { auto other_actor = (actor != actor_pair.first) ? actor_pair.first : actor_pair.second; - ret = lookup_table.insert(std::pair(other_actor, false)); + ret = lookup_table.insert(std::pair(other_actor, false)); if (ret.second) { m_linked_actors.push_back(other_actor); @@ -816,7 +843,7 @@ void Actor::calcNodeConnectivityGraph() } } -bool Actor::Intersects(Actor* actor, Vector3 offset) +bool Actor::Intersects(ActorPtr actor, Vector3 offset) { Vector3 bb_min = ar_bounding_box.getMinimum() + offset; Vector3 bb_max = ar_bounding_box.getMaximum() + offset; @@ -900,7 +927,7 @@ Vector3 Actor::calculateCollisionOffset(Vector3 direction) bool collision = false; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor == this) continue; @@ -980,7 +1007,7 @@ Vector3 Actor::calculateCollisionOffset(Vector3 direction) // Test beams (between contactable nodes) against cabs if (!collision) { - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor == this) continue; @@ -1480,6 +1507,9 @@ float Actor::getHeightAboveGroundBelow(float height, bool skip_virtual_nodes) void Actor::reset(bool keep_position) { + if (ar_state == ActorState::DISPOSED) + return; + ActorModifyRequest* rq = new ActorModifyRequest; rq->amr_actor = this; rq->amr_type = (keep_position) ? ActorModifyRequest::Type::RESET_ON_SPOT : ActorModifyRequest::Type::RESET_ON_INIT_POS; @@ -1501,7 +1531,7 @@ void Actor::SoftReset() { Vector3 translation = -agl * Vector3::UNIT_Y; this->resetPosition(ar_nodes[0].AbsPosition + translation, false); - for (auto actor : m_linked_actors) + for (ActorPtr actor : m_linked_actors) { actor->resetPosition(actor->ar_nodes[0].AbsPosition + translation, false); } @@ -2931,12 +2961,12 @@ void Actor::prepareInside(bool inside) void Actor::lightsToggle() { // export light command - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); - if (ar_state == ActorState::LOCAL_SIMULATED && this == player_actor && ar_forward_commands) + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); + if (ar_state == ActorState::LOCAL_SIMULATED && this == player_actor.GetRef() && ar_forward_commands) { - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { - if (actor->ar_state == ActorState::LOCAL_SIMULATED && this != actor && actor->ar_import_commands) + if (actor->ar_state == ActorState::LOCAL_SIMULATED && this != actor.GetRef() && actor->ar_import_commands) actor->lightsToggle(); } } @@ -3078,6 +3108,9 @@ void Actor::toggleBlinkType(BlinkType blink) void Actor::setBlinkType(BlinkType blink) { + if (ar_state == ActorState::DISPOSED) + return; + m_blink_type = blink; ar_dashboard->setBool(DD_SIGNAL_WARNING, false); @@ -3125,6 +3158,9 @@ void Actor::autoBlinkReset() void Actor::toggleCustomParticles() { + if (ar_state == ActorState::DISPOSED) + return; + m_custom_particles_enabled = !m_custom_particles_enabled; for (int i = 0; i < ar_num_custom_particles; i++) { @@ -3262,7 +3298,7 @@ void Actor::updateVisual(float dt) ar_hydro_elevator_command = autoelevator; } -void Actor::AddInterActorBeam(beam_t* beam, Actor* a, Actor* b) +void Actor::AddInterActorBeam(beam_t* beam, ActorPtr a, ActorPtr b) { beam->bm_locked_actor = b; @@ -3272,15 +3308,15 @@ void Actor::AddInterActorBeam(beam_t* beam, Actor* a, Actor* b) ar_inter_beams.push_back(beam); } - std::pair actor_pair(a, b); + std::pair actor_pair(a, b); App::GetGameContext()->GetActorManager()->inter_actor_links[beam] = actor_pair; a->DetermineLinkedActors(); - for (auto actor : a->m_linked_actors) + for (ActorPtr actor : a->m_linked_actors) actor->DetermineLinkedActors(); b->DetermineLinkedActors(); - for (auto actor : b->m_linked_actors) + for (ActorPtr actor : b->m_linked_actors) actor->DetermineLinkedActors(); } @@ -3299,11 +3335,11 @@ void Actor::RemoveInterActorBeam(beam_t* beam) App::GetGameContext()->GetActorManager()->inter_actor_links.erase(it); actor_pair.first->DetermineLinkedActors(); - for (auto actor : actor_pair.first->m_linked_actors) + for (ActorPtr actor : actor_pair.first->m_linked_actors) actor->DetermineLinkedActors(); actor_pair.second->DetermineLinkedActors(); - for (auto actor : actor_pair.second->m_linked_actors) + for (ActorPtr actor : actor_pair.second->m_linked_actors) actor->DetermineLinkedActors(); } } @@ -3315,7 +3351,7 @@ void Actor::DisjoinInterActorBeams() for (auto it = inter_actor_links->begin(); it != inter_actor_links->end();) { auto actor_pair = it->second; - if (this == actor_pair.first || this == actor_pair.second) + if (this == actor_pair.first.GetRef() || this == actor_pair.second.GetRef()) { it->first->bm_locked_actor = nullptr; it->first->bm_inter_actor = false; @@ -3323,11 +3359,11 @@ void Actor::DisjoinInterActorBeams() inter_actor_links->erase(it++); actor_pair.first->DetermineLinkedActors(); - for (auto actor : actor_pair.first->m_linked_actors) + for (ActorPtr actor : actor_pair.first->m_linked_actors) actor->DetermineLinkedActors(); actor_pair.second->DetermineLinkedActors(); - for (auto actor : actor_pair.second->m_linked_actors) + for (ActorPtr actor : actor_pair.second->m_linked_actors) actor->DetermineLinkedActors(); } else @@ -3339,7 +3375,7 @@ void Actor::DisjoinInterActorBeams() void Actor::tieToggle(int group) { - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); // untie all ties if one is tied bool istied = false; @@ -3371,10 +3407,10 @@ void Actor::tieToggle(int group) auto linked_actors = it->ti_locked_actor->getAllLinkedActors(); if (!(std::find(linked_actors.begin(), linked_actors.end(), this) != linked_actors.end())) { - if (this == player_actor) + if (this == player_actor.GetRef()) { it->ti_locked_actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); - for (auto actor : it->ti_locked_actor->getAllLinkedActors()) + for (ActorPtr actor : it->ti_locked_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); } @@ -3382,7 +3418,7 @@ void Actor::tieToggle(int group) else if (it->ti_locked_actor == player_actor) { m_gfx_actor->SetDebugView(DebugViewType::DEBUGVIEW_NONE); - for (auto actor : this->getAllLinkedActors()) + for (ActorPtr actor : this->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); } @@ -3407,10 +3443,10 @@ void Actor::tieToggle(int group) // tie is unlocked and should get locked, search new remote ropable to lock to float mindist = it->ti_beam->refL; node_t* nearest_node = 0; - Actor* nearest_actor = 0; + ActorPtr nearest_actor = 0; ropable_t* locktedto = 0; // iterate over all actors - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_state == ActorState::LOCAL_SLEEPING || (actor == this && it->ti_no_self_lock)) @@ -3426,7 +3462,7 @@ void Actor::tieToggle(int group) continue; // skip if tienode is ropable too (no selflock) - if (this == actor && itr->node->pos == it->ti_beam->p1->pos) + if (this == actor.GetRef() && itr->node->pos == it->ti_beam->p1->pos) continue; // calculate the distance and record the nearest ropable @@ -3459,10 +3495,10 @@ void Actor::tieToggle(int group) { AddInterActorBeam(it->ti_beam, this, nearest_actor); // update skeletonview on the tied actors - if (this == player_actor) + if (this == player_actor.GetRef()) { nearest_actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); - for (auto actor : nearest_actor->getAllLinkedActors()) + for (ActorPtr actor : nearest_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); } @@ -3470,7 +3506,7 @@ void Actor::tieToggle(int group) else if (nearest_actor == player_actor) { m_gfx_actor->SetDebugView(player_actor->GetGfxActor()->GetDebugView()); - for (auto actor : this->getAllLinkedActors()) + for (ActorPtr actor : this->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(player_actor->GetGfxActor()->GetDebugView()); } @@ -3487,7 +3523,7 @@ void Actor::tieToggle(int group) void Actor::ropeToggle(int group) { - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); // iterate over all ropes for (std::vector::iterator it = ar_ropes.begin(); it != ar_ropes.end(); it++) @@ -3510,10 +3546,10 @@ void Actor::ropeToggle(int group) auto linked_actors = it->rp_locked_actor->getAllLinkedActors(); if (!(std::find(linked_actors.begin(), linked_actors.end(), this) != linked_actors.end())) { - if (this == player_actor) + if (this == player_actor.GetRef()) { it->rp_locked_actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); - for (auto actor : it->rp_locked_actor->getAllLinkedActors()) + for (ActorPtr actor : it->rp_locked_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); } @@ -3521,7 +3557,7 @@ void Actor::ropeToggle(int group) else if (it->rp_locked_actor == player_actor) { m_gfx_actor->SetDebugView(DebugViewType::DEBUGVIEW_NONE); - for (auto actor : this->getAllLinkedActors()) + for (ActorPtr actor : this->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(DebugViewType::DEBUGVIEW_NONE); } @@ -3536,10 +3572,10 @@ void Actor::ropeToggle(int group) //we lock ropes // search new remote ropable to lock to float mindist = it->rp_beam->L; - Actor* nearest_actor = nullptr; + ActorPtr nearest_actor = nullptr; ropable_t* rop = 0; // iterate over all actor_slots - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_state == ActorState::LOCAL_SLEEPING) continue; @@ -3572,10 +3608,10 @@ void Actor::ropeToggle(int group) { AddInterActorBeam(it->rp_beam, this, nearest_actor); // update skeletonview on the roped up actors - if (this == player_actor) + if (this == player_actor.GetRef()) { nearest_actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); - for (auto actor : nearest_actor->getAllLinkedActors()) + for (ActorPtr actor : nearest_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); } @@ -3583,7 +3619,7 @@ void Actor::ropeToggle(int group) else if (nearest_actor == player_actor) { m_gfx_actor->SetDebugView(player_actor->GetGfxActor()->GetDebugView()); - for (auto actor : this->getAllLinkedActors()) + for (ActorPtr actor : this->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(player_actor->GetGfxActor()->GetDebugView()); } @@ -3638,7 +3674,7 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE continue; } - Actor* prev_locked_actor = it->hk_locked_actor; // memorize current value + ActorPtr prev_locked_actor = it->hk_locked_actor; // memorize current value // do this only for toggle or lock attempts, skip prelocked or locked nodes for performance if (mode != HOOK_UNLOCK && it->hk_locked == UNLOCKED) @@ -3648,11 +3684,11 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE float mindist = it->hk_lockrange; float distance = 100000000.0f; // iterate over all actor_slots - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor->ar_state == ActorState::LOCAL_SLEEPING) continue; - if (this == actor && !it->hk_selflock) + if (this == actor.GetRef() && !it->hk_selflock) continue; // don't lock to self node_t* nearest_node = nullptr; @@ -3663,7 +3699,7 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE continue; // exclude this truck and its current hooknode from the locking search - if (this == actor && i == it->hk_hook_node->pos) + if (this == actor.GetRef() && i == it->hk_hook_node->pos) continue; // a lockgroup for this hooknode is set -> skip all nodes that do not have the same lockgroup (-1 = default(all nodes)) @@ -3715,7 +3751,7 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE if (it->hk_locked_actor) { it->hk_locked_actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); - for (auto actor : it->hk_locked_actor->getAllLinkedActors()) + for (ActorPtr actor : it->hk_locked_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); } @@ -3723,7 +3759,7 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE else if (prev_locked_actor != this) { prev_locked_actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); - for (auto actor : prev_locked_actor->getAllLinkedActors()) + for (ActorPtr actor : prev_locked_actor->getAllLinkedActors()) { actor->GetGfxActor()->SetDebugView(m_gfx_actor->GetDebugView()); } @@ -3734,6 +3770,9 @@ void Actor::hookToggle(int group, HookAction mode, NodeNum_t node_number /*=NODE void Actor::parkingbrakeToggle() { + if (ar_state == ActorState::DISPOSED) + return; + ar_parking_brake = !ar_parking_brake; if (ar_parking_brake) @@ -3747,18 +3786,27 @@ void Actor::parkingbrakeToggle() void Actor::antilockbrakeToggle() { + if (ar_state == ActorState::DISPOSED) + return; + if (!alb_notoggle) alb_mode = !alb_mode; } void Actor::tractioncontrolToggle() { + if (ar_state == ActorState::DISPOSED) + return; + if (!tc_notoggle) tc_mode = !tc_mode; } void Actor::beaconsToggle() { + if (ar_state == ActorState::DISPOSED) + return; + if (m_flares_mode == GfxFlaresMode::NONE) { return; @@ -3772,6 +3820,9 @@ void Actor::beaconsToggle() bool Actor::getReverseLightVisible() { + if (ar_state == ActorState::DISPOSED) + return false; + if (ar_state == ActorState::NETWORKED_OK) return m_net_reverse_light_on; @@ -4562,7 +4613,7 @@ Vector3 Actor::getNodePosition(int nodeNumber) } else { - return Ogre::Vector3(); + return Ogre::Vector3::ZERO; } } diff --git a/source/main/physics/Actor.h b/source/main/physics/Actor.h index 800699d1c7..b93743b813 100644 --- a/source/main/physics/Actor.h +++ b/source/main/physics/Actor.h @@ -2,7 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer - Copyright 2016-2020 Petr Ohlidal + Copyright 2016-2022 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -27,6 +27,8 @@ #include "GfxActor.h" #include "PerVehicleCameraContext.h" #include "RigDef_Prerequisites.h" +#include "RefCountingObject.h" +#include "RefCountingObjectPtr.h" #include "SimData.h" #include "TyrePressure.h" @@ -37,9 +39,11 @@ namespace RoR { /// @addtogroup Physics /// @{ +typedef std::vector ActorPtrVec; + /// Softbody object; can be anything from soda can to a space shuttle /// Former name: `Beam` (that's why scripting uses `BeamClass`) -class Actor : public ZeroedMemoryAllocator +class Actor : public ZeroedMemoryAllocator, public RefCountingObject { friend class ActorSpawner; friend class ActorManager; @@ -56,6 +60,8 @@ class Actor : public ZeroedMemoryAllocator ~Actor(); + void dispose(); //!< Effectively destroys the object but keeps it in memory to satisfy shared pointers. + /// @name Networking /// @{ void sendStreamSetup(); @@ -148,7 +154,7 @@ class Actor : public ZeroedMemoryAllocator void toggleBlinkType(BlinkType blink); BlinkType getBlinkType(); void setBlinkType(BlinkType blink); - std::vector& getAllLinkedActors() { return m_linked_actors; }; //!< Returns a list of all connected (hooked) actors + std::vector& getAllLinkedActors() { return m_linked_actors; }; //!< Returns a list of all connected (hooked) actors //! @} /// @name Visual state updates @@ -191,7 +197,7 @@ class Actor : public ZeroedMemoryAllocator void HandleInputEvents(float dt); void HandleAngelScriptEvents(float dt); void UpdateCruiseControl(float dt); //!< Defined in 'gameplay/CruiseControl.cpp' - bool Intersects(Actor* actor, Ogre::Vector3 offset = Ogre::Vector3::ZERO); //!< Slow intersection test + bool Intersects(ActorPtr actor, Ogre::Vector3 offset = Ogre::Vector3::ZERO); //!< Slow intersection test /// Moves the actor at most 'direction.length()' meters towards 'direction' to resolve any collisions void resolveCollisions(Ogre::Vector3 direction); /// Auto detects an ideal collision avoidance direction (front, back, left, right, up) @@ -219,11 +225,6 @@ class Actor : public ZeroedMemoryAllocator float GetFFbHydroForces() const { return m_force_sensors.out_hydros_forces; } bool isBeingReset() const { return m_ongoing_reset; }; void UpdatePropAnimInputEvents(); -#ifdef USE_ANGELSCRIPT - // we have to add this to be able to use the class as reference inside scripts - void addRef() {}; - void release() {}; -#endif // -------------------- Public data -------------------- // @@ -449,7 +450,7 @@ class Actor : public ZeroedMemoryAllocator void DetermineLinkedActors(); void RecalculateNodeMasses(Ogre::Real total); //!< Previously 'calc_masses2()' void calcNodeConnectivityGraph(); - void AddInterActorBeam(beam_t* beam, Actor* a, Actor* b); + void AddInterActorBeam(beam_t* beam, ActorPtr a, ActorPtr b); void RemoveInterActorBeam(beam_t* beam); void DisjoinInterActorBeams(); //!< Destroys all inter-actor beams which are connected with this actor void autoBlinkReset(); //!< Resets the turn signal when the steering wheel is turned back. @@ -462,7 +463,7 @@ class Actor : public ZeroedMemoryAllocator /// @param actor which actor to retrieve the closest Rail from /// @param node which SlideNode is being checked against /// @return a pair containing the rail, and the distant to the SlideNode - std::pair GetClosestRailOnActor( Actor* actor, const SlideNode& node); + std::pair GetClosestRailOnActor( ActorPtr actor, const SlideNode& node); // -------------------- data -------------------- // @@ -481,7 +482,7 @@ class Actor : public ZeroedMemoryAllocator float m_avionic_chatter_timer; //!< Sound fx state PointColDetector* m_inter_point_col_detector; //!< Physics PointColDetector* m_intra_point_col_detector; //!< Physics - std::vector m_linked_actors; //!< Sim state; other actors linked using 'hooks' + ActorPtrVec m_linked_actors; //!< Sim state; other actors linked using 'hooks' Ogre::Vector3 m_avg_node_position; //!< average node position Ogre::Real m_min_camera_radius; Ogre::Vector3 m_avg_node_position_prev; diff --git a/source/main/physics/ActorForcesEuler.cpp b/source/main/physics/ActorForcesEuler.cpp index 4c294178e1..b31c5586f6 100644 --- a/source/main/physics/ActorForcesEuler.cpp +++ b/source/main/physics/ActorForcesEuler.cpp @@ -65,7 +65,7 @@ void Actor::CalcForcesEulerCompute(bool doUpdate, int num_steps) void Actor::CalcForceFeedback(bool doUpdate) { - if (this == App::GetGameContext()->GetPlayerActor()) + if (this == App::GetGameContext()->GetPlayerActor().GetRef()) { if (doUpdate) { @@ -986,7 +986,7 @@ void Actor::CalcCommands(bool doUpdate) ar_engine->SetEnginePriming(requested); } - if (doUpdate && this == App::GetGameContext()->GetPlayerActor()) + if (doUpdate && this == App::GetGameContext()->GetPlayerActor().GetRef()) { #ifdef USE_OPENAL if (active > 0) @@ -1634,7 +1634,7 @@ void Actor::CalcHooks() { //enable beam if not enabled yet between those 2 nodes it->hk_beam->p2 = it->hk_lock_node; - it->hk_beam->bm_inter_actor = it->hk_locked_actor != 0; + it->hk_beam->bm_inter_actor = (it->hk_locked_actor != nullptr); it->hk_beam->L = (it->hk_hook_node->AbsPosition - it->hk_lock_node->AbsPosition).length(); it->hk_beam->bm_disabled = false; AddInterActorBeam(it->hk_beam, this, it->hk_locked_actor); diff --git a/source/main/physics/ActorManager.cpp b/source/main/physics/ActorManager.cpp index edf1dc82ae..968e2bc2da 100644 --- a/source/main/physics/ActorManager.cpp +++ b/source/main/physics/ActorManager.cpp @@ -74,9 +74,9 @@ ActorManager::~ActorManager() this->SyncWithSimThread(); // Wait for sim task to finish } -Actor* ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr def) +ActorPtr ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr def) { - Actor* actor = new Actor(m_actor_counter++, static_cast(m_actors.size()), def, rq); + ActorPtr actor = new Actor(m_actor_counter++, static_cast(m_actors.size()), def, rq); if (App::mp_state->getEnum() == MpState::CONNECTED && rq.asr_origin != ActorSpawnRequest::Origin::NETWORK) { @@ -325,7 +325,7 @@ Actor* ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr de actor->WriteDiagnosticDump(actor->ar_filename + "_dump_recalc.txt"); // Saves file to 'logs' } - m_actors.push_back(actor); + m_actors.push_back(ActorPtr(actor)); return actor; } @@ -334,14 +334,14 @@ void ActorManager::RemoveStreamSource(int sourceid) { m_stream_mismatches.erase(sourceid); - for (auto actor : m_actors) + for (ActorPtr& actor : m_actors) { if (actor->ar_state != ActorState::NETWORKED_OK) continue; if (actor->ar_net_source_id == sourceid) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } } @@ -436,7 +436,7 @@ void ActorManager::HandleActorStreamData(std::vector packet_ else if (packet.header.command == RoRnet::MSG2_STREAM_REGISTER_RESULT) { RoRnet::StreamRegister* reg = (RoRnet::StreamRegister *)packet.buffer; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_net_source_id == reg->origin_sourceid && actor->ar_net_stream_id == reg->origin_streamid) { @@ -458,12 +458,12 @@ void ActorManager::HandleActorStreamData(std::vector packet_ } else if (packet.header.command == RoRnet::MSG2_STREAM_UNREGISTER) { - Actor* b = this->GetActorByNetworkLinks(packet.header.source, packet.header.streamid); + ActorPtr b = this->GetActorByNetworkLinks(packet.header.source, packet.header.streamid); if (b) { if (b->ar_state == ActorState::NETWORKED_OK || b->ar_state == ActorState::NETWORKED_HIDDEN) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)b)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(b)))); } } m_stream_mismatches[packet.header.source].erase(packet.header.streamid); @@ -474,7 +474,7 @@ void ActorManager::HandleActorStreamData(std::vector packet_ } else if (packet.header.command == RoRnet::MSG2_STREAM_DATA) { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state != ActorState::NETWORKED_OK) continue; @@ -512,7 +512,7 @@ int ActorManager::CheckNetworkStreamsOk(int sourceid) if (!m_stream_mismatches[sourceid].empty()) return 0; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state != ActorState::NETWORKED_OK) continue; @@ -530,7 +530,7 @@ int ActorManager::CheckNetRemoteStreamsOk(int sourceid) { int result = 2; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state == ActorState::NETWORKED_OK) continue; @@ -545,9 +545,9 @@ int ActorManager::CheckNetRemoteStreamsOk(int sourceid) return result; } -Actor* ActorManager::GetActorByNetworkLinks(int source_id, int stream_id) +ActorPtr ActorManager::GetActorByNetworkLinks(int source_id, int stream_id) { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_net_source_id == source_id && actor->ar_net_stream_id == stream_id) { @@ -641,13 +641,13 @@ void ActorManager::RecursiveActivation(int j, std::vector& visited) } } -void ActorManager::ForwardCommands(Actor* source_actor) +void ActorManager::ForwardCommands(ActorPtr source_actor) { if (source_actor->ar_forward_commands) { auto linked_actors = source_actor->getAllLinkedActors(); - for (auto actor : this->GetActors()) + for (ActorPtr& actor : this->GetActors()) { if (actor != source_actor && actor->ar_import_commands && (actor->getPosition().distance(source_actor->getPosition()) < @@ -703,11 +703,11 @@ void ActorManager::ForwardCommands(Actor* source_actor) } } -void ActorManager::UpdateSleepingState(Actor* player_actor, float dt) +void ActorManager::UpdateSleepingState(ActorPtr player_actor, float dt) { if (!m_forced_awake) { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state != ActorState::LOCAL_SIMULATED) continue; @@ -750,7 +750,7 @@ void ActorManager::UpdateSleepingState(Actor* player_actor, float dt) void ActorManager::WakeUpAllActors() { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state == ActorState::LOCAL_SLEEPING) { @@ -763,7 +763,7 @@ void ActorManager::WakeUpAllActors() void ActorManager::SendAllActorsSleeping() { m_forced_awake = false; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_state == ActorState::LOCAL_SIMULATED) { @@ -772,11 +772,11 @@ void ActorManager::SendAllActorsSleeping() } } -Actor* ActorManager::FindActorInsideBox(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box) +ActorPtr ActorManager::FindActorInsideBox(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box) { // try to find the desired actor (the one in the box) - Actor* ret = nullptr; - for (auto actor : m_actors) + ActorPtr ret = nullptr; + for (ActorPtr& actor: m_actors) { if (collisions->isInside(actor->ar_nodes[0].AbsPosition, inst, box)) { @@ -793,7 +793,7 @@ Actor* ActorManager::FindActorInsideBox(Collisions* collisions, const Ogre::Stri void ActorManager::RepairActor(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box, bool keepPosition) { - Actor* actor = this->FindActorInsideBox(collisions, inst, box); + ActorPtr actor = this->FindActorInsideBox(collisions, inst, box); if (actor != nullptr) { SOUND_PLAY_ONCE(actor, SS_TRIG_REPAIR); @@ -807,7 +807,7 @@ void ActorManager::RepairActor(Collisions* collisions, const Ogre::String& inst, void ActorManager::MuteAllActors() { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { actor->muteAllSounds(); } @@ -815,17 +815,17 @@ void ActorManager::MuteAllActors() void ActorManager::UnmuteAllActors() { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { actor->unmuteAllSounds(); } } -std::pair ActorManager::GetNearestActor(Vector3 position) +std::pair ActorManager::GetNearestActor(Vector3 position) { - Actor* nearest_actor = nullptr; + ActorPtr nearest_actor = nullptr; float min_squared_distance = std::numeric_limits::max(); - for (auto actor : m_actors) + for (ActorPtr& actor : m_actors) { float squared_distance = position.squaredDistance(actor->ar_nodes[0].AbsPosition); if (squared_distance < min_squared_distance) @@ -839,9 +839,10 @@ std::pair ActorManager::GetNearestActor(Vector3 position) void ActorManager::CleanUpSimulation() // Called after simulation finishes { - for (auto actor : m_actors) + for (ActorPtr& actor : m_actors) { - delete actor; + // Only dispose(), do not `delete`; a script may still hold pointer to the object. + actor->dispose(); } m_actors.clear(); @@ -851,9 +852,9 @@ void ActorManager::CleanUpSimulation() // Called after simulation finishes m_simulation_speed = 1.f; } -void ActorManager::DeleteActorInternal(Actor* actor) +void ActorManager::DeleteActorInternal(ActorPtr actor) { - if (actor == 0) + if (actor == nullptr) return; this->SyncWithSimThread(); @@ -865,7 +866,7 @@ void ActorManager::DeleteActorInternal(Actor* actor) { App::GetNetwork()->AddPacket(actor->ar_net_stream_id, RoRnet::MSG2_STREAM_UNREGISTER, 0, 0); } - else if (std::count_if(m_actors.begin(), m_actors.end(), [actor](Actor* b) + else if (std::count_if(m_actors.begin(), m_actors.end(), [actor](ActorPtr& b) { return b->ar_net_source_id == actor->ar_net_source_id; }) == 1) { // We're deleting the last actor from this stream source, reset the stream time offset @@ -874,15 +875,28 @@ void ActorManager::DeleteActorInternal(Actor* actor) } #endif // USE_SOCKETW - m_actors.erase(std::remove(m_actors.begin(), m_actors.end(), actor), m_actors.end()); - delete actor; + auto actor_i = m_actors.begin(); + while (actor_i != m_actors.end()) + { + if (actor == actor_i->GetRef()) + { + actor_i = m_actors.erase(actor_i); + } + else + { + actor_i++; + } + } + + // Only dispose(), do not `delete`; a script may still hold pointer to the object. + actor->dispose(); // Upate actor indices for (unsigned int i = 0; i < m_actors.size(); i++) m_actors[i]->ar_vector_index = i; } -int FindPivotActorId(Actor* player, Actor* prev_player) +int FindPivotActorId(ActorPtr player, ActorPtr prev_player) { if (player != nullptr) return player->ar_vector_index; @@ -891,7 +905,7 @@ int FindPivotActorId(Actor* player, Actor* prev_player) return -1; } -Actor* ActorManager::FetchNextVehicleOnList(Actor* player, Actor* prev_player) +ActorPtr ActorManager::FetchNextVehicleOnList(ActorPtr player, ActorPtr prev_player) { int pivot_index = FindPivotActorId(player, prev_player); @@ -899,7 +913,7 @@ Actor* ActorManager::FetchNextVehicleOnList(Actor* player, Actor* prev_player) { if (m_actors[i]->ar_state != ActorState::NETWORKED_OK && !m_actors[i]->isPreloadedWithTerrain()) { - return m_actors[i]; + return m_actors[i].GetRef(); } } @@ -907,19 +921,19 @@ Actor* ActorManager::FetchNextVehicleOnList(Actor* player, Actor* prev_player) { if (m_actors[i]->ar_state != ActorState::NETWORKED_OK && !m_actors[i]->isPreloadedWithTerrain()) { - return m_actors[i]; + return m_actors[i].GetRef(); } } if (pivot_index >= 0 && m_actors[pivot_index]->ar_state != ActorState::NETWORKED_OK && !m_actors[pivot_index]->isPreloadedWithTerrain()) { - return m_actors[pivot_index]; + return m_actors[pivot_index].GetRef(); } return nullptr; } -Actor* ActorManager::FetchPreviousVehicleOnList(Actor* player, Actor* prev_player) +ActorPtr ActorManager::FetchPreviousVehicleOnList(ActorPtr player, ActorPtr prev_player) { int pivot_index = FindPivotActorId(player, prev_player); @@ -927,7 +941,7 @@ Actor* ActorManager::FetchPreviousVehicleOnList(Actor* player, Actor* prev_playe { if (m_actors[i]->ar_state != ActorState::NETWORKED_OK && !m_actors[i]->isPreloadedWithTerrain()) { - return m_actors[i]; + return m_actors[i].GetRef(); } } @@ -935,21 +949,21 @@ Actor* ActorManager::FetchPreviousVehicleOnList(Actor* player, Actor* prev_playe { if (m_actors[i]->ar_state != ActorState::NETWORKED_OK && !m_actors[i]->isPreloadedWithTerrain()) { - return m_actors[i]; + return m_actors[i].GetRef(); } } if (pivot_index >= 0 && m_actors[pivot_index]->ar_state != ActorState::NETWORKED_OK && !m_actors[pivot_index]->isPreloadedWithTerrain()) { - return m_actors[pivot_index]; + return m_actors[pivot_index].GetRef(); } return nullptr; } -Actor* ActorManager::FetchRescueVehicle() +ActorPtr ActorManager::FetchRescueVehicle() { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_rescuer_flag) { @@ -959,7 +973,7 @@ Actor* ActorManager::FetchRescueVehicle() return nullptr; } -void ActorManager::UpdateActors(Actor* player_actor) +void ActorManager::UpdateActors(ActorPtr player_actor) { float dt = m_simulation_time; @@ -982,7 +996,7 @@ void ActorManager::UpdateActors(Actor* player_actor) this->UpdateSleepingState(player_actor, dt); - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { actor->HandleInputEvents(dt); actor->HandleAngelScriptEvents(dt); @@ -1063,9 +1077,9 @@ void ActorManager::UpdateActors(Actor* player_actor) m_sim_task->join(); } -Actor* ActorManager::GetActorById(int actor_id) +ActorPtr ActorManager::GetActorById(int actor_id) { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_instance_id == actor_id) { @@ -1077,7 +1091,7 @@ Actor* ActorManager::GetActorById(int actor_id) void ActorManager::UpdatePhysicsSimulation() { - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { actor->UpdatePhysicsOrigin(); } @@ -1085,19 +1099,20 @@ void ActorManager::UpdatePhysicsSimulation() { { std::vector> tasks; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_update_physics = actor->CalcForcesEulerPrepare(i == 0)) { - auto func = std::function([this, i, actor]() + ActorPtr actor_raw = actor; + auto func = std::function([this, i, actor_raw]() { - actor->CalcForcesEulerCompute(i == 0, m_physics_steps); + actor_raw->CalcForcesEulerCompute(i == 0, m_physics_steps); }); tasks.push_back(func); } } App::GetThreadPool()->Parallelize(tasks); - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->ar_update_physics) { @@ -1107,25 +1122,26 @@ void ActorManager::UpdatePhysicsSimulation() } { std::vector> tasks; - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { if (actor->m_inter_point_col_detector != nullptr && (actor->ar_update_physics || (App::mp_pseudo_collisions->getBool() && actor->ar_state == ActorState::NETWORKED_OK))) { - auto func = std::function([this, actor]() + ActorPtr actor_raw = actor; + auto func = std::function([this, actor_raw]() { - actor->m_inter_point_col_detector->UpdateInterPoint(); - if (actor->ar_collision_relevant) + actor_raw->m_inter_point_col_detector->UpdateInterPoint(); + if (actor_raw->ar_collision_relevant) { ResolveInterActorCollisions(PHYSICS_DT, - *actor->m_inter_point_col_detector, - actor->ar_num_collcabs, - actor->ar_collcabs, - actor->ar_cabs, - actor->ar_inter_collcabrate, - actor->ar_nodes, - actor->ar_collision_range, - *actor->ar_submesh_ground_model); + *actor_raw->m_inter_point_col_detector, + actor_raw->ar_num_collcabs, + actor_raw->ar_collcabs, + actor_raw->ar_cabs, + actor_raw->ar_inter_collcabrate, + actor_raw->ar_nodes, + actor_raw->ar_collision_range, + *actor_raw->ar_submesh_ground_model); } }); tasks.push_back(func); @@ -1134,7 +1150,7 @@ void ActorManager::UpdatePhysicsSimulation() App::GetThreadPool()->Parallelize(tasks); } } - for (auto actor : m_actors) + for (ActorPtr& actor: m_actors) { actor->m_ongoing_reset = false; if (actor->ar_update_physics && m_physics_steps > 0) @@ -1257,10 +1273,10 @@ RigDef::DocumentPtr ActorManager::FetchActorDef(std::string filename, bool prede } } -std::vector ActorManager::GetLocalActors() +std::vector ActorManager::GetLocalActors() { - std::vector actors; - for (auto actor : m_actors) + std::vector actors; + for (ActorPtr& actor: m_actors) { if (actor->ar_state != ActorState::NETWORKED_OK) actors.push_back(actor); @@ -1358,7 +1374,7 @@ void ActorManager::UpdateInputEvents(float dt) } } -void ActorManager::UpdateTruckFeatures(Actor* vehicle, float dt) +void ActorManager::UpdateTruckFeatures(ActorPtr vehicle, float dt) { if (vehicle->isBeingReset() || vehicle->ar_physics_paused) return; diff --git a/source/main/physics/ActorManager.h b/source/main/physics/ActorManager.h index e4e73003cf..a7db9bd891 100644 --- a/source/main/physics/ActorManager.h +++ b/source/main/physics/ActorManager.h @@ -24,8 +24,8 @@ #pragma once +#include "Actor.h" #include "Application.h" - #include "SimData.h" #include "CmdKeyInertia.h" #include "Network.h" @@ -50,8 +50,13 @@ class ActorManager ActorManager(); ~ActorManager(); - Actor* CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr def); - void UpdateActors(Actor* player_actor); + /// @name Lifetime + /// @{ + ActorPtr CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr def); + void DeleteActorInternal(ActorPtr actor); //!< Do not call directly; use `GameContext::DeleteActor()` + /// @} + + void UpdateActors(ActorPtr player_actor); void SyncWithSimThread(); void UpdatePhysicsSimulation(); void WakeUpAllActors(); @@ -72,16 +77,16 @@ class ActorManager void SetSimulationPaused(bool v) { m_simulation_paused = v; } float GetTotalTime() const { return m_total_sim_time; } RoR::CmdKeyInertiaConfig& GetInertiaConfig() { return m_inertia_config; } - Actor* FetchNextVehicleOnList(Actor* player, Actor* prev_player); - Actor* FetchPreviousVehicleOnList(Actor* player, Actor* prev_player); - Actor* FetchRescueVehicle(); + ActorPtr FetchNextVehicleOnList(ActorPtr player, ActorPtr prev_player); + ActorPtr FetchPreviousVehicleOnList(ActorPtr player, ActorPtr prev_player); + ActorPtr FetchRescueVehicle(); void CleanUpSimulation(); //!< Call this after simulation loop finishes. - Actor* GetActorByNetworkLinks(int source_id, int stream_id); // used by character + ActorPtr GetActorByNetworkLinks(int source_id, int stream_id); // used by character void RepairActor(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box, bool keepPosition = false); - void UpdateSleepingState(Actor* player_actor, float dt); - void DeleteActorInternal(Actor* b); //!< Use `GameContext::DeleteActor()` - Actor* GetActorById(int actor_id); - Actor* FindActorInsideBox(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box); + void UpdateSleepingState(ActorPtr player_actor, float dt); + + ActorPtr GetActorById(int actor_id); + ActorPtr FindActorInsideBox(Collisions* collisions, const Ogre::String& inst, const Ogre::String& box); void UpdateInputEvents(float dt); RigDef::DocumentPtr FetchActorDef(std::string filename, bool predefined_on_terrain = false); @@ -93,15 +98,15 @@ class ActorManager bool LoadScene(Ogre::String filename); bool SaveScene(Ogre::String filename); - void RestoreSavedState(Actor* actor, rapidjson::Value const& j_entry); + void RestoreSavedState(ActorPtr actor, rapidjson::Value const& j_entry); - std::vector GetActors() const { return m_actors; }; - std::vector GetLocalActors(); + ActorPtrVec& GetActors() { return m_actors; }; + std::vector GetLocalActors(); - std::pair GetNearestActor(Ogre::Vector3 position); + std::pair GetNearestActor(Ogre::Vector3 position); // A list of all beams interconnecting two actors - std::map> inter_actor_links; + std::map> inter_actor_links; private: @@ -109,8 +114,8 @@ class ActorManager bool PredictActorCollAabbIntersect(int a, int b); //!< Returns whether or not the bounding boxes of truck a and truck b might intersect during the next framestep. Based on the truck collision bounding boxes. void RemoveStreamSource(int sourceid); void RecursiveActivation(int j, std::vector& visited); - void ForwardCommands(Actor* source_actor); //!< Fowards things to trailers - void UpdateTruckFeatures(Actor* vehicle, float dt); + void ForwardCommands(ActorPtr source_actor); //!< Fowards things to trailers + void UpdateTruckFeatures(ActorPtr vehicle, float dt); // Networking std::map> m_stream_mismatches; //!< Networking: A set of streams without a corresponding actor in the actor-array for each stream source @@ -118,7 +123,7 @@ class ActorManager Ogre::Timer m_net_timer; // Physics - std::vector m_actors; + ActorPtrVec m_actors; bool m_forced_awake = false; //!< disables sleep counters int m_physics_steps = 0; float m_dt_remainder = 0.f; //!< Keeps track of the rounding error in the time step calculation diff --git a/source/main/physics/ActorSlideNode.cpp b/source/main/physics/ActorSlideNode.cpp index 22513e8572..ef5b9399de 100644 --- a/source/main/physics/ActorSlideNode.cpp +++ b/source/main/physics/ActorSlideNode.cpp @@ -53,10 +53,10 @@ void Actor::toggleSlideNodeLock() } // check all the slide rail on all the other trucks :( - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { // make sure this truck is allowed - if ((this != actor && !itNode->sn_attach_foreign) || (this == actor && !itNode->sn_attach_self)) + if ((this != actor.GetRef() && !itNode->sn_attach_foreign) || (this == actor.GetRef() && !itNode->sn_attach_self)) continue; current = GetClosestRailOnActor(actor, (*itNode)); @@ -70,7 +70,7 @@ void Actor::toggleSlideNodeLock() m_slidenodes_locked = !m_slidenodes_locked; } // is ugly.... -std::pair Actor::GetClosestRailOnActor(Actor* actor, const SlideNode& node) +std::pair Actor::GetClosestRailOnActor(ActorPtr actor, const SlideNode& node) { std::pair closest((RailGroup*)NULL, std::numeric_limits::infinity()); diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index 79b423a592..1c8d8974c6 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -1125,14 +1125,14 @@ void ActorSpawner::ProcessSoundSource2(RigDef::SoundSource2 & def) #endif // USE_OPENAL } -void ActorSpawner::AddSoundSourceInstance(Actor *vehicle, Ogre::String const & sound_script_name, int node_index, int type) +void ActorSpawner::AddSoundSourceInstance(ActorPtr const& vehicle, Ogre::String const & sound_script_name, int node_index, int type) { #ifdef USE_OPENAL AddSoundSource(vehicle, App::GetSoundScriptManager()->createInstance(sound_script_name, vehicle->ar_instance_id, nullptr), (NodeNum_t)node_index); #endif // USE_OPENAL } -void ActorSpawner::AddSoundSource(Actor *vehicle, SoundScriptInstance *sound_script, NodeNum_t node_index, int type) +void ActorSpawner::AddSoundSource(ActorPtr const& vehicle, SoundScriptInstance *sound_script, NodeNum_t node_index, int type) { if (! CheckSoundScriptLimit(vehicle, 1)) { @@ -5873,7 +5873,7 @@ bool ActorSpawner::CheckTexcoordLimit(unsigned int count) } /* Static version */ -bool ActorSpawner::CheckSoundScriptLimit(Actor *vehicle, unsigned int count) +bool ActorSpawner::CheckSoundScriptLimit(ActorPtr const& vehicle, unsigned int count) { if ((vehicle->ar_num_soundsources + count) > MAX_SOUNDSCRIPTS_PER_TRUCK) { @@ -5990,7 +5990,7 @@ void ActorSpawner::SetBeamDamping(beam_t & beam, float damping) beam.d = damping; } -void ActorSpawner::SetupDefaultSoundSources(Actor *vehicle) +void ActorSpawner::SetupDefaultSoundSources(ActorPtr const& vehicle) { int trucknum = vehicle->ar_instance_id; int ar_exhaust_pos_node = vehicle->ar_exhaust_pos_node; diff --git a/source/main/physics/ActorSpawner.h b/source/main/physics/ActorSpawner.h index 180abb0b4b..1c157f12e4 100644 --- a/source/main/physics/ActorSpawner.h +++ b/source/main/physics/ActorSpawner.h @@ -96,13 +96,13 @@ class ActorSpawner /// @name Processing /// @{ void ConfigureSections(Ogre::String const & sectionconfig, RigDef::DocumentPtr def); - void ProcessNewActor(Actor *actor, ActorSpawnRequest rq, RigDef::DocumentPtr def); - static void SetupDefaultSoundSources(Actor *actor); + void ProcessNewActor(ActorPtr actor, ActorSpawnRequest rq, RigDef::DocumentPtr def); + static void SetupDefaultSoundSources(ActorPtr const& actor); /// @} /// @name Utility /// @{ - Actor* GetActor() { return m_actor; } + ActorPtr GetActor() { return m_actor; } ActorMemoryRequirements const& GetMemoryRequirements() { return m_memory_requirements; } std::string GetSubmeshGroundmodelName(); /// @} @@ -361,7 +361,7 @@ class ActorSpawner bool CheckTexcoordLimit(unsigned int count); bool CheckCabLimit(unsigned int count); bool CheckCameraRailLimit(unsigned int count); - static bool CheckSoundScriptLimit(Actor *vehicle, unsigned int count); + static bool CheckSoundScriptLimit(ActorPtr const& vehicle, unsigned int count); bool CheckAeroEngineLimit(unsigned int count); bool CheckScrewpropLimit(unsigned int count); /// @} @@ -415,8 +415,8 @@ class ActorSpawner /// @name Audio setup /// @{ - static void AddSoundSource(Actor *vehicle, SoundScriptInstance *sound_script, NodeNum_t node_index, int type = -2); - static void AddSoundSourceInstance(Actor *vehicle, Ogre::String const & sound_script_name, int node_index, int type = -2); + static void AddSoundSource(ActorPtr const& vehicle, SoundScriptInstance *sound_script, NodeNum_t node_index, int type = -2); + static void AddSoundSourceInstance(ActorPtr const& vehicle, Ogre::String const & sound_script_name, int node_index, int type = -2); /// @} /// Maintenance @@ -434,7 +434,7 @@ class ActorSpawner /// @name Settings /// @{ - Actor* m_actor; + ActorPtr m_actor; RigDef::DocumentPtr m_file; std::list> m_selected_modules; diff --git a/source/main/physics/ActorSpawnerFlow.cpp b/source/main/physics/ActorSpawnerFlow.cpp index e39a6c8c65..b123b21c78 100644 --- a/source/main/physics/ActorSpawnerFlow.cpp +++ b/source/main/physics/ActorSpawnerFlow.cpp @@ -54,7 +54,7 @@ using namespace RoR; this->SetCurrentKeyword(RigDef::Keyword::INVALID); \ } -void ActorSpawner::ProcessNewActor(Actor* actor, ActorSpawnRequest rq, RigDef::DocumentPtr def) +void ActorSpawner::ProcessNewActor(ActorPtr actor, ActorSpawnRequest rq, RigDef::DocumentPtr def) { m_actor = actor; m_file = def; diff --git a/source/main/physics/Savegame.cpp b/source/main/physics/Savegame.cpp index 38ac047c29..d3be16c3e5 100644 --- a/source/main/physics/Savegame.cpp +++ b/source/main/physics/Savegame.cpp @@ -298,8 +298,8 @@ bool ActorManager::LoadScene(Ogre::String filename) auto actors_changed = false; auto player_actor = App::GetGameContext()->GetPlayerActor(); auto prev_player_actor = App::GetGameContext()->GetPrevPlayerActor(); - std::vector actors; - std::vector x_actors = GetLocalActors(); + std::vector actors; + std::vector x_actors = GetLocalActors(); for (rapidjson::Value& j_entry: j_doc["actors"].GetArray()) { String filename = j_entry["filename"].GetString(); @@ -319,7 +319,7 @@ bool ActorManager::LoadScene(Ogre::String filename) String section_config = j_entry["section_config"].GetString(); - Actor* actor = nullptr; + ActorPtr actor = nullptr; int index = static_cast(actors.size()); if (index < x_actors.size()) { @@ -335,7 +335,7 @@ bool ActorManager::LoadScene(Ogre::String filename) { App::GetGameContext()->SetPrevPlayerActor(nullptr); } - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)x_actors[index])); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(x_actors[index])))); actors_changed = true; } else @@ -380,7 +380,7 @@ bool ActorManager::LoadScene(Ogre::String filename) { App::GetGameContext()->SetPrevPlayerActor(nullptr); } - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)x_actors[index])); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(x_actors[index])))); actors_changed = true; } @@ -390,7 +390,7 @@ bool ActorManager::LoadScene(Ogre::String filename) if (actors[index] == nullptr) continue; - Actor* actor = actors[index]; + ActorPtr actor = actors[index]; rapidjson::Value& j_entry = j_doc["actors"][index]; this->RestoreSavedState(actor, j_entry); @@ -407,7 +407,7 @@ bool ActorManager::LoadScene(Ogre::String filename) bool ActorManager::SaveScene(Ogre::String filename) { - std::vector x_actors = GetLocalActors(); + std::vector x_actors = GetLocalActors(); if (App::mp_state->getEnum() == RoR::MpState::CONNECTED) { @@ -453,10 +453,10 @@ bool ActorManager::SaveScene(Ogre::String filename) j_doc.AddMember("player_rotation", App::GetGameContext()->GetPlayerCharacter()->getRotation().valueRadians(), j_doc.GetAllocator()); std::map vector_index_lookup; - for (auto actor : m_actors) + for (ActorPtr& actor : m_actors) { vector_index_lookup[actor->ar_vector_index] = -1; - auto search = std::find_if(x_actors.begin(), x_actors.end(), [actor](Actor* b) + auto search = std::find_if(x_actors.begin(), x_actors.end(), [actor](ActorPtr b) { return actor->ar_instance_id == b->ar_instance_id; }); if (search != x_actors.end()) { @@ -466,7 +466,7 @@ bool ActorManager::SaveScene(Ogre::String filename) // Actors rapidjson::Value j_actors(rapidjson::kArrayType); - for (auto actor : x_actors) + for (ActorPtr actor : x_actors) { rapidjson::Value j_entry(rapidjson::kObjectType); @@ -720,7 +720,7 @@ bool ActorManager::SaveScene(Ogre::String filename) j_beam.PushBack(actor->ar_beams[i].bm_broken, j_doc.GetAllocator()); j_beam.PushBack(actor->ar_beams[i].bm_disabled, j_doc.GetAllocator()); j_beam.PushBack(actor->ar_beams[i].bm_inter_actor, j_doc.GetAllocator()); - Actor* locked_actor = actor->ar_beams[i].bm_locked_actor; + ActorPtr locked_actor = actor->ar_beams[i].bm_locked_actor; j_beam.PushBack(locked_actor ? vector_index_lookup[locked_actor->ar_vector_index] : -1, j_doc.GetAllocator()); j_beams.PushBack(j_beam, j_doc.GetAllocator()); @@ -749,7 +749,7 @@ bool ActorManager::SaveScene(Ogre::String filename) return true; } -void ActorManager::RestoreSavedState(Actor* actor, rapidjson::Value const& j_entry) +void ActorManager::RestoreSavedState(ActorPtr actor, rapidjson::Value const& j_entry) { actor->m_spawn_rotation = j_entry["spawn_rotation"].GetFloat(); actor->ar_state = static_cast(j_entry["sim_state"].GetInt()); @@ -757,7 +757,7 @@ void ActorManager::RestoreSavedState(Actor* actor, rapidjson::Value const& j_ent if (j_entry["player_actor"].GetBool()) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } else if (j_entry["prev_player_actor"].GetBool()) { @@ -905,7 +905,7 @@ void ActorManager::RestoreSavedState(Actor* actor, rapidjson::Value const& j_ent actor->ar_initial_node_positions[i] = Vector3(data[6].GetFloat(), data[7].GetFloat(), data[8].GetFloat()); } - std::vector actors = this->GetLocalActors(); + std::vector actors = this->GetLocalActors(); auto beams = j_entry["beams"].GetArray(); for (rapidjson::SizeType i = 0; i < beams.Size(); i++) diff --git a/source/main/physics/SimData.h b/source/main/physics/SimData.h index 605a761047..54bcaf0dd6 100644 --- a/source/main/physics/SimData.h +++ b/source/main/physics/SimData.h @@ -274,6 +274,7 @@ enum class ActorState NETWORKED_HIDDEN, //!< not simulated, not updated (remote) LOCAL_REPLAY, LOCAL_SLEEPING, //!< sleeping (local) actor + DISPOSED //!< removed from simulation, still in memory to satisfy pointers. }; enum class AeroEngineType @@ -353,7 +354,7 @@ struct beam_t SpecialBeam bounded; BeamType bm_type; bool bm_inter_actor; //!< in case p2 is on another actor - Actor* bm_locked_actor; //!< in case p2 is on another actor + ActorPtr bm_locked_actor; //!< in case p2 is on another actor bool bm_disabled; bool bm_broken; @@ -491,7 +492,7 @@ struct hook_t node_t* hk_hook_node; node_t* hk_lock_node; beam_t* hk_beam; - Actor* hk_locked_actor; + ActorPtr hk_locked_actor; }; struct ropable_t @@ -510,12 +511,12 @@ struct rope_t int rp_group; beam_t* rp_beam; ropable_t* rp_locked_ropable; - Actor* rp_locked_actor; + ActorPtr rp_locked_actor; }; struct tie_t { - Actor* ti_locked_actor; + ActorPtr ti_locked_actor; beam_t* ti_beam; ropable_t* ti_locked_ropable; int ti_group; @@ -784,7 +785,7 @@ struct ActorModifyRequest WAKE_UP }; - Actor* amr_actor; + ActorPtr amr_actor; Type amr_type; std::shared_ptr amr_saved_state; diff --git a/source/main/physics/SlideNode.cpp b/source/main/physics/SlideNode.cpp index 6f21a568b4..cd02c51ad9 100644 --- a/source/main/physics/SlideNode.cpp +++ b/source/main/physics/SlideNode.cpp @@ -26,6 +26,7 @@ #include "SlideNode.h" +#include "Actor.h" #include "Application.h" #include "SimData.h" diff --git a/source/main/physics/air/AirBrake.cpp b/source/main/physics/air/AirBrake.cpp index 4433e7058e..7857ae82e4 100644 --- a/source/main/physics/air/AirBrake.cpp +++ b/source/main/physics/air/AirBrake.cpp @@ -31,7 +31,7 @@ using namespace Ogre; using namespace RoR; -Airbrake::Airbrake(Actor* actor, const char* basename, int num, node_t* ndref, node_t* ndx, node_t* ndy, node_t* nda, Ogre::Vector3 pos, float width, float length, float maxang, std::string const & texname, float tx1, float ty1, float tx2, float ty2, float lift_coef) +Airbrake::Airbrake(ActorPtr actor, const char* basename, int num, node_t* ndref, node_t* ndx, node_t* ndy, node_t* nda, Ogre::Vector3 pos, float width, float length, float maxang, std::string const & texname, float tx1, float ty1, float tx2, float ty2, float lift_coef) { snode = 0; noderef = ndref; diff --git a/source/main/physics/air/AirBrake.h b/source/main/physics/air/AirBrake.h index 8877356bae..99734fd827 100644 --- a/source/main/physics/air/AirBrake.h +++ b/source/main/physics/air/AirBrake.h @@ -59,7 +59,7 @@ class Airbrake : public ZeroedMemoryAllocator Ogre::Entity* ec; public: - Airbrake(Actor* actor, const char* basename, int num, node_t* ndref, node_t* ndx, node_t* ndy, node_t* nda, Ogre::Vector3 pos, float width, float length, float maxang, std::string const & texname, float tx1, float tx2, float tx3, float tx4, float lift_coef); + Airbrake(ActorPtr actor, const char* basename, int num, node_t* ndref, node_t* ndx, node_t* ndy, node_t* nda, Ogre::Vector3 pos, float width, float length, float maxang, std::string const & texname, float tx1, float tx2, float tx3, float tx4, float lift_coef); ~Airbrake() {} // Cleanup of visuals is done by GfxActor void updatePosition(float amount); diff --git a/source/main/physics/air/TurboJet.cpp b/source/main/physics/air/TurboJet.cpp index 0ce0297e88..07d0957f1e 100644 --- a/source/main/physics/air/TurboJet.cpp +++ b/source/main/physics/air/TurboJet.cpp @@ -33,7 +33,7 @@ using namespace Ogre; using namespace RoR; -Turbojet::Turbojet(Actor* actor, NodeNum_t tnodefront, NodeNum_t tnodeback, NodeNum_t tnoderef, RigDef::Turbojet & def) +Turbojet::Turbojet(ActorPtr actor, NodeNum_t tnodefront, NodeNum_t tnodeback, NodeNum_t tnoderef, RigDef::Turbojet & def) { m_actor = actor; #ifdef USE_OPENAL diff --git a/source/main/physics/air/TurboJet.h b/source/main/physics/air/TurboJet.h index f6850fb276..67ab659363 100644 --- a/source/main/physics/air/TurboJet.h +++ b/source/main/physics/air/TurboJet.h @@ -64,7 +64,7 @@ class Turbojet: public AeroEngine, public ZeroedMemoryAllocator public: - Turbojet(Actor* actor, NodeNum_t tnodefront, NodeNum_t tnodeback, NodeNum_t tnoderef, RigDef::Turbojet & def); + Turbojet(ActorPtr actor, NodeNum_t tnodefront, NodeNum_t tnodeback, NodeNum_t tnoderef, RigDef::Turbojet & def); ~Turbojet(); void flipStart(); @@ -128,7 +128,7 @@ class Turbojet: public AeroEngine, public ZeroedMemoryAllocator int m_sound_thr; // Attachment - Actor* m_actor; + ActorPtr m_actor; NodeNum_t m_node_back; NodeNum_t m_node_front; NodeNum_t m_node_ref; diff --git a/source/main/physics/air/TurboProp.cpp b/source/main/physics/air/TurboProp.cpp index 152965707f..4a4b4efe79 100644 --- a/source/main/physics/air/TurboProp.cpp +++ b/source/main/physics/air/TurboProp.cpp @@ -35,7 +35,7 @@ using namespace Ogre; using namespace RoR; Turboprop::Turboprop( - Actor* a, + ActorPtr a, const char* propname, NodeNum_t nr, NodeNum_t nb, diff --git a/source/main/physics/air/TurboProp.h b/source/main/physics/air/TurboProp.h index 38e1763222..bf9420cde1 100644 --- a/source/main/physics/air/TurboProp.h +++ b/source/main/physics/air/TurboProp.h @@ -45,7 +45,7 @@ class Turboprop: public AeroEngine, public ZeroedMemoryAllocator float max_torque; Turboprop( - Actor* a, + ActorPtr a, const char* propname, NodeNum_t nr, NodeNum_t nb, @@ -131,7 +131,7 @@ class Turboprop: public AeroEngine, public ZeroedMemoryAllocator int thr_id; // Attachment - Actor* m_actor; + ActorPtr m_actor; NodeNum_t nodeback; NodeNum_t noderef; NodeNum_t nodep[4]; diff --git a/source/main/physics/collision/Collisions.cpp b/source/main/physics/collision/Collisions.cpp index 9f1dc38c04..9f6fbcabcc 100644 --- a/source/main/physics/collision/Collisions.cpp +++ b/source/main/physics/collision/Collisions.cpp @@ -893,7 +893,7 @@ bool Collisions::collisionCorrect(Vector3 *refpos, bool envokeScriptCallbacks) bool Collisions::permitEvent(CollisionEventFilter filter) { - Actor *b = App::GetGameContext()->GetPlayerActor(); + ActorPtr b = App::GetGameContext()->GetPlayerActor(); switch (filter) { diff --git a/source/main/physics/collision/PointColDetector.cpp b/source/main/physics/collision/PointColDetector.cpp index c6e6cb720d..7d32d113fb 100644 --- a/source/main/physics/collision/PointColDetector.cpp +++ b/source/main/physics/collision/PointColDetector.cpp @@ -48,8 +48,8 @@ void PointColDetector::UpdateInterPoint(bool ignorestate) m_linked_actors = m_actor->getAllLinkedActors(); int contacters_size = 0; - std::vector collision_partners; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + std::vector collision_partners; + for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (actor != m_actor && (ignorestate || actor->ar_update_physics) && m_actor->ar_bounding_box.intersects(actor->ar_bounding_box)) @@ -94,7 +94,7 @@ void PointColDetector::update_structures_for_contacters(bool ignoreinternal) // Insert all contacters into the list of points to consider when building the kdtree int refi = 0; - for (auto actor : m_collision_partners) + for (ActorPtr actor : m_collision_partners) { bool is_linked = std::find(m_linked_actors.begin(), m_linked_actors.end(), actor) != m_linked_actors.end(); bool internal_collision = !ignoreinternal && ((actor == m_actor) || is_linked); diff --git a/source/main/physics/collision/PointColDetector.h b/source/main/physics/collision/PointColDetector.h index 2f791f848c..94a0ddd613 100644 --- a/source/main/physics/collision/PointColDetector.h +++ b/source/main/physics/collision/PointColDetector.h @@ -35,13 +35,13 @@ class PointColDetector : public ZeroedMemoryAllocator struct pointid_t { - Actor* actor; + ActorPtr actor; short node_id; }; std::vector hit_list; - PointColDetector(Actor* actor): m_actor(actor), m_object_list_size(-1) {}; + PointColDetector(ActorPtr actor): m_actor(actor), m_object_list_size(-1) {}; void UpdateIntraPoint(bool contactables = false); void UpdateInterPoint(bool ignorestate = false); @@ -65,9 +65,9 @@ class PointColDetector : public ZeroedMemoryAllocator int begin; }; - Actor* m_actor; - std::vector m_linked_actors; - std::vector m_collision_partners; + ActorPtr m_actor; + std::vector m_linked_actors; + std::vector m_collision_partners; std::vector m_ref_list; std::vector m_pointid_list; std::vector m_kdtree; diff --git a/source/main/physics/flex/FlexAirfoil.cpp b/source/main/physics/flex/FlexAirfoil.cpp index 561a548871..6b0cfb2d51 100644 --- a/source/main/physics/flex/FlexAirfoil.cpp +++ b/source/main/physics/flex/FlexAirfoil.cpp @@ -74,7 +74,7 @@ float refairfoilpos[90]={ using namespace Ogre; -FlexAirfoil::FlexAirfoil(Ogre::String const & name, Actor* actor, NodeNum_t pnfld, NodeNum_t pnfrd, NodeNum_t pnflu, NodeNum_t pnfru, NodeNum_t pnbld, NodeNum_t pnbrd, NodeNum_t pnblu, NodeNum_t pnbru, std::string const & texband, Vector2 texlf, Vector2 texrf, Vector2 texlb, Vector2 texrb, char mtype, float controlratio, float mind, float maxd, Ogre::String const & afname, float lift_coef, bool break_able) +FlexAirfoil::FlexAirfoil(Ogre::String const & name, ActorPtr actor, NodeNum_t pnfld, NodeNum_t pnfrd, NodeNum_t pnflu, NodeNum_t pnfru, NodeNum_t pnbld, NodeNum_t pnbrd, NodeNum_t pnblu, NodeNum_t pnbru, std::string const & texband, Vector2 texlf, Vector2 texrf, Vector2 texlb, Vector2 texrb, char mtype, float controlratio, float mind, float maxd, Ogre::String const & afname, float lift_coef, bool break_able) :nfld(pnfld) ,nfrd(pnfrd) ,nflu(pnflu) diff --git a/source/main/physics/flex/FlexAirfoil.h b/source/main/physics/flex/FlexAirfoil.h index 7f68415690..1e2ea8f7aa 100644 --- a/source/main/physics/flex/FlexAirfoil.h +++ b/source/main/physics/flex/FlexAirfoil.h @@ -33,7 +33,7 @@ namespace RoR { class FlexAirfoil : public ZeroedMemoryAllocator { public: - FlexAirfoil(Ogre::String const& wname, Actor* actor, + FlexAirfoil(Ogre::String const& wname, ActorPtr actor, NodeNum_t pnfld, NodeNum_t pnfrd, NodeNum_t pnflu, NodeNum_t pnfru, NodeNum_t pnbld, NodeNum_t pnbrd, NodeNum_t pnblu, NodeNum_t pnbru, std::string const & texname, Ogre::Vector2 texlf, Ogre::Vector2 texrf, Ogre::Vector2 texlb, Ogre::Vector2 texrb, diff --git a/source/main/physics/water/ScrewProp.cpp b/source/main/physics/water/ScrewProp.cpp index e76b8dfe15..0ec595dab1 100644 --- a/source/main/physics/water/ScrewProp.cpp +++ b/source/main/physics/water/ScrewProp.cpp @@ -33,7 +33,7 @@ using namespace Ogre; using namespace RoR; -Screwprop::Screwprop(Actor* a, NodeNum_t noderef, NodeNum_t nodeback, NodeNum_t nodeup, float fullpower) : +Screwprop::Screwprop(ActorPtr a, NodeNum_t noderef, NodeNum_t nodeback, NodeNum_t nodeup, float fullpower) : m_actor(a) , noderef(noderef) , nodeback(nodeback) diff --git a/source/main/physics/water/ScrewProp.h b/source/main/physics/water/ScrewProp.h index 9f3b3280c7..7b6937e26e 100644 --- a/source/main/physics/water/ScrewProp.h +++ b/source/main/physics/water/ScrewProp.h @@ -35,7 +35,7 @@ class Screwprop : public ZeroedMemoryAllocator { public: - Screwprop( Actor* actor, NodeNum_t noderef, NodeNum_t nodeback, NodeNum_t nodeup, float power); + Screwprop( ActorPtr actor, NodeNum_t noderef, NodeNum_t nodeback, NodeNum_t nodeup, float power); void updateForces(int update); void setThrottle(float val); @@ -54,7 +54,7 @@ class Screwprop : public ZeroedMemoryAllocator float throtle; // Attachment - Actor* m_actor; + ActorPtr m_actor; NodeNum_t nodeback; NodeNum_t noderef; NodeNum_t nodeup; diff --git a/source/main/resources/odef_fileformat/ODefFileFormat.cpp b/source/main/resources/odef_fileformat/ODefFileFormat.cpp index 412b3216bb..e1bf987251 100644 --- a/source/main/resources/odef_fileformat/ODefFileFormat.cpp +++ b/source/main/resources/odef_fileformat/ODefFileFormat.cpp @@ -19,6 +19,7 @@ #include "ODefFileFormat.h" +#include "Actor.h" #include "Utils.h" using namespace RoR; diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.cpp b/source/main/resources/rig_def_fileformat/RigDef_File.cpp index a712a4ac8d..9f50a3cc9a 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_File.cpp @@ -24,6 +24,8 @@ /// @date 12/2013 #include "RigDef_File.h" + +#include "Actor.h" #include "SimConstants.h" namespace RigDef diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp index 37b05a0580..d8c4ef16d3 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp @@ -25,6 +25,7 @@ #include "RigDef_Parser.h" +#include "Actor.h" #include "Application.h" #include "SimConstants.h" #include "CacheSystem.h" diff --git a/source/main/resources/rig_def_fileformat/RigDef_SequentialImporter.cpp b/source/main/resources/rig_def_fileformat/RigDef_SequentialImporter.cpp index ece0655ae7..8edb642049 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_SequentialImporter.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_SequentialImporter.cpp @@ -26,6 +26,7 @@ #include #include "RigDef_SequentialImporter.h" +#include "Actor.h" #include "Application.h" #include "Console.h" #include "RigDef_Parser.h" diff --git a/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp b/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp index 0ff2bab3bd..701dcd178c 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp @@ -25,6 +25,7 @@ #include "RigDef_Serializer.h" +#include "Actor.h" #include "RigDef_File.h" #include diff --git a/source/main/resources/rig_def_fileformat/RigDef_Validator.cpp b/source/main/resources/rig_def_fileformat/RigDef_Validator.cpp index ba9a995172..8ad4fc7bfd 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Validator.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Validator.cpp @@ -25,6 +25,7 @@ #include "RigDef_Validator.h" +#include "Actor.h" #include "SimConstants.h" #include "Application.h" #include "Console.h" diff --git a/source/main/resources/tobj_fileformat/TObjFileFormat.cpp b/source/main/resources/tobj_fileformat/TObjFileFormat.cpp index ebd326813c..59e397b977 100644 --- a/source/main/resources/tobj_fileformat/TObjFileFormat.cpp +++ b/source/main/resources/tobj_fileformat/TObjFileFormat.cpp @@ -19,6 +19,7 @@ #include "TObjFileFormat.h" +#include "Actor.h" #include "ProceduralRoad.h" #define LOGSTREAM Ogre::LogManager::getSingleton().stream() << "[RoR|TObj fileformat] " diff --git a/source/main/scripting/GameScript.cpp b/source/main/scripting/GameScript.cpp index 9650da503c..7ed1b7fbe7 100644 --- a/source/main/scripting/GameScript.cpp +++ b/source/main/scripting/GameScript.cpp @@ -232,7 +232,7 @@ float GameScript::getWaterHeight() return result; } -Actor* GameScript::getCurrentTruck() +ActorPtr GameScript::getCurrentTruck() { return App::GetGameContext()->GetPlayerActor(); } @@ -255,7 +255,7 @@ void GameScript::setGravity(float value) App::GetSimTerrain()->setGravity(value); } -Actor* GameScript::getTruckByNum(int num) +ActorPtr GameScript::getTruckByNum(int num) { return App::GetGameContext()->GetActorManager()->GetActorById(num); } @@ -268,7 +268,7 @@ int GameScript::getNumTrucks() int GameScript::getNumTrucksByFlag(int flag) { int result = 0; - for (auto actor : App::GetGameContext()->GetActorManager()->GetActors()) + for (ActorPtr actor : App::GetGameContext()->GetActorManager()->GetActors()) { if (!flag || static_cast(actor->ar_state) == flag) result++; @@ -278,7 +278,7 @@ int GameScript::getNumTrucksByFlag(int flag) int GameScript::getCurrentTruckNumber() { - Actor* actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr actor = App::GetGameContext()->GetPlayerActor(); return (actor != nullptr) ? actor->ar_instance_id : -1; } @@ -372,10 +372,10 @@ void GameScript::repairVehicle(const String& instance, const String& box, bool k void GameScript::removeVehicle(const String& event_source_instance_name, const String& event_source_box_name) { - Actor* actor = App::GetGameContext()->FindActorByCollisionBox(event_source_instance_name, event_source_box_name); + ActorPtr actor = App::GetGameContext()->FindActorByCollisionBox(event_source_instance_name, event_source_box_name); if (actor) { - App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, (void*)actor)); + App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast(new ActorPtr(actor)))); } } @@ -761,7 +761,7 @@ int GameScript::useOnlineAPI(const String& apiquery, const AngelScript::CScriptD if (unit_id == SCRIPTUNITID_INVALID) return 2; - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); if (player_actor == nullptr) return 1; @@ -794,7 +794,7 @@ int GameScript::useOnlineAPI(const String& apiquery, const AngelScript::CScriptD j_doc.AddMember("actor-hash", rapidjson::StringRef(player_actor->ar_filehash.c_str()), j_doc.GetAllocator()); rapidjson::Value j_linked_actors(rapidjson::kArrayType); - for (auto actor : player_actor->getAllLinkedActors()) + for (ActorPtr actor : player_actor->getAllLinkedActors()) { rapidjson::Value j_actor(rapidjson::kObjectType); j_actor.AddMember("actor-name", rapidjson::StringRef(actor->ar_design_name.c_str()), j_doc.GetAllocator()); @@ -849,7 +849,7 @@ int GameScript::useOnlineAPI(const String& apiquery, const AngelScript::CScriptD void GameScript::boostCurrentTruck(float factor) { - Actor* actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr actor = App::GetGameContext()->GetPlayerActor(); if (actor && actor->ar_engine) { float rpm = actor->ar_engine->GetEngineRpm(); @@ -909,7 +909,7 @@ VehicleAI* GameScript::getCurrentTruckAI() VehicleAI* GameScript::getTruckAIByNum(int num) { VehicleAI* result = nullptr; - Actor* actor = App::GetGameContext()->GetActorManager()->GetActorById(num); + ActorPtr actor = App::GetGameContext()->GetActorManager()->GetActorById(num); if (actor != nullptr) { result = actor->ar_vehicle_ai; @@ -917,7 +917,7 @@ VehicleAI* GameScript::getTruckAIByNum(int num) return result; } -Actor* GameScript::spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot) +ActorPtr GameScript::spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot) { ActorSpawnRequest rq; rq.asr_position = pos; @@ -926,7 +926,7 @@ Actor* GameScript::spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre: return App::GetGameContext()->SpawnActor(rq); } -Actor* GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin) +ActorPtr GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin) { ActorSpawnRequest rq; rq.asr_position = pos; diff --git a/source/main/scripting/GameScript.h b/source/main/scripting/GameScript.h index 19f432f801..f0b761ac24 100644 --- a/source/main/scripting/GameScript.h +++ b/source/main/scripting/GameScript.h @@ -324,13 +324,13 @@ class GameScript : public ZeroedMemoryAllocator * returns the current selected truck, 0 if in person mode * @return reference to Beam object that is currently in use */ - Actor* getCurrentTruck(); + ActorPtr getCurrentTruck(); /** * returns a truck by index, get max index by calling getNumTrucks * @return reference to Beam object that the selected slot */ - Actor* getTruckByNum(int num); + ActorPtr getTruckByNum(int num); /** * returns the current amount of loaded trucks @@ -344,8 +344,8 @@ class GameScript : public ZeroedMemoryAllocator */ int getCurrentTruckNumber(); - Actor* spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot); - Actor* spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin); + ActorPtr spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot); + ActorPtr spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin); AngelScript::CScriptArray* getWaypoints(); int getAIVehicleCount(); int getAIVehicleDistance(); diff --git a/source/main/scripting/LocalStorage.cpp b/source/main/scripting/LocalStorage.cpp index 3e201eecdd..6497b898f7 100644 --- a/source/main/scripting/LocalStorage.cpp +++ b/source/main/scripting/LocalStorage.cpp @@ -21,6 +21,7 @@ #include "LocalStorage.h" +#include "Actor.h" #include "Application.h" #include "ContentManager.h" #include "PlatformUtils.h" diff --git a/source/main/scripting/ScriptEngine.cpp b/source/main/scripting/ScriptEngine.cpp index e1b4d7dccd..1520916d43 100644 --- a/source/main/scripting/ScriptEngine.cpp +++ b/source/main/scripting/ScriptEngine.cpp @@ -502,7 +502,7 @@ int ScriptEngine::deleteVariable(const String &arg) void ScriptEngine::triggerEvent(int eventnum, int value) { - if (!engine || !context) return; + if (!engine || !context || !m_events_enabled) return; for (auto& pair: m_script_units) { diff --git a/source/main/scripting/ScriptEngine.h b/source/main/scripting/ScriptEngine.h index cc97a94167..77132aafce 100644 --- a/source/main/scripting/ScriptEngine.h +++ b/source/main/scripting/ScriptEngine.h @@ -117,6 +117,8 @@ class ScriptEngine : public Ogre::LogListener, public ZeroedMemoryAllocator */ void triggerEvent(int scriptEvents, int value = 0); + void setEventsEnabled(bool val) { m_events_enabled = val; } + /** * executes a string (useful for the console) * @param command string to execute @@ -207,6 +209,7 @@ class ScriptEngine : public Ogre::LogListener, public ZeroedMemoryAllocator ScriptUnitMap m_script_units; ScriptUnitId_t m_terrain_script_unit = SCRIPTUNITID_INVALID; ScriptUnitId_t m_currently_executing_script_unit = SCRIPTUNITID_INVALID; + bool m_events_enabled = true; //!< Hack to enable fast shutdown without cleanup InterThreadStoreVector stringExecutionQueue; //!< The string execution queue \see queueStringForExecution }; diff --git a/source/main/scripting/bindings/ActorAngelscript.cpp b/source/main/scripting/bindings/ActorAngelscript.cpp index 71eb71586e..8e989310b8 100644 --- a/source/main/scripting/bindings/ActorAngelscript.cpp +++ b/source/main/scripting/bindings/ActorAngelscript.cpp @@ -48,6 +48,7 @@ void RoR::RegisterActor(asIScriptEngine *engine) // class Actor (historically Beam) result = engine->RegisterObjectType("BeamClass", sizeof(Actor), asOBJ_REF); ROR_ASSERT(result>=0); + ActorPtr::RegisterRefCountingObjectPtr("BeamClassPtr", "BeamClass", engine); result = engine->RegisterObjectMethod("BeamClass", "void scaleTruck(float)", asMETHOD(Actor,scaleTruck), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "string getTruckName()", asMETHOD(Actor,getTruckName), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "string getTruckFileName()", asMETHOD(Actor,getTruckFileName), asCALL_THISCALL); ROR_ASSERT(result>=0); @@ -76,14 +77,8 @@ void RoR::RegisterActor(asIScriptEngine *engine) result = engine->RegisterObjectMethod("BeamClass", "float getWheelSpeed()", asMETHOD(Actor,getWheelSpeed), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "float getSpeed()", asMETHOD(Actor,getSpeed), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "vector3 getGForces()", asMETHOD(Actor,getGForces), asCALL_THISCALL); ROR_ASSERT(result>=0); - result = engine->RegisterObjectMethod("BeamClass", "float getRotation()", asMETHOD(Actor,getRotation), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "vector3 getVehiclePosition()", asMETHOD(Actor,getPosition), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "vector3 getNodePosition(int)", asMETHOD(Actor,getNodePosition), asCALL_THISCALL); ROR_ASSERT(result>=0); - result = engine->RegisterObjectMethod("BeamClass", "VehicleAIClass @getVehicleAI()", asMETHOD(Actor,getVehicleAI), asCALL_THISCALL); ROR_ASSERT(result>=0); - - result = engine->RegisterObjectBehaviour("BeamClass", asBEHAVE_ADDREF, "void f()", asMETHOD(Actor,addRef), asCALL_THISCALL); ROR_ASSERT(result>=0); - result = engine->RegisterObjectBehaviour("BeamClass", asBEHAVE_RELEASE, "void f()", asMETHOD(Actor,release), asCALL_THISCALL); ROR_ASSERT(result>=0); - } diff --git a/source/main/system/AppConfig.cpp b/source/main/system/AppConfig.cpp index 0f5386175a..beee77a5ef 100644 --- a/source/main/system/AppConfig.cpp +++ b/source/main/system/AppConfig.cpp @@ -19,6 +19,7 @@ along with Rigs of Rods. If not, see . */ +#include "Actor.h" #include "Application.h" #include "Console.h" #include "ContentManager.h" // RGN_CONFIG diff --git a/source/main/system/ConsoleCmd.cpp b/source/main/system/ConsoleCmd.cpp index b28dfd7397..337d1b57f9 100644 --- a/source/main/system/ConsoleCmd.cpp +++ b/source/main/system/ConsoleCmd.cpp @@ -136,7 +136,7 @@ class TerrainheightCmd: public ConsoleCmd reply << m_name << ": "; Console::MessageType reply_type = Console::CONSOLE_SYSTEM_REPLY; Ogre::Vector3 pos; - Actor* const actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr const actor = App::GetGameContext()->GetPlayerActor(); if (actor) { pos = actor->getPosition(); @@ -251,7 +251,7 @@ class PosCmd: public ConsoleCmd reply << m_name << ": "; Console::MessageType reply_type = Console::CONSOLE_SYSTEM_REPLY; - Actor* b = App::GetGameContext()->GetPlayerActor(); + ActorPtr b = App::GetGameContext()->GetPlayerActor(); if (!b && App::GetGameContext()->GetPlayerCharacter()) { Ogre::Vector3 pos = App::GetGameContext()->GetPlayerCharacter()->getPosition(); @@ -291,7 +291,7 @@ class GotoCmd: public ConsoleCmd reply_type = Console::CONSOLE_SYSTEM_REPLY; Ogre::Vector3 pos(PARSEREAL(args[1]), PARSEREAL(args[2]), PARSEREAL(args[3])); - Actor* b = App::GetGameContext()->GetPlayerActor(); + ActorPtr b = App::GetGameContext()->GetPlayerActor(); if (!b && App::GetGameContext()->GetPlayerCharacter()) { App::GetGameContext()->GetPlayerCharacter()->setPosition(pos); diff --git a/source/main/terrain/ProceduralRoad.cpp b/source/main/terrain/ProceduralRoad.cpp index f307d25a64..bd8444401b 100644 --- a/source/main/terrain/ProceduralRoad.cpp +++ b/source/main/terrain/ProceduralRoad.cpp @@ -20,6 +20,7 @@ #include "ProceduralRoad.h" +#include "Actor.h" #include "Application.h" #include "Collisions.h" #include "GfxScene.h" diff --git a/source/main/terrain/TerrainGeometryManager.cpp b/source/main/terrain/TerrainGeometryManager.cpp index be68bb713a..e1007e1017 100644 --- a/source/main/terrain/TerrainGeometryManager.cpp +++ b/source/main/terrain/TerrainGeometryManager.cpp @@ -21,6 +21,7 @@ #include "TerrainGeometryManager.h" +#include "Actor.h" #include "Application.h" #include "ContentManager.h" #include "Language.h" diff --git a/source/main/utils/ForceFeedback.cpp b/source/main/utils/ForceFeedback.cpp index 6e4e0e22ab..8307c50c46 100644 --- a/source/main/utils/ForceFeedback.cpp +++ b/source/main/utils/ForceFeedback.cpp @@ -112,7 +112,7 @@ void ForceFeedback::Update() return; } - Actor* player_actor = App::GetGameContext()->GetPlayerActor(); + ActorPtr player_actor = App::GetGameContext()->GetPlayerActor(); if (player_actor && player_actor->ar_driveable == TRUCK) { Ogre::Vector3 ff_vehicle = player_actor->GetFFbBodyForces(); diff --git a/source/main/utils/InputEngine.cpp b/source/main/utils/InputEngine.cpp index 27d29a7e0d..2fec4264a7 100644 --- a/source/main/utils/InputEngine.cpp +++ b/source/main/utils/InputEngine.cpp @@ -21,6 +21,7 @@ #include "InputEngine.h" +#include "Actor.h" #include "AppContext.h" #include "Console.h" #include "ContentManager.h" diff --git a/source/main/utils/MeshObject.cpp b/source/main/utils/MeshObject.cpp index 4fa1e6871a..64ca3f18db 100644 --- a/source/main/utils/MeshObject.cpp +++ b/source/main/utils/MeshObject.cpp @@ -24,6 +24,7 @@ #include "MeshObject.h" +#include "Actor.h" #include "Application.h" #include "GfxScene.h" #include "MeshLodGenerator/OgreMeshLodGenerator.h" diff --git a/source/main/utils/memory/RefCountingObject.h b/source/main/utils/memory/RefCountingObject.h new file mode 100644 index 0000000000..89e42fee0f --- /dev/null +++ b/source/main/utils/memory/RefCountingObject.h @@ -0,0 +1,75 @@ + +// RefCountingObject system for AngelScript +// Copyright (c) 2022 Petr Ohlidal +// https://github.com/only-a-ptr/RefCountingObject-AngelScript + +#pragma once + +#include "Application.h" +#include + +/// Self reference-counting objects, as requred by AngelScript garbage collector. +template class RefCountingObject +{ +public: + RefCountingObject() + { + } + + virtual ~RefCountingObject() + { + } + + void AddRef() + { + m_refcount++; + } + + void Release() + { + m_refcount--; + if (m_refcount == 0) + { + delete this; // commit suicide! This is legit in C++ + } + } + + static void RegisterRefCountingObject(const char* name, AngelScript::asIScriptEngine *engine) + { + using namespace AngelScript; + + int r; + // Registering the reference type + r = engine->RegisterObjectType(name, 0, asOBJ_REF); ROR_ASSERT( r >= 0 ); + + // Registering the addref/release behaviours + r = engine->RegisterObjectBehaviour(name, asBEHAVE_ADDREF, "void f()", asMETHOD(T,AddRef), asCALL_THISCALL); ROR_ASSERT( r >= 0 ); + r = engine->RegisterObjectBehaviour(name, asBEHAVE_RELEASE, "void f()", asMETHOD(T,Release), asCALL_THISCALL); ROR_ASSERT( r >= 0 ); + } + + int m_refcount = 1; // Initial refcount for any angelscript object. +}; + +/* +MIT License + +Copyright (c) 2022 Petr Ohlídal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ diff --git a/source/main/utils/memory/RefCountingObjectPtr.h b/source/main/utils/memory/RefCountingObjectPtr.h new file mode 100644 index 0000000000..e77745b3de --- /dev/null +++ b/source/main/utils/memory/RefCountingObjectPtr.h @@ -0,0 +1,254 @@ + +// RefCountingObject system for AngelScript +// Copyright (c) 2022 Petr Ohlidal +// https://github.com/only-a-ptr/RefCountingObject-AngelScript + +// Adopted from "scripthandle" AngelScript addon, distributed with AngelScript SDK. + +#pragma once + +#include + +#ifndef ROR_ASSERT +# define ROR_ASSERT(_EXPR) assert(_EXPR) +#endif + +template +class RefCountingObjectPtr +{ +public: + // Constructors + RefCountingObjectPtr(); + RefCountingObjectPtr(const RefCountingObjectPtr &other); + RefCountingObjectPtr(T *ref); // Only invoke directly using C++! AngelScript must use a wrapper. + ~RefCountingObjectPtr(); + + // Assignments + RefCountingObjectPtr &operator=(const RefCountingObjectPtr &other); + // Intentionally omitting raw-pointer assignment, for simplicity - see raw pointer constructor. + + // Compare equalness + bool operator==(const RefCountingObjectPtr &o) const { return m_ref == o.m_ref; } + bool operator!=(const RefCountingObjectPtr &o) const { return m_ref != o.m_ref; } + + // Get the reference + T *GetRef() { return m_ref; } + T* operator->() { return m_ref; } + T* operator->() const { return m_ref; } + + // Boolean conversion (classic pointer check) + operator bool() const { return (bool)m_ref; } + + // GC callback + void EnumReferences(AngelScript::asIScriptEngine *engine); + void ReleaseReferences(AngelScript::asIScriptEngine *engine); + + static void RegisterRefCountingObjectPtr(const char* handle_name, const char* obj_name, AngelScript::asIScriptEngine *engine); + +protected: + + void Set(T* ref); + void ReleaseHandle(); + void AddRefHandle(); + + // Wrapper functions, to be invoked by AngelScript only! + static void ConstructDefault(RefCountingObjectPtr *self) { new(self) RefCountingObjectPtr(); } + static void ConstructCopy(RefCountingObjectPtr *self, const RefCountingObjectPtr &o) { new(self) RefCountingObjectPtr(o); } + static void ConstructRef(RefCountingObjectPtr* self, void** objhandle); + static void Destruct(RefCountingObjectPtr *self) { self->~RefCountingObjectPtr(); } + static T* OpImplCast(RefCountingObjectPtr* self); + static RefCountingObjectPtr & OpAssign(RefCountingObjectPtr* self, void** objhandle); + static bool OpEquals(RefCountingObjectPtr* self, void** objhandle); + static T* DereferenceHandle(void** objhandle); + + T *m_ref; +}; + +template +void RefCountingObjectPtr::RegisterRefCountingObjectPtr(const char* handle_name, const char* obj_name, AngelScript::asIScriptEngine *engine) +{ + using namespace AngelScript; + + int r; + const size_t DECLBUF_MAX = 300; + char decl_buf[DECLBUF_MAX]; + + // With C++11 it is possible to use asGetTypeTraits to automatically determine the flags that represent the C++ class + r = engine->RegisterObjectType(handle_name, sizeof(RefCountingObjectPtr), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asGetTypeTraits()); ROR_ASSERT( r >= 0 ); + + // construct/destruct + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(RefCountingObjectPtr::ConstructDefault), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + snprintf(decl_buf, DECLBUF_MAX, "void f(%s @&in)", obj_name); + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_CONSTRUCT, decl_buf, asFUNCTION(RefCountingObjectPtr::ConstructRef), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + snprintf(decl_buf, DECLBUF_MAX, "void f(const %s &in)", handle_name); + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_CONSTRUCT, decl_buf, asFUNCTION(RefCountingObjectPtr::ConstructCopy), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_DESTRUCT, "void f()", asFUNCTION(RefCountingObjectPtr::Destruct), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + + // GC + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(RefCountingObjectPtr,EnumReferences), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectBehaviour(handle_name, asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(RefCountingObjectPtr, ReleaseReferences), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // Cast + snprintf(decl_buf, DECLBUF_MAX, "%s @ opImplCast()", obj_name); + r = engine->RegisterObjectMethod(handle_name, decl_buf, asFUNCTION(RefCountingObjectPtr::OpImplCast), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + + // Assign + snprintf(decl_buf, DECLBUF_MAX, "%s &opHndlAssign(const %s &in)", handle_name, handle_name); + r = engine->RegisterObjectMethod(handle_name, decl_buf, asMETHOD(RefCountingObjectPtr, operator=), asCALL_THISCALL); ROR_ASSERT( r >= 0 ); + snprintf(decl_buf, DECLBUF_MAX, "%s &opHndlAssign(const %s @&in)", handle_name, obj_name); + r = engine->RegisterObjectMethod(handle_name, decl_buf, asFUNCTION(RefCountingObjectPtr::OpAssign), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); + + // Equals + snprintf(decl_buf, DECLBUF_MAX, "bool opEquals(const %s &in) const", handle_name); + r = engine->RegisterObjectMethod(handle_name, decl_buf, asMETHODPR(RefCountingObjectPtr, operator==, (const RefCountingObjectPtr &) const, bool), asCALL_THISCALL); ROR_ASSERT( r >= 0 ); + snprintf(decl_buf, DECLBUF_MAX, "bool opEquals(const %s @&in) const", obj_name); + r = engine->RegisterObjectMethod(handle_name, decl_buf, asFUNCTION(RefCountingObjectPtr::OpEquals), asCALL_CDECL_OBJFIRST); ROR_ASSERT( r >= 0 ); +} + + +// ---------------------------- Internals ------------------------------ + +template +T* RefCountingObjectPtr::DereferenceHandle(void** objhandle) +{ + // Dereference the handle to get the object itself (see AngelScript SDK, addon 'generic handle', function `Assign()` or `Equals()`). + return static_cast(*objhandle); +} + +template +inline void RefCountingObjectPtr::ConstructRef(RefCountingObjectPtr* self, void** objhandle) +{ + T* ref = DereferenceHandle(objhandle); + new(self)RefCountingObjectPtr(ref); + + // Increase refcount manually because constructor is designed for C++ use only. + if (ref) + ref->AddRef(); +} + +template +inline T* RefCountingObjectPtr::OpImplCast(RefCountingObjectPtr* self) +{ + T* ref = self->GetRef(); + ref->AddRef(); + return ref; +} + +template +inline RefCountingObjectPtr & RefCountingObjectPtr::OpAssign(RefCountingObjectPtr* self, void** objhandle) +{ + T* ref = DereferenceHandle(objhandle); + self->Set(ref); + return *self; +} + +template +inline bool RefCountingObjectPtr::OpEquals(RefCountingObjectPtr* self, void** objhandle) +{ + T* ref = DereferenceHandle(objhandle); + return self->GetRef() == ref; +} + +template +inline RefCountingObjectPtr::RefCountingObjectPtr() + : m_ref(nullptr) +{ +} + +template +inline RefCountingObjectPtr::RefCountingObjectPtr(const RefCountingObjectPtr &other) +{ + m_ref = other.m_ref; + AddRefHandle(); +} + +template +inline RefCountingObjectPtr::RefCountingObjectPtr(T *ref) +{ + // Used directly from C++, DO NOT increase refcount! + // It's already been done by constructor/factory/AngelScript (if retrieved from script context). + // ------------------------------------------ + m_ref = ref; +} + +template +inline RefCountingObjectPtr::~RefCountingObjectPtr() +{ + ReleaseHandle(); +} + +template +inline void RefCountingObjectPtr::ReleaseHandle() +{ + if( m_ref ) + { + m_ref->Release(); + m_ref = nullptr; + } +} + +template +inline void RefCountingObjectPtr::AddRefHandle() +{ + if( m_ref ) + { + m_ref->AddRef(); + } +} + +template +inline RefCountingObjectPtr &RefCountingObjectPtr::operator =(const RefCountingObjectPtr &other) +{ + Set(other.m_ref); + return *this; +} + +template +inline void RefCountingObjectPtr::Set(T* ref) +{ + if( m_ref == ref ) + return; + + ReleaseHandle(); + m_ref = ref; + AddRefHandle(); +} + +template +inline void RefCountingObjectPtr::EnumReferences(AngelScript::asIScriptEngine *inEngine) +{ + // If we're holding a reference, we'll notify the garbage collector of it + if (m_ref) + inEngine->GCEnumCallback(m_ref); +} + +template +inline void RefCountingObjectPtr::ReleaseReferences(AngelScript::asIScriptEngine * /*inEngine*/) +{ + // Simply clear the content to release the references + Set(nullptr); +} + +/* +MIT License + +Copyright (c) 2022 Petr Ohlídal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ diff --git a/source/main/utils/memory/RefCountingObject_README.md b/source/main/utils/memory/RefCountingObject_README.md new file mode 100644 index 0000000000..575affba45 --- /dev/null +++ b/source/main/utils/memory/RefCountingObject_README.md @@ -0,0 +1,123 @@ + +# RefCountingObject system for AngelScript + +_Created 2022 by Petr Ohlídal_ + +_https://github.com/only-a-ptr/RefCountingObject-AngelScript_ + +This mini-framework lets you use a single reference counting mechanism for both +AngelScript's built-in garbage collection and C++ smart pointers. This allows you to fluently +pass objects between C++ and script context(s) without caring who created the object and where may +references be held. + +## Motivation + +I maintain [a game project](https://github.com/RigsOfRods/rigs-of-rods) +where AngelScript is an optional dependency +but at the same time plays an important gameplay role. +I wanted to expand the scripting interface by exposing +the internal objects and functions as directly as possible, but I didn't want to do +AngelScript refcounting manually on the C++ side. +I wanted a classic C++ smart pointer (like `std::shared_ptr<>`) that would do it for me, +and which would remain fully functional for C++ even if built without AngelScript. + +## How to use + +The project was developed against AngelScript 2.35.1; but any reasonably recent version should do. + +To install, just copy the 'RefCountingObject\*' files to your project. + +Define your C++ classes by implementing `RefCountingObject` +and calling `RegisterRefCountingObject()` for each type. + +``` +class Foo: RefCountingObject{} +Foo::RegisterRefCountingObject("Foo", engine); +``` + +Define your C++ smart pointers by qualifying `RefCountingObjectPtr<>` +and use them in your interfaces. +These will become usable interchangeably from both C++ and script. + +``` +typedef RefCountingObjectPtr FooPtr; +// demo API: +static FooPtr gf; +static void SetFoo(FooPtr f) { gf = f; } +static FooPtr GetFoo() { return gf; } +``` + +Register the smart pointers with `RegisterRefCountingObjectPtr()` +and use them in your application interface. + +``` +FooPtr::RegisterRefCountingObjectPtr("FooPtr", "Foo", engine); +// ... +engine->RegisterGlobalFunction("void SetFoo(FooPtr@)", asFUNCTION(SetFoo), asCALL_CDECL); +engine->RegisterGlobalFunction("FooPtr@ GetFoo()", asFUNCTION(GetFoo), asCALL_CDECL); +``` + +In C++, use just the smart pointers and you'll be safe. + +``` +FooPtr f1 = new Foo(); // refcount 1 +SetFoo(f1); // refcount 2 +FooPtr f2 = GetFoo(); // refcount 3 +f2 = nullptr; // refcount 2 +f1 = nullptr; // refcount 1 +SetFoo(nullptr); // refcount 0 -> deleted. +``` + +In AngelScript, use the native handles. + +``` +Foo@ f1 = new Foo(); // refcount 1 +SetFoo(f1); // refcount 2 +Foo@ f2 = GetFoo(); // refcount 3 +@f2 = null; // refcount 2 +@f1 = null; // refcount 1 +SetFoo(null); // refcount 0 -> deleted. +``` + +## How it works + +This part explains the less obvious bits of AngelScript mechanics. + +### How the AngelScript refcounting works + + Intuitively, you would call AddRef() every time you obtain a raw pointer to the object, + i.e. when creating a new object or retrieving one from script engine. Well, don't. + + * New objects have refcount initialized to 1. + You must call Release() to dispose of it, but don't call AddRef() unless you're creating additional pointers. + * When passing the object as parameter from script to C++ function, the refcount is already incremented by the script engine. + If you don't store the pointer, you must call Release() before the function returns. + * When passing the object from C++ to script, you must increase the refcount yourself. + +Documentation: + https://www.angelcode.com/angelscript/sdk/docs/manual/doc_as_vs_cpp_types.html#doc_as_vs_cpp_types_3 + https://www.angelcode.com/angelscript/sdk/docs/manual/doc_obj_handle.html#doc_obj_handle_3 + +### How RefCountingObject fits into it + +RefCountingObject just implements the essential `AddRef()` and `Release()` functions needed by reference types: +https://www.angelcode.com/angelscript/sdk/docs/manual/doc_reg_basicref.html + +RefCountingObjectPtr, for the most part, does the typical smart pointer scheme: +when created, add ref; when deleted, remove ref. + +However, there is one major catch: constructing new objects. Since RefCountingObjectPtr must +be intuitive in C++, the only acceptable form of creating objects is this: +``` +FooPtr foo_ptr = new Foo(); // C++ programmer reads "Pointer is taken care of". +``` +With AngelScript, though, this means a memory leak because the smart pointer added a reference +while one already existed (the temporary one). The treatment expected by AngelScript is: +``` +FooPtr foo_ptr = new Foo(); +foo_ptr->Release(); // C++ programmer goes "WTF ?!?" +``` +**The closure:** RefCountingObjectPtr never increases refcount when assigned a raw pointer (in C++). +Assignment within AngelScript engine is handled by wrapper interface, not available from C++. + +