diff --git a/server/src/board/tile/rail/signal/signal2aspectrailtile.cpp b/server/src/board/tile/rail/signal/signal2aspectrailtile.cpp index dbfdf7cd..89a868f0 100644 --- a/server/src/board/tile/rail/signal/signal2aspectrailtile.cpp +++ b/server/src/board/tile/rail/signal/signal2aspectrailtile.cpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,18 +22,18 @@ #include "signal2aspectrailtile.hpp" #include "../../../../core/attributes.hpp" -#include "../../../../utils/makearray.hpp" + +static const std::array aspectValues = {SignalAspect::Stop, SignalAspect::Proceed, SignalAspect::Unknown}; +static const std::array setAspectValues = {SignalAspect::Stop, SignalAspect::Proceed}; Signal2AspectRailTile::Signal2AspectRailTile(World& world, std::string_view _id) : SignalRailTile(world, _id, TileId::RailSignal2Aspect) { outputMap.setValueInternal(std::make_shared(*this, outputMap.name(), std::initializer_list{SignalAspect::Stop, SignalAspect::Proceed})); - Attributes::addValues(aspect, makeArray(SignalAspect::Stop, SignalAspect::Proceed, SignalAspect::Unknown)); + Attributes::addValues(aspect, aspectValues); m_interfaceItems.add(aspect); -} -void Signal2AspectRailTile::doNextAspect(bool /*reverse*/) -{ - aspect = (aspect == SignalAspect::Stop) ? SignalAspect::Proceed : SignalAspect::Stop; + Attributes::addValues(setAspect, setAspectValues); + m_interfaceItems.add(setAspect); } diff --git a/server/src/board/tile/rail/signal/signal2aspectrailtile.hpp b/server/src/board/tile/rail/signal/signal2aspectrailtile.hpp index 1faeead5..3b21dc29 100644 --- a/server/src/board/tile/rail/signal/signal2aspectrailtile.hpp +++ b/server/src/board/tile/rail/signal/signal2aspectrailtile.hpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,9 +30,6 @@ class Signal2AspectRailTile : public SignalRailTile CLASS_ID("board_tile.rail.signal_2_aspect") CREATE(Signal2AspectRailTile) - protected: - void doNextAspect(bool) final; - public: Signal2AspectRailTile(World& world, std::string_view _id); }; diff --git a/server/src/board/tile/rail/signal/signal3aspectrailtile.cpp b/server/src/board/tile/rail/signal/signal3aspectrailtile.cpp index e59073e8..fd6a8e5a 100644 --- a/server/src/board/tile/rail/signal/signal3aspectrailtile.cpp +++ b/server/src/board/tile/rail/signal/signal3aspectrailtile.cpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,39 +22,18 @@ #include "signal3aspectrailtile.hpp" #include "../../../../core/attributes.hpp" -#include "../../../../utils/makearray.hpp" + +static const std::array aspectValues = {SignalAspect::Stop, SignalAspect::ProceedReducedSpeed, SignalAspect::Proceed, SignalAspect::Unknown}; +static const std::array setAspectValues = {SignalAspect::Stop, SignalAspect::ProceedReducedSpeed, SignalAspect::Proceed}; Signal3AspectRailTile::Signal3AspectRailTile(World& world, std::string_view _id) : SignalRailTile(world, _id, TileId::RailSignal3Aspect) { outputMap.setValueInternal(std::make_shared(*this, outputMap.name(), std::initializer_list{SignalAspect::Stop, SignalAspect::ProceedReducedSpeed, SignalAspect::Proceed})); - Attributes::addValues(aspect, makeArray(SignalAspect::Stop, SignalAspect::ProceedReducedSpeed, SignalAspect::Proceed, SignalAspect::Unknown)); + Attributes::addValues(aspect, aspectValues); m_interfaceItems.add(aspect); -} - -void Signal3AspectRailTile::doNextAspect(bool reverse) -{ - switch(aspect) - { - case SignalAspect::Unknown: - aspect = SignalAspect::Stop; - break; - - case SignalAspect::Stop: - aspect = reverse ? SignalAspect::Proceed : SignalAspect::ProceedReducedSpeed; - break; - - case SignalAspect::ProceedReducedSpeed: - aspect = reverse ? SignalAspect::Stop : SignalAspect::Proceed; - break; - - case SignalAspect::Proceed: - aspect = reverse ? SignalAspect::ProceedReducedSpeed : SignalAspect::Stop; - break; - - default: - assert(false); - break; - } + + Attributes::addValues(setAspect, setAspectValues); + m_interfaceItems.add(setAspect); } diff --git a/server/src/board/tile/rail/signal/signal3aspectrailtile.hpp b/server/src/board/tile/rail/signal/signal3aspectrailtile.hpp index 079c7bd7..0d54db2d 100644 --- a/server/src/board/tile/rail/signal/signal3aspectrailtile.hpp +++ b/server/src/board/tile/rail/signal/signal3aspectrailtile.hpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,9 +30,6 @@ class Signal3AspectRailTile : public SignalRailTile CLASS_ID("board_tile.rail.signal_3_aspect") CREATE(Signal3AspectRailTile) - protected: - void doNextAspect(bool reverse) final; - public: Signal3AspectRailTile(World& world, std::string_view _id); }; diff --git a/server/src/board/tile/rail/signal/signalrailtile.cpp b/server/src/board/tile/rail/signal/signalrailtile.cpp index 3887ac5c..865e7592 100644 --- a/server/src/board/tile/rail/signal/signalrailtile.cpp +++ b/server/src/board/tile/rail/signal/signalrailtile.cpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,14 +27,10 @@ SignalRailTile::SignalRailTile(World& world, std::string_view _id, TileId tileId) : StraightRailTile(world, _id, tileId), - name{this, "name", std::string(_id), PropertyFlags::ReadWrite | PropertyFlags::Store}, - aspect{this, "aspect", SignalAspect::Unknown, PropertyFlags::ReadWrite | PropertyFlags::StoreState, - [this](SignalAspect value) - { - (*outputMap)[value]->execute(); - }}, - outputMap{this, "output_map", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject}, - nextAspect{*this, "next_aspect", [this](bool reverse){ doNextAspect(reverse); }} + name{this, "name", std::string(_id), PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly}, + aspect{this, "aspect", SignalAspect::Unknown, PropertyFlags::ReadOnly | PropertyFlags::StoreState | PropertyFlags::ScriptReadOnly}, + outputMap{this, "output_map", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject | PropertyFlags::NoScript}, + setAspect{*this, "set_aspect", MethodFlags::ScriptCallable, [this](SignalAspect value) { return doSetAspect(value); }} { const bool editable = contains(m_world.state.value(), WorldState::Edit); @@ -48,8 +44,8 @@ SignalRailTile::SignalRailTile(World& world, std::string_view _id, TileId tileId Attributes::addDisplayName(outputMap, DisplayName::BoardTile::outputMap); m_interfaceItems.add(outputMap); - Attributes::addObjectEditor(nextAspect, false); - m_interfaceItems.add(nextAspect); + Attributes::addObjectEditor(setAspect, false); + // setAspect is added by sub class } void SignalRailTile::worldEvent(WorldState state, WorldEvent event) @@ -60,3 +56,14 @@ void SignalRailTile::worldEvent(WorldState state, WorldEvent event) Attributes::setEnabled(name, editable); } + +bool SignalRailTile::doSetAspect(SignalAspect value) +{ + const auto* values = setAspect.tryGetValuesAttribute(AttributeName::Values); + assert(values); + if(!values->contains(static_cast(value))) + return false; + (*outputMap)[value]->execute(); + aspect.setValueInternal(value); + return true; +} diff --git a/server/src/board/tile/rail/signal/signalrailtile.hpp b/server/src/board/tile/rail/signal/signalrailtile.hpp index 3495a4f2..ffec7aa9 100644 --- a/server/src/board/tile/rail/signal/signalrailtile.hpp +++ b/server/src/board/tile/rail/signal/signalrailtile.hpp @@ -3,7 +3,7 @@ * * This file is part of the traintastic source code. * - * Copyright (C) 2020-2021 Reinder Feenstra + * Copyright (C) 2020-2022 Reinder Feenstra * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,13 +38,13 @@ class SignalRailTile : public StraightRailTile void worldEvent(WorldState state, WorldEvent event) override; - virtual void doNextAspect(bool reverse) = 0; + virtual bool doSetAspect(SignalAspect value); public: Property name; Property aspect; ObjectProperty outputMap; - Method nextAspect; + Method setAspect; }; #endif diff --git a/server/src/core/abstractvaluesattribute.hpp b/server/src/core/abstractvaluesattribute.hpp index 2b4c2321..431bff2f 100644 --- a/server/src/core/abstractvaluesattribute.hpp +++ b/server/src/core/abstractvaluesattribute.hpp @@ -39,6 +39,15 @@ class AbstractValuesAttribute : public AbstractAttribute virtual int64_t getInt64(uint32_t index) const = 0; virtual double getDouble(uint32_t index) const = 0; virtual std::string getString(uint32_t index) const = 0; + + inline bool contains(int64_t value) const + { + const auto l{length()}; + for(uint32_t i = 0; i < l; i++) + if(value == getInt64(i)) + return true; + return false; + } }; #endif diff --git a/server/src/core/attributes.hpp b/server/src/core/attributes.hpp index 0c179834..27ada980 100644 --- a/server/src/core/attributes.hpp +++ b/server/src/core/attributes.hpp @@ -176,6 +176,12 @@ struct Attributes item.addAttribute(AttributeName::ObjectList, id); } + template + static inline void addValues(Method& method, const std::array& values) + { + method.addAttribute(AttributeName::Values, values); + } + template static inline void addValues(Property& property, const std::array& values) {