mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-07 12:13:17 +01:00
fix(sonar): addressing reliability/security issues
This commit is contained in:
@@ -2408,16 +2408,14 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
|
|||||||
if (CtrlSpeed > 1)
|
if (CtrlSpeed > 1)
|
||||||
{
|
{
|
||||||
OK = IncMainCtrl(1) && IncMainCtrl(CtrlSpeed - 1); // a fail will propagate up the recursion chain. should this be || instead?
|
OK = IncMainCtrl(1) && IncMainCtrl(CtrlSpeed - 1); // a fail will propagate up the recursion chain. should this be || instead?
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
++MainCtrlPos;
|
||||||
|
OK = true;
|
||||||
|
if (EIMCtrlType == 0 && ( SpeedCtrlAutoTurnOffFlag & 1 ) == 1 && MainCtrlActualPos != MainCtrlPos)
|
||||||
{
|
{
|
||||||
++MainCtrlPos;
|
DecScndCtrl(2);
|
||||||
OK = true;
|
SpeedCtrlUnit.IsActive = false;
|
||||||
if (EIMCtrlType == 0 && ( SpeedCtrlAutoTurnOffFlag & 1 ) == 1 && MainCtrlActualPos != MainCtrlPos)
|
|
||||||
{
|
|
||||||
DecScndCtrl(2);
|
|
||||||
SpeedCtrlUnit.IsActive = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ void scenarioloader_ui::render_()
|
|||||||
const float spacing = 10.0f * scale; // odstęp między ikoną a tekstem
|
const float spacing = 10.0f * scale; // odstęp między ikoną a tekstem
|
||||||
|
|
||||||
// Loading icon
|
// Loading icon
|
||||||
const deferred_image *img = &m_loading_wheel_frames[38];
|
deferred_image *img = &m_loading_wheel_frames[38];
|
||||||
const auto loading_tex = img->get();
|
const auto loading_tex = img->get();
|
||||||
const auto loading_size = glm::vec2(img->size()) * glm::vec2(scale);
|
const auto loading_size = glm::vec2(img->size()) * glm::vec2(scale);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include "model/Texture.h"
|
#include "model/Texture.h"
|
||||||
#include "rendering/renderer.h"
|
#include "rendering/renderer.h"
|
||||||
@@ -14,26 +13,16 @@ public:
|
|||||||
deferred_image() = default;
|
deferred_image() = default;
|
||||||
deferred_image(const std::string &p) : path(p) { }
|
deferred_image(const std::string &p) : path(p) { }
|
||||||
deferred_image(const deferred_image&) = delete;
|
deferred_image(const deferred_image&) = delete;
|
||||||
deferred_image(deferred_image &&other) noexcept : deferred_image(std::move(other), std::scoped_lock(other.mutex)) { }
|
deferred_image(deferred_image&&) = default;
|
||||||
~deferred_image() = default;
|
deferred_image &operator=(deferred_image&&) = default;
|
||||||
deferred_image &operator=(deferred_image &&other) noexcept
|
|
||||||
{
|
|
||||||
if (this != &other) {
|
|
||||||
std::scoped_lock lock(mutex, other.mutex);
|
|
||||||
path = std::move(other.path);
|
|
||||||
image = other.image;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(mutex);
|
|
||||||
return image != null_handle || !path.empty();
|
return image != null_handle || !path.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint get() const
|
// loads the texture on first use
|
||||||
|
GLuint get()
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(mutex);
|
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
image = GfxRenderer->Fetch_Texture(path, true);
|
image = GfxRenderer->Fetch_Texture(path, true);
|
||||||
path.clear();
|
path.clear();
|
||||||
@@ -52,7 +41,6 @@ public:
|
|||||||
|
|
||||||
glm::ivec2 size() const
|
glm::ivec2 size() const
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(mutex);
|
|
||||||
if (image != null_handle) {
|
if (image != null_handle) {
|
||||||
auto &tex = GfxRenderer->Texture(image);
|
auto &tex = GfxRenderer->Texture(image);
|
||||||
return glm::ivec2(tex.get_width(), tex.get_height());
|
return glm::ivec2(tex.get_width(), tex.get_height());
|
||||||
@@ -61,11 +49,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// moves content of the other image, while the caller holds its lock
|
std::string path;
|
||||||
deferred_image(deferred_image &&other, std::scoped_lock<std::mutex> const &) noexcept : path(std::move(other.path)), image(other.image) { }
|
texture_handle image = 0;
|
||||||
|
|
||||||
// guards lazy loading performed by the const accessors
|
|
||||||
mutable std::mutex mutex;
|
|
||||||
mutable std::string path;
|
|
||||||
mutable texture_handle image = 0;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void ui::vehiclepicker_panel::render_contents()
|
|||||||
if (ImGui::RadioButton(STR_C("texture group"), display_by_groups))
|
if (ImGui::RadioButton(STR_C("texture group"), display_by_groups))
|
||||||
display_by_groups = true;
|
display_by_groups = true;
|
||||||
|
|
||||||
std::vector<const skin_set*> skinset_list;
|
std::vector<skin_set*> skinset_list;
|
||||||
|
|
||||||
if (display_by_groups) {
|
if (display_by_groups) {
|
||||||
std::vector<const std::string*> model_list;
|
std::vector<const std::string*> model_list;
|
||||||
@@ -114,7 +114,7 @@ void ui::vehiclepicker_panel::render_contents()
|
|||||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||||
auto &desc = model_list[i];
|
auto &desc = model_list[i];
|
||||||
|
|
||||||
const deferred_image *image = nullptr;
|
deferred_image *image = nullptr;
|
||||||
for (auto const &skinset : desc->matching_skinsets) {
|
for (auto const &skinset : desc->matching_skinsets) {
|
||||||
if (skinset->mini) {
|
if (skinset->mini) {
|
||||||
image = &skinset->mini;
|
image = &skinset->mini;
|
||||||
@@ -256,7 +256,7 @@ bool ui::vehiclepicker_panel::skin_filter(const skin_set *skin, std::vector<sear
|
|||||||
return alternative_present ? !any : false;
|
return alternative_present ? !any : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, const deferred_image* image, const skin_set *pickable)
|
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, deferred_image *image, const skin_set *pickable)
|
||||||
{
|
{
|
||||||
ImGui::PushID(pickable);
|
ImGui::PushID(pickable);
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class vehiclepicker_panel : public ui_panel
|
|||||||
void render_contents() override;
|
void render_contents() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool selectable_image(const char *desc, bool selected, const deferred_image *image, const skin_set *pickable = nullptr);
|
bool selectable_image(const char *desc, bool selected, deferred_image *image, const skin_set *pickable = nullptr);
|
||||||
|
|
||||||
vehicle_type selected_type = vehicle_type::none;
|
vehicle_type selected_type = vehicle_type::none;
|
||||||
std::shared_ptr<const vehicle_desc> selected_vehicle;
|
std::shared_ptr<const vehicle_desc> selected_vehicle;
|
||||||
|
|||||||
@@ -4987,8 +4987,7 @@ TController::PrepareDirection() {
|
|||||||
|
|
||||||
void TController::JumpToNextOrder( bool const Ignoremergedchangedirection )
|
void TController::JumpToNextOrder( bool const Ignoremergedchangedirection )
|
||||||
{ // wykonanie kolejnej komendy z tablicy rozkazów
|
{ // wykonanie kolejnej komendy z tablicy rozkazów
|
||||||
auto const currentorder { OrderCurrentGet() };
|
if (auto const currentorder { OrderCurrentGet() }; currentorder != Wait_for_orders)
|
||||||
if (currentorder != Wait_for_orders)
|
|
||||||
{
|
{
|
||||||
if( (currentorder & Change_direction) != 0 // jeśli zmiana kierunku
|
if( (currentorder & Change_direction) != 0 // jeśli zmiana kierunku
|
||||||
&& currentorder != Change_direction && false == Ignoremergedchangedirection ) { // ale nałożona na coś
|
&& currentorder != Change_direction && false == Ignoremergedchangedirection ) { // ale nałożona na coś
|
||||||
@@ -5056,16 +5055,21 @@ void TController::OrderNext(TOrders NewOrder)
|
|||||||
OrderTop = OrderPos; // ale może jest czymś zajęty na razie
|
OrderTop = OrderPos; // ale może jest czymś zajęty na razie
|
||||||
if (NewOrder >= Shunt) // jeśli ma jechać
|
if (NewOrder >= Shunt) // jeśli ma jechać
|
||||||
{ // ale może być zajęty chwilowymi operacjami
|
{ // ale może być zajęty chwilowymi operacjami
|
||||||
while (OrderList[OrderTop] != Wait_for_orders && OrderList[OrderTop] < Shunt) // jeśli coś robi
|
while (OrderTop >= 0 && OrderTop < maxorders - 1
|
||||||
|
&& OrderList[OrderTop] != Wait_for_orders && OrderList[OrderTop] < Shunt) // jeśli coś robi
|
||||||
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // jeśli ma ustawioną jazdę, to wyłączamy na rzecz operacji
|
{ // jeśli ma ustawioną jazdę, to wyłączamy na rzecz operacji
|
||||||
while (OrderList[OrderTop] ?
|
while (OrderTop >= 0 && OrderTop < maxorders - 1
|
||||||
OrderList[OrderTop] < Shunt && OrderList[OrderTop] != NewOrder :
|
&& OrderList[OrderTop] != Wait_for_orders && OrderList[OrderTop] < Shunt && OrderList[OrderTop] != NewOrder) // jeśli coś robi
|
||||||
false) // jeśli coś robi
|
|
||||||
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
||||||
}
|
}
|
||||||
|
if (OrderTop < 0 || OrderTop >= maxorders)
|
||||||
|
{
|
||||||
|
ErrorLog("Commands overflow: order \"" + Order2Str(NewOrder) + "\" dropped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu jako następnego
|
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu jako następnego
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
OrdersDump( "OrderNext" ); // normalnie nie ma po co tego wypisywać
|
OrdersDump( "OrderNext" ); // normalnie nie ma po co tego wypisywać
|
||||||
@@ -5078,11 +5082,13 @@ void TController::OrderPush(TOrders NewOrder)
|
|||||||
// ale nie jedzie
|
// ale nie jedzie
|
||||||
++OrderTop;
|
++OrderTop;
|
||||||
// niektóre operacje muszą zostać najpierw dokończone => zapis na kolejnej
|
// niektóre operacje muszą zostać najpierw dokończone => zapis na kolejnej
|
||||||
|
if (OrderTop < 0 || OrderTop >= maxorders)
|
||||||
|
{
|
||||||
|
ErrorLog("Commands overflow: order \"" + Order2Str(NewOrder) + "\" dropped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (OrderList[OrderTop] != NewOrder) // jeśli jest to samo, to nie dodajemy
|
if (OrderList[OrderTop] != NewOrder) // jeśli jest to samo, to nie dodajemy
|
||||||
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu na stos
|
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu na stos
|
||||||
// if (OrderTop<OrderPos) OrderTop=OrderPos;
|
|
||||||
if (OrderTop >= maxorders)
|
|
||||||
ErrorLog("Commands overflow: The program will now crash");
|
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
OrdersDump( "OrderPush: [" + Order2Str( NewOrder ) + "]" ); // normalnie nie ma po co tego wypisywać
|
OrdersDump( "OrderPush: [" + Order2Str( NewOrder ) + "]" ); // normalnie nie ma po co tego wypisywać
|
||||||
#endif
|
#endif
|
||||||
@@ -5398,8 +5404,7 @@ TCommandType TController::BackwardScan( double const Range )
|
|||||||
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany
|
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany
|
||||||
auto const sl{e->input_location()}; // położenie komórki pamięci
|
auto const sl{e->input_location()}; // położenie komórki pamięci
|
||||||
auto const pos{pVehicles[end::rear]->RearPosition()}; // pozycja tyłu
|
auto const pos{pVehicles[end::rear]->RearPosition()}; // pozycja tyłu
|
||||||
auto const sem{sl - pos}; // wektor do komórki pamięci od końca składu
|
if (auto const sem{sl - pos}; dir.x * sem.x + dir.z * sem.z < 0) // wektor do komórki pamięci od końca składu
|
||||||
if (dir.x * sem.x + dir.z * sem.z < 0)
|
|
||||||
{
|
{
|
||||||
// jeśli został minięty
|
// jeśli został minięty
|
||||||
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
||||||
@@ -5411,7 +5416,7 @@ TCommandType TController::BackwardScan( double const Range )
|
|||||||
scanvel = e->input_value(1); // prędkość przy tym semaforze
|
scanvel = e->input_value(1); // prędkość przy tym semaforze
|
||||||
#if LOGBACKSCAN
|
#if LOGBACKSCAN
|
||||||
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
|
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
|
||||||
scandist = std::max(glm::length(sem) - 2.0, 0.0); // 2m luzu przy manewrach wystarczy, ujemnych nie ma po co wysyłać
|
scandist = std::max(glm::length(sl - pos) - 2.0, 0.0); // 2m luzu przy manewrach wystarczy, ujemnych nie ma po co wysyłać
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "application/application.h"
|
#include "application/application.h"
|
||||||
#include "rendering/renderer.h"
|
#include "rendering/renderer.h"
|
||||||
#include <exception>
|
#include <future>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -647,9 +647,8 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DynamicSet(NewDynamicObject);
|
DynamicSet(NewDynamicObject);
|
||||||
if (!e3d)
|
if (!e3d && DynamicObject->Mechanik == nullptr)
|
||||||
if (DynamicObject->Mechanik == nullptr)
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
DynamicObject->MechInside = true;
|
DynamicObject->MechInside = true;
|
||||||
|
|
||||||
@@ -12401,20 +12400,13 @@ uint16_t TTrain::id()
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// updates trains in range [Start, End); an exception is stored for the calling thread to rethrow
|
// updates trains in range [Start, End)
|
||||||
void update_trains(std::deque<TTrain *> const &Trains, std::size_t const Start, std::size_t const End, double const Dt, std::exception_ptr &Error)
|
void update_trains(std::deque<TTrain *> const &Trains, std::size_t const Start, std::size_t const End, double const Dt)
|
||||||
{
|
{
|
||||||
try
|
for (std::size_t j = Start; j < End; ++j)
|
||||||
{
|
{
|
||||||
for (std::size_t j = Start; j < End; ++j)
|
if (Trains[j])
|
||||||
{
|
Trains[j]->Update(Dt);
|
||||||
if (Trains[j])
|
|
||||||
Trains[j]->Update(Dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception const &)
|
|
||||||
{
|
|
||||||
Error = std::current_exception();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -12426,8 +12418,9 @@ void train_table::updateAsync(double dt)
|
|||||||
const size_t chunkSize = (total + threads - 1) / threads;
|
const size_t chunkSize = (total + threads - 1) / threads;
|
||||||
|
|
||||||
std::vector<std::jthread> workers;
|
std::vector<std::jthread> workers;
|
||||||
std::vector<std::exception_ptr> errors(threads);
|
std::vector<std::future<void>> results; // przekazują wyjątki z wątków do głównego wątku
|
||||||
workers.reserve(threads);
|
workers.reserve(threads);
|
||||||
|
results.reserve(threads);
|
||||||
|
|
||||||
for (int i = 0; i < threads; ++i)
|
for (int i = 0; i < threads; ++i)
|
||||||
{
|
{
|
||||||
@@ -12437,19 +12430,17 @@ void train_table::updateAsync(double dt)
|
|||||||
if (start >= end)
|
if (start >= end)
|
||||||
break; // brak więcej danych
|
break; // brak więcej danych
|
||||||
|
|
||||||
// wyjątek przekazywany jest do głównego wątku
|
std::packaged_task<void()> task([this, start, end, dt]() { update_trains(m_items, start, end, dt); });
|
||||||
workers.emplace_back(update_trains, std::cref(m_items), start, end, dt, std::ref(errors[i]));
|
results.emplace_back(task.get_future());
|
||||||
|
workers.emplace_back(std::move(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poczekaj aż wszystkie wątki skończą
|
// Poczekaj aż wszystkie wątki skończą
|
||||||
for (auto &worker : workers)
|
for (auto &worker : workers)
|
||||||
worker.join();
|
worker.join();
|
||||||
|
|
||||||
for (auto const &error : errors)
|
for (auto &result : results)
|
||||||
{
|
result.get();
|
||||||
if (error)
|
|
||||||
std::rethrow_exception(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Teraz kasowanie (tylko w głównym wątku)
|
// Teraz kasowanie (tylko w głównym wątku)
|
||||||
for (TTrain *train : m_items)
|
for (TTrain *train : m_items)
|
||||||
|
|||||||
Reference in New Issue
Block a user