diff --git a/.gitignore b/.gitignore index 5186ceae..a37adb6e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ ci_shadervalidator/validateshaders # CMake build output build/ +build-*/ bin/ #Visual Studio [Code] folders diff --git a/CMakeLists.txt b/CMakeLists.txt index 111f8cc6..3dc46bbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,18 @@ set(SOURCES "editor/polandmap.cpp" "editor/turnouts.cpp" "editor/orthophoto.cpp" +"editor/plan_chain.cpp" +"editor/plan_document_io.cpp" +"editor/plan_join.cpp" +"editor/plan_layout.cpp" +"editor/plan_model.cpp" +"editor/plan_rail_renderer.cpp" +"editor/plan_render.cpp" +"editor/plan_scn_export.cpp" +"editor/plan_sketch.cpp" +"editor/plan_solution.cpp" +"editor/plan_tilecache.cpp" +"editor/plan_turnout_geometry.cpp" "editor/editorTerrain.cpp" "editor/editorTerrainStreamer.cpp" "application/editormode.cpp" @@ -633,9 +645,6 @@ target_link_libraries(${PROJECT_NAME} nlohmann_json::nlohmann_json) target_include_directories(${PROJECT_NAME} PRIVATE ${NLOHMANN_JSON_INCLUDE_INSTALL_DIR}) # track layout domain model used by the editor; plain C++20, no dependencies of its own -add_subdirectory(maj0sted) -set_target_properties(maj0sted PROPERTIES FOLDER "libraries") -target_link_libraries(${PROJECT_NAME} maj0sted::maj0sted) @@ -716,6 +725,8 @@ endif() # copied off it rather than restated; this has to happen after all the # third-party wiring above and before betterRenderer is added, or the mirrored # link list would point back at betterRenderer and make the dependency circular. +add_subdirectory(editor/tests) + add_library(eu07_modules STATIC) get_target_property(EU07_INCLUDES ${PROJECT_NAME} INCLUDE_DIRECTORIES) diff --git a/NIWELETA_REDESIGN.md b/NIWELETA_REDESIGN.md index 47cfd1b3..4771aefc 100644 --- a/NIWELETA_REDESIGN.md +++ b/NIWELETA_REDESIGN.md @@ -63,7 +63,7 @@ osobnym, jawnym polem.** Kernel do tego już mamy: `geometry::layout_segment`. ## 3. Model docelowy -Płasko, w `maj0sted::editor`, Id jako mocne typy. +Płasko, w `editor::plan`, Id jako mocne typy. ### 3.1. Odcinek jest bytem diff --git a/application/application.cpp b/application/application.cpp index 052f4f89..cdc99296 100644 --- a/application/application.cpp +++ b/application/application.cpp @@ -1176,6 +1176,13 @@ int eu07_application::init_settings(int Argc, char *Argv[]) std::string token{Argv[i]}; + // a switch may be written with one dash or two: both spellings are common on the command + // line and neither says anything different, so the second dash is simply dropped here + if (token.size() > 2 && token.compare(0, 2, "--") == 0) + { + token.erase(0, 1); + } + if (token == "-s") { if (i + 1 < Argc) @@ -1199,7 +1206,8 @@ int eu07_application::init_settings(int Argc, char *Argv[]) { std::cout << "usage: " << std::string(Argv[0]) << " [-s sceneryfilepath]" << " [-v vehiclename]" - << " [-editor]" << std::endl; + << " [-editor]" + << " (every switch also takes a double dash: --editor)" << std::endl; return -1; } } diff --git a/application/planpanel.cpp b/application/planpanel.cpp index 39403229..fbebdc45 100644 --- a/application/planpanel.cpp +++ b/application/planpanel.cpp @@ -6,24 +6,25 @@ module; #include #include #include +#include #include #include "imgui/imgui.h" #include "utilities/Globals_macros.h" -#include "maj0sted/editor/layout.hpp" -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/render.hpp" -#include "maj0sted/editor/solution.hpp" -#include "maj0sted/editor/tile_cache.hpp" -#include "maj0sted/io/scn_export.hpp" -#include "maj0sted/editor/join.hpp" -#include "maj0sted/editor/sketch.hpp" -#include "maj0sted/io/document_io.hpp" #if !defined(_WIN32) #include #include #endif module eu07.application.planpanel; +import eu07.editor.plan_layout; +import eu07.editor.plan_model; +import eu07.editor.plan_render; +import eu07.editor.plan_solution; +import eu07.editor.plan_tilecache; +import eu07.editor.plan_scn_export; +import eu07.editor.plan_join; +import eu07.editor.plan_sketch; +import eu07.editor.plan_document_io; import eu07.glm; import eu07.utilities.globals; import eu07.utilities.utilities; @@ -44,13 +45,13 @@ http://mozilla.org/MPL/2.0/. namespace { -using maj0sted::editor::Element; -using maj0sted::editor::ElementId; -using maj0sted::editor::Free; -using maj0sted::editor::Kind; -using maj0sted::editor::Parallel; -using maj0sted::editor::TrackId; -using maj0sted::editor::TurnoutId; +using editor::plan::Element; +using editor::plan::ElementId; +using editor::plan::Free; +using editor::plan::Kind; +using editor::plan::Parallel; +using editor::plan::TrackId; +using editor::plan::TurnoutId; // the plan works in EPSG:2180, the scenery in the engine's world space around its own zero. the // georeference says which point of the projection that zero stands for; a fictional scenery leaves @@ -286,7 +287,7 @@ editor::turnout_preset const *find_preset(std::string const &Name_) // the catalogue figure written onto a document's own type. a document keeps its own copy of the // catalogue - that is what lets an instance name its type and nothing more - so this is the one // place the preset's numbers cross over, and it has to carry all of them -void adopt_preset(editor::turnout_preset const &Preset_, maj0sted::editor::TurnoutType &Type_) +void adopt_preset(editor::turnout_preset const &Preset_, editor::plan::TurnoutType &Type_) { Type_.name = Preset_.name; Type_.crossing_n = Preset_.crossing_n; @@ -298,7 +299,7 @@ void adopt_preset(editor::turnout_preset const &Preset_, maj0sted::editor::Turno for (auto const &piece : Preset_.pieces) { Type_.pieces.push_back( - maj0sted::editor::TurnoutPieceSpec{piece.part, piece.length, piece.radius_start, piece.radius_end, piece.turn_in}); + editor::plan::TurnoutPieceSpec{piece.part, piece.length, piece.radius_start, piece.radius_end, piece.turn_in}); } } @@ -436,7 +437,7 @@ void plan_panel::seed_catalogue() [&](auto const &Type_) { return Type_.name == preset.name; })}; if (existing == m_document.turnout_types.end()) { - maj0sted::editor::TurnoutType type; + editor::plan::TurnoutType type; adopt_preset(preset, type); m_document.turnout_types.push_back(std::move(type)); continue; @@ -460,24 +461,24 @@ void plan_panel::seed_catalogue() void plan_panel::solve() { - m_solution = maj0sted::editor::solve(m_document); - m_rails = maj0sted::editor::render_rails(m_solution); + m_solution = editor::plan::solve(m_document); + m_rails = editor::plan::render_rails(m_solution); } plan_panel::Track *plan_panel::current_track() { - return maj0sted::editor::find_track(m_document, m_track); + return editor::plan::find_track(m_document, m_track); } plan_panel::Track const *plan_panel::current_track() const { - return maj0sted::editor::find_track(m_document, m_track); + return editor::plan::find_track(m_document, m_track); } void plan_panel::new_track() { Track track; - track.id = maj0sted::editor::mint_track(m_document); + track.id = editor::plan::mint_track(m_document); track.name = "tor " + std::to_string(m_document.tracks.size() + 1); m_document.tracks.push_back(track); m_track = track.id; @@ -548,8 +549,8 @@ void plan_panel::append_point_to(double const X, double const Y) m_status = "za krotka prosta"; return; } - track->anchor = maj0sted::editor::AtPose{m_startx, m_starty, std::atan2(dx, dy)}; - track->elements.push_back(maj0sted::editor::make_line(m_document, length)); + track->anchor = editor::plan::AtPose{m_startx, m_starty, std::atan2(dx, dy)}; + track->elements.push_back(editor::plan::make_line(m_document, length)); m_pending = false; solve(); m_status.clear(); @@ -557,7 +558,7 @@ void plan_panel::append_point_to(double const X, double const Y) } // the track ends on the last click, so that end is the corner this one turns at - auto const *solved{maj0sted::editor::find_track(m_solution, track->id)}; + auto const *solved{editor::plan::find_track(m_solution, track->id)}; if (solved == nullptr || solved->elements.empty()) { m_status = "tor nie jest polozony - popraw najpierw to, co nie wyszlo"; @@ -574,7 +575,7 @@ void plan_panel::append_point_to(double const X, double const Y) return; } - auto const corner{maj0sted::editor::fit_corner(corner_pose.hx, corner_pose.hy, dx / reach, dy / reach, m_corner_radius)}; + auto const corner{editor::plan::fit_corner(corner_pose.hx, corner_pose.hy, dx / reach, dy / reach, m_corner_radius)}; if (false == corner.ok) { // straight on: nothing to round. two straights end to end are one straight, so the one @@ -601,8 +602,8 @@ void plan_panel::append_point_to(double const X, double const Y) } previous.length -= corner.tangent; - track->elements.push_back(maj0sted::editor::make_arc(m_document, m_corner_radius, corner.hand, corner.arc_length)); - track->elements.push_back(maj0sted::editor::make_line(m_document, reach - corner.tangent)); + track->elements.push_back(editor::plan::make_arc(m_document, m_corner_radius, corner.hand, corner.arc_length)); + track->elements.push_back(editor::plan::make_line(m_document, reach - corner.tangent)); solve(); m_status.clear(); } @@ -659,7 +660,7 @@ void plan_panel::append_element(Kind const Kind_) } Element element; - element.id = maj0sted::editor::mint_element(m_document); + element.id = editor::plan::mint_element(m_document); element.kind = Kind_; element.radius = Kind_ == Kind::Line ? 0.0 : m_new_radius; element.hand = Kind_ == Kind::Line ? 0 : m_new_hand; @@ -739,33 +740,33 @@ bool plan_panel::refit_current_track(std::string &Why) auto *track{current_track()}; // the solution still holds the geometry from before the change, which is exactly what the // straights are supposed to go on standing on - auto const *solved{maj0sted::editor::find_track(m_solution, m_track)}; + auto const *solved{editor::plan::find_track(m_solution, m_track)}; if (track == nullptr || solved == nullptr) { Why = "tor nie jest polozony"; return false; } - maj0sted::editor::Skeleton skeleton; - if (false == maj0sted::editor::skeleton_of(*track, *solved, skeleton, Why)) + editor::plan::Skeleton skeleton; + if (false == editor::plan::skeleton_of(*track, *solved, skeleton, Why)) { return false; } - return maj0sted::editor::lay_along_skeleton(*track, skeleton, Why); + return editor::plan::lay_along_skeleton(*track, skeleton, Why); } void plan_panel::drag_straight_to(double const X, double const Y) { auto *track{current_track()}; - auto const *solved{maj0sted::editor::find_track(m_solution, m_track)}; + auto const *solved{editor::plan::find_track(m_solution, m_track)}; if (track == nullptr || solved == nullptr || m_drag_index >= track->elements.size()) { return; } - maj0sted::editor::Skeleton skeleton; + editor::plan::Skeleton skeleton; std::string why; - if (false == maj0sted::editor::skeleton_of(*track, *solved, skeleton, why)) + if (false == editor::plan::skeleton_of(*track, *solved, skeleton, why)) { m_status = why; return; @@ -818,18 +819,18 @@ void plan_panel::drag_straight_to(double const X, double const Y) // nothing is written until the whole chain works out, so a bad drag leaves the track alone Track candidate{*track}; - if (false == maj0sted::editor::lay_along_skeleton(candidate, skeleton, why)) + if (false == editor::plan::lay_along_skeleton(candidate, skeleton, why)) { m_status = why; return; } // the chain laying out is not enough: shortening a straight can pull it out from under a rozjazd // standing on it, and a rozjazd half on an arc is not a rozjazd. the drag stops at that instead - auto const off_straight{[](maj0sted::editor::Solution const &Solution_) { + auto const off_straight{[](editor::plan::Solution const &Solution_) { std::size_t count{0}; for (auto const &diagnostic : Solution_.diagnostics) { - count += diagnostic.code == maj0sted::editor::Code::StationOffTrack ? 1 : 0; + count += diagnostic.code == editor::plan::Code::StationOffTrack ? 1 : 0; } return count; }}; @@ -842,7 +843,7 @@ void plan_panel::drag_straight_to(double const X, double const Y) { for (auto const &diagnostic : m_solution.diagnostics) { - if (diagnostic.code == maj0sted::editor::Code::StationOffTrack) + if (diagnostic.code == editor::plan::Code::StationOffTrack) { m_status = "dalej nie: " + diagnostic.text; break; @@ -870,8 +871,8 @@ void plan_panel::place_turnout_at(TrackId const On, double const Wx, double cons } auto const type{static_cast(std::clamp(m_turnout_type, 0, static_cast(m_document.turnout_types.size()) - 1))}; - maj0sted::editor::TurnoutPlacement placement; - placement.id = maj0sted::editor::mint_turnout(m_document); + editor::plan::TurnoutPlacement placement; + placement.id = editor::plan::mint_turnout(m_document); placement.type = m_document.turnout_types[type].name; placement.on = On; placement.station = station; @@ -880,9 +881,9 @@ void plan_panel::place_turnout_at(TrackId const On, double const Wx, double cons // a switch is worth nothing without somewhere for the branch to go, so one starts at its frog Track branch; - branch.id = maj0sted::editor::mint_track(m_document); + branch.id = editor::plan::mint_track(m_document); branch.name = "odnoga " + std::to_string(m_document.tracks.size() + 1); - branch.anchor = maj0sted::editor::AtPort{placement.id, maj0sted::editor::Port::Frog}; + branch.anchor = editor::plan::AtPort{placement.id, editor::plan::Port::Frog}; m_document.tracks.push_back(branch); m_track = branch.id; @@ -899,7 +900,7 @@ void plan_panel::place_turnout_at(TrackId const On, double const Wx, double cons bool plan_panel::hit_straight_end(ImVec2 const &Mouse, std::size_t &OutIndex, int &OutEnd) const { - auto const *solved{maj0sted::editor::find_track(m_solution, m_track)}; + auto const *solved{editor::plan::find_track(m_solution, m_track)}; auto const *track{current_track()}; if (solved == nullptr || track == nullptr) { @@ -916,7 +917,7 @@ bool plan_panel::hit_straight_end(ImVec2 const &Mouse, std::size_t &OutIndex, in continue; } // a branch starts on its turnout's frog and cannot be pulled off it - auto const pinned{i == 0 && false == std::holds_alternative(track->anchor)}; + auto const pinned{i == 0 && false == std::holds_alternative(track->anchor)}; for (int end = 0; end < 2; ++end) { if (end == 0 && pinned) @@ -1007,7 +1008,7 @@ bool plan_panel::hit_turnout(ImVec2 const &Mouse, TurnoutId &OutTurnout) const bool plan_panel::station_on(TrackId const Track_, double const Wx, double const Wy, double &OutStation) const { - auto const *track{maj0sted::editor::find_track(m_solution, Track_)}; + auto const *track{editor::plan::find_track(m_solution, Track_)}; if (track == nullptr || track->centreline.size() < 2) { return false; @@ -1171,7 +1172,7 @@ void plan_panel::handle_scene() int end{0}; if (hit_straight_end(mouse, index, end)) { - auto const *solved{maj0sted::editor::find_track(m_solution, m_track)}; + auto const *solved{editor::plan::find_track(m_solution, m_track)}; auto const *track{current_track()}; if (solved != nullptr && index < solved->elements.size()) { @@ -1183,7 +1184,7 @@ void plan_panel::handle_scene() m_drag_end = end; m_dragging_straight = true; m_sel_element = track->elements[index].id; - if (track != nullptr && std::holds_alternative(track->elements[index].hold)) + if (track != nullptr && std::holds_alternative(track->elements[index].hold)) { m_status = "ten odcinek trzyma rownoleglosc - po puszczeniu tor i tak zostanie przystawiony"; } @@ -1223,7 +1224,7 @@ void plan_panel::handle_scene() { m_sel_element = element; m_track = track; - auto const *chosen{maj0sted::editor::find_track(m_document, track)}; + auto const *chosen{editor::plan::find_track(m_document, track)}; if (chosen != nullptr) { std::snprintf(m_namebuf, sizeof(m_namebuf), "%s", chosen->name.c_str()); @@ -1243,7 +1244,7 @@ void plan_panel::handle_scene() if (ImGui::IsMouseDown(0) && m_dragging_turnout && m_sel_turnout != TurnoutId::none) { - auto *placement{maj0sted::editor::find_turnout(m_document, m_sel_turnout)}; + auto *placement{editor::plan::find_turnout(m_document, m_sel_turnout)}; if (placement != nullptr) { double station{0.0}; @@ -1267,7 +1268,7 @@ void plan_panel::handle_scene() if (track != TrackId::none) { m_track = track; - auto const *chosen{maj0sted::editor::find_track(m_document, track)}; + auto const *chosen{editor::plan::find_track(m_document, track)}; if (chosen != nullptr) { std::snprintf(m_namebuf, sizeof(m_namebuf), "%s", chosen->name.c_str()); @@ -1295,9 +1296,9 @@ void plan_panel::draw_on_scene() auto const display{ImGui::GetIO().DisplaySize}; auto const halfheight{static_cast(Global.editor_ortho_extent)}; auto const halfwidth{halfheight * std::max(1.0f, display.x) / std::max(1.0f, display.y)}; - maj0sted::editor::TileBBox const view{planx - halfwidth, plany - halfheight, planx + halfwidth, plany + halfheight}; + editor::plan::TileBBox const view{planx - halfwidth, plany - halfheight, planx + halfwidth, plany + halfheight}; - auto const draw_box = [&](maj0sted::editor::TileBBox const &Box, unsigned int const Texture) { + auto const draw_box = [&](editor::plan::TileBBox const &Box, unsigned int const Texture) { ImVec2 corners[4]; auto const ok = world_to_screen(plan_to_world(Box.min_x, Box.max_y), corners[0]) && world_to_screen(plan_to_world(Box.max_x, Box.max_y), corners[1]) && world_to_screen(plan_to_world(Box.max_x, Box.min_y), corners[2]) && world_to_screen(plan_to_world(Box.min_x, Box.min_y), corners[3]); @@ -1399,7 +1400,7 @@ void plan_panel::draw_on_scene() // the points that sit on the straight - PR, the blade tip and the koniec rozjazdu - // are drawn the way a catalogue drawing marks them: a tick across the track, not a // dot lost among the rails the turnout runs along - auto const tick{[&](maj0sted::editor::TurnoutMark const &Mark_, ImU32 const Colour_, float const Half_) { + auto const tick{[&](editor::plan::TurnoutMark const &Mark_, ImU32 const Colour_, float const Half_) { ImVec2 centre; if (false == world_to_screen(plan_to_world(Mark_.x, Mark_.y), centre)) { @@ -1536,7 +1537,7 @@ void plan_panel::draw_on_scene() // the ends of the edited track's straights, while ctrl says they are what you are after if (ImGui::GetIO().KeyCtrl) { - auto const *solved{maj0sted::editor::find_track(m_solution, m_track)}; + auto const *solved{editor::plan::find_track(m_solution, m_track)}; auto const *track{current_track()}; if (solved != nullptr && track != nullptr) { @@ -1546,7 +1547,7 @@ void plan_panel::draw_on_scene() { continue; } - auto const pinned{i == 0 && false == std::holds_alternative(track->anchor)}; + auto const pinned{i == 0 && false == std::holds_alternative(track->anchor)}; for (int end = 0; end < 2; ++end) { if (end == 0 && pinned) @@ -1643,25 +1644,25 @@ void plan_panel::draw_on_scene() // left the way it came, and the arriving end reads the other way about if (m_pick_join == 2 && over && hovered != m_join_first) { - auto const *head{maj0sted::editor::find_track(m_solution, m_join_first)}; - auto const *tail{maj0sted::editor::find_track(m_solution, hovered)}; + auto const *head{editor::plan::find_track(m_solution, m_join_first)}; + auto const *tail{editor::plan::find_track(m_solution, hovered)}; if (head != nullptr && tail != nullptr) { auto const leaving{join_pose(*head, m_join_first_end, true)}; auto const arriving{join_pose(*tail, hovered_end, false)}; - maj0sted::editor::JoinSettings settings; + editor::plan::JoinSettings settings; settings.radius = m_join_radius; - auto const plan{maj0sted::editor::plan_join(leaving, arriving, settings)}; + auto const plan{editor::plan::plan_join(leaving, arriving, settings)}; std::string label; if (plan.ok) { - std::vector points; + std::vector points; auto walker{leaving}; for (auto const &element : plan.elements) { auto const k{element.kind == Kind::Line || element.radius <= 0.0 ? 0.0 : element.hand / element.radius}; - walker = maj0sted::domain::geometry::layout_segment(k, k, element.length, walker, &points); + walker = editor::plan::geometry::layout_segment(k, k, element.length, walker, &points); } std::vector line; line.reserve(points.size()); @@ -1677,7 +1678,7 @@ void plan_panel::draw_on_scene() { dashed_polyline(drawlist, line, IM_COL32(120, 255, 160, 235), 2.5f); } - label = maj0sted::editor::join_kind_name(plan.kind); + label = editor::plan::join_kind_name(plan.kind); auto laid{0.0}; for (auto const &element : plan.elements) { @@ -1872,10 +1873,10 @@ void plan_panel::render_join() void plan_panel::join_ends(TrackId const A, int const Aend, TrackId const B, int const Bend) { - maj0sted::editor::JoinSettings settings; + editor::plan::JoinSettings settings; settings.radius = m_join_radius; - auto const report{maj0sted::editor::join_ends(m_document, m_solution, A, Aend, B, Bend, settings)}; + auto const report{editor::plan::join_ends(m_document, m_solution, A, Aend, B, Bend, settings)}; if (false == report.ok) { m_status = report.why; @@ -1884,16 +1885,16 @@ void plan_panel::join_ends(TrackId const A, int const Aend, TrackId const B, int // whichever track was left standing is the one to select afterwards, and it is not // always the first clicked - the other one may have been the only one that could turn - auto const survivor{maj0sted::editor::find_track(m_document, A) != nullptr ? A : B}; + auto const survivor{editor::plan::find_track(m_document, A) != nullptr ? A : B}; char status[256]; - std::snprintf(status, sizeof(status), "polaczone: %s, %d odcinkow zlanych w jeden, %d rozjazdow przeniesionych%s", maj0sted::editor::join_kind_name(report.join.kind), report.fused, + std::snprintf(status, sizeof(status), "polaczone: %s, %d odcinkow zlanych w jeden, %d rozjazdow przeniesionych%s", editor::plan::join_kind_name(report.join.kind), report.fused, report.turnouts, report.reversed ? ", jeden tor czytany od drugiego konca" : ""); m_status = status; m_track = survivor; m_pick_join = 0; m_join_first = TrackId::none; - auto const *joined{maj0sted::editor::find_track(m_document, survivor)}; + auto const *joined{editor::plan::find_track(m_document, survivor)}; if (joined != nullptr) { std::snprintf(m_namebuf, sizeof(m_namebuf), "%s", joined->name.c_str()); @@ -1902,7 +1903,7 @@ void plan_panel::join_ends(TrackId const A, int const Aend, TrackId const B, int solve(); } -maj0sted::domain::geometry::Pose plan_panel::join_pose(maj0sted::editor::SolvedTrack const &Track_, int const End_, bool const Leaving_) +editor::plan::geometry::Pose plan_panel::join_pose(editor::plan::SolvedTrack const &Track_, int const End_, bool const Leaving_) { auto pose{End_ == 1 ? Track_.end : Track_.start}; // what is laid runs out of one end and into the other, so an end that points the @@ -1916,7 +1917,7 @@ maj0sted::domain::geometry::Pose plan_panel::join_pose(maj0sted::editor::SolvedT return pose; } -bool plan_panel::loose_end(maj0sted::editor::SolvedTrack const &Track_, int const End_) const +bool plan_panel::loose_end(editor::plan::SolvedTrack const &Track_, int const End_) const { if (Track_.elements.empty()) { @@ -1925,8 +1926,8 @@ bool plan_panel::loose_end(maj0sted::editor::SolvedTrack const &Track_, int cons if (End_ == 0) { // a track hanging on a turnout's port starts on the frog, and that is not a loose end - auto const *authored{maj0sted::editor::find_track(m_document, Track_.id)}; - if (authored == nullptr || false == std::holds_alternative(authored->anchor)) + auto const *authored{editor::plan::find_track(m_document, Track_.id)}; + if (authored == nullptr || false == std::holds_alternative(authored->anchor)) { return false; } @@ -2050,7 +2051,7 @@ void plan_panel::render_elements() // and to nothing else, so the track is re-laid along the lines its straights already stood on. // a change of length is what it says it is: the element gets longer, and what follows moves auto refit{false}; - auto const *solved{maj0sted::editor::find_track(m_solution, track->id)}; + auto const *solved{editor::plan::find_track(m_solution, track->id)}; for (std::size_t i = 0; i < track->elements.size(); ++i) { @@ -2111,7 +2112,7 @@ void plan_panel::render_elements() ImGui::SetNextItemWidth(120.0f); if (ImGui::InputDouble(element.kind == Kind::Clothoid ? "R na koncu [m]" : "promien [m]", &element.radius, 10.0, 100.0, "%.2f")) { - maj0sted::editor::sync_joint(*track, i); + editor::plan::sync_joint(*track, i); dirty = true; refit = true; } @@ -2124,7 +2125,7 @@ void plan_panel::render_elements() if (ImGui::Combo("skret", &hand, "w lewo\0w prawo\0")) { element.hand = hand == 0 ? 1 : -1; - maj0sted::editor::sync_joint(*track, i); + editor::plan::sync_joint(*track, i); dirty = true; refit = true; } @@ -2191,7 +2192,7 @@ void plan_panel::render_elements() // prosta krzyzownicowa, in the order they are laid from PR. every length is the catalogue's - // nothing here is fitted, so the skos and the catalogue length are checked against what the list // works out to and the difference is said out loud -void plan_panel::render_turnout_type(maj0sted::editor::TurnoutType &Type_) +void plan_panel::render_turnout_type(editor::plan::TurnoutType &Type_) { auto dirty{false}; @@ -2290,7 +2291,7 @@ void plan_panel::render_turnout_type(maj0sted::editor::TurnoutType &Type_) } if (ImGui::SmallButton("dodaj odcinek")) { - Type_.pieces.push_back(maj0sted::editor::TurnoutPieceSpec{2, 1.0, 0.0, 0.0, 0.0}); + Type_.pieces.push_back(editor::plan::TurnoutPieceSpec{2, 1.0, 0.0, 0.0, 0.0}); m_sel_piece = static_cast(Type_.pieces.size()) - 1; dirty = true; } @@ -2319,7 +2320,7 @@ void plan_panel::render_turnout_type(maj0sted::editor::TurnoutType &Type_) dirty = true; } - auto const laid{maj0sted::domain::lay_turnout(maj0sted::domain::geometry::Pose{0.0, 0.0, 1.0, 0.0}, maj0sted::editor::to_domain(Type_, 1))}; + auto const laid{editor::plan::lay_turnout(editor::plan::geometry::Pose{0.0, 0.0, 1.0, 0.0}, editor::plan::to_domain(Type_, 1))}; if (false == laid.valid) { ImGui::TextColored(ImVec4(1.0f, 0.55f, 0.55f, 1.0f), "lista nie da sie polozyc: dlugosci > 0, promienie >= 0"); @@ -2370,9 +2371,9 @@ void plan_panel::render_template_window() m_turnout_type = std::clamp(m_turnout_type, 0, static_cast(m_document.turnout_types.size()) - 1); auto const &type{m_document.turnout_types[static_cast(m_turnout_type)]}; - auto const start{maj0sted::domain::geometry::Pose{0.0, 0.0, 1.0, 0.0}}; + auto const start{editor::plan::geometry::Pose{0.0, 0.0, 1.0, 0.0}}; auto const bend{m_tpl_bend_radius > 1.0 ? (m_tpl_bend_hand == 0 ? 1.0 : -1.0) / m_tpl_bend_radius : 0.0}; - auto const laid{maj0sted::domain::lay_turnout(start, maj0sted::editor::to_domain(type, 1), bend)}; + auto const laid{editor::plan::lay_turnout(start, editor::plan::to_domain(type, 1), bend)}; if (false == laid.valid) { ImGui::TextColored(ImVec4(1.0f, 0.55f, 0.55f, 1.0f), bend != 0.0 ? "typu \"%s\" nie da sie wygiac na taki luk" : "typ \"%s\" nie da sie polozyc", @@ -2469,11 +2470,11 @@ void plan_panel::render_template_window() drawlist->PushClipRect(origin, ImVec2(origin.x + w, origin.y + h), true); drawlist->AddRectFilled(origin, ImVec2(origin.x + w, origin.y + h), IM_COL32(16, 20, 26, 255)); - auto const half{maj0sted::domain::kHalfGauge}; + auto const half{editor::plan::kHalfGauge}; // the tor zasadniczy, and the opornica the blade lies against. bent, it is an arc like any other, // so it is walked rather than ruled - auto const through_at{[&](double const Station_) { return maj0sted::domain::geometry::layout_segment(bend, bend, Station_, start, nullptr); }}; + auto const through_at{[&](double const Station_) { return editor::plan::geometry::layout_segment(bend, bend, Station_, start, nullptr); }}; auto const through_line{[&](double const From_, double const To_, double const Offset_) { auto const steps{bend == 0.0 ? 1 : 96}; std::vector line; @@ -2505,7 +2506,7 @@ void plan_panel::render_template_window() // dziob, not the arc. from A on the blade lies on the arc and the line goes solid static ImU32 const part_colour[]{IM_COL32(150, 175, 210, 255), IM_COL32(120, 235, 255, 255), IM_COL32(240, 240, 240, 255), IM_COL32(255, 200, 110, 255)}; auto const hand{laid.frog.y >= 0.0 ? 1 : -1}; - auto const rail_line{[&](std::vector const &Points_, int const Side_) { + auto const rail_line{[&](std::vector const &Points_, int const Side_) { std::vector rail; rail.reserve(Points_.size()); for (std::size_t i = 0; i < Points_.size(); ++i) @@ -2526,8 +2527,8 @@ void plan_panel::render_template_window() // the sampling step is metres and the dziob is centimetres, so the two stretches have to part on // the exact distance rather than on whichever sample happens to fall nearest it - auto const cut_at{[](std::vector const &Points_, double const Distance_, - std::vector &Head_, std::vector &Tail_) { + auto const cut_at{[](std::vector const &Points_, double const Distance_, + std::vector &Head_, std::vector &Tail_) { auto travelled{0.0}; for (std::size_t i = 0; i < Points_.size(); ++i) { @@ -2542,7 +2543,7 @@ void plan_panel::render_template_window() { auto const &back{Points_[i - 1]}; auto const share{(Distance_ - (travelled - step)) / step}; - maj0sted::domain::geometry::XY const meeting{back.x + (Points_[i].x - back.x) * share, back.y + (Points_[i].y - back.y) * share}; + editor::plan::geometry::XY const meeting{back.x + (Points_[i].x - back.x) * share, back.y + (Points_[i].y - back.y) * share}; Head_.push_back(meeting); Tail_.push_back(meeting); } @@ -2550,7 +2551,7 @@ void plan_panel::render_template_window() } }}; - auto const draw_run{[&](std::vector const &Points_, ImU32 const Colour_, bool const Theoretical_) { + auto const draw_run{[&](std::vector const &Points_, ImU32 const Colour_, bool const Theoretical_) { if (Points_.size() < 2) { return; @@ -2603,11 +2604,11 @@ void plan_panel::render_template_window() auto const s{std::sin(segment.turn_in)}; walker = {walker.x, walker.y, walker.hx * c - walker.hy * s, walker.hx * s + walker.hy * c}; } - std::vector points; - walker = maj0sted::domain::geometry::layout_segment(segment.k0, segment.k1, segment.length, walker, &points); + std::vector points; + walker = editor::plan::geometry::layout_segment(segment.k0, segment.k1, segment.length, walker, &points); auto const from{station}; station += segment.length; - if (segment.part == maj0sted::domain::TurnoutPart::Blade) + if (segment.part == editor::plan::TurnoutPart::Blade) { heel = station; } @@ -2625,8 +2626,8 @@ void plan_panel::render_template_window() draw_run(points, colour, false); continue; } - std::vector ahead; - std::vector behind; + std::vector ahead; + std::vector behind; cut_at(points, upto, behind, ahead); draw_run(behind, colour, true); draw_run(ahead, colour, false); @@ -2680,7 +2681,7 @@ void plan_panel::render_template_window() // the construction points, from the very list the solver reports for a placement if (m_tpl_marks) { - auto marks{maj0sted::editor::turnout_marks(laid, start)}; + auto marks{editor::plan::turnout_marks(laid, start)}; std::sort(marks.begin(), marks.end(), [](auto const &Left_, auto const &Right_) { return Left_.station < Right_.station; }); auto level{0}; @@ -2820,8 +2821,8 @@ void plan_panel::render_turnouts() auto &placement{m_document.turnouts[i]}; ImGui::PushID(static_cast(1000 + i)); - auto const *solved{maj0sted::editor::find_turnout(m_solution, placement.id)}; - auto const *on{maj0sted::editor::find_track(m_document, placement.on)}; + auto const *solved{editor::plan::find_turnout(m_solution, placement.id)}; + auto const *on{editor::plan::find_track(m_document, placement.on)}; char label[200]; std::snprintf(label, sizeof(label), "%s na %s, km %.1f%s", placement.type.c_str(), on != nullptr ? on->name.c_str() : "?", placement.station, (solved != nullptr && solved->valid) ? "" : " (nie da sie zlozyc)"); @@ -2891,11 +2892,11 @@ void plan_panel::render_turnouts() // mean guessing kilometres by hand: the nearest element long enough to hold it, whole if (solved != nullptr && solved->valid) { - auto const *through{maj0sted::editor::find_track(m_solution, placement.on)}; + auto const *through{editor::plan::find_track(m_solution, placement.on)}; double curvature{0.0}; double behind{0.0}; double ahead{0.0}; - auto const room{through != nullptr && maj0sted::editor::steady_room(*through, placement.station, curvature, behind, ahead) + auto const room{through != nullptr && editor::plan::steady_room(*through, placement.station, curvature, behind, ahead) ? (placement.facing ? ahead : behind) : -1.0}; if (through != nullptr && room < solved->through_length - 1e-6) @@ -2975,7 +2976,7 @@ void plan_panel::render_diagnostics() auto const &diagnostic{m_solution.diagnostics[i]}; ImGui::PushID(static_cast(2000 + i)); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.60f, 0.55f, 1.0f)); - auto const *track{maj0sted::editor::find_track(m_document, diagnostic.track)}; + auto const *track{editor::plan::find_track(m_document, diagnostic.track)}; if (ImGui::Selectable(diagnostic.text.c_str())) { if (diagnostic.track != TrackId::none) @@ -3019,12 +3020,12 @@ void plan_panel::render_storage() m_document.georeferenced = Global.scenery_georeferenced; m_document.origin_x = Global.scenery_origin.x; m_document.origin_y = Global.scenery_origin.y; - m_status = maj0sted::io::save(m_document, m_path) ? "saved to " + std::string(m_path) : "could not write " + std::string(m_path); + m_status = editor::plan::io::save(m_document, m_path) ? "saved to " + std::string(m_path) : "could not write " + std::string(m_path); } ImGui::SameLine(); if (ImGui::Button("Load")) { - auto const loaded{maj0sted::io::load(m_path)}; + auto const loaded{editor::plan::io::load(m_path)}; if (loaded) { m_document = *loaded; @@ -3110,7 +3111,7 @@ void plan_panel::export_scn(bool const Run_) // where a plan exports to belongs to the plan: say it once and it is there the next time the // project is opened, whichever MaSzyna it was drawn for m_document.scn_path = m_scn_path; - maj0sted::io::ScnExportOptions opt; + editor::plan::io::ScnExportOptions opt; opt.origin_east = Global.scenery_origin.x; opt.origin_north = Global.scenery_origin.y; opt.trainset = m_scn_trainset; @@ -3120,7 +3121,7 @@ void plan_panel::export_scn(bool const Run_) m_status = "could not write " + std::string(m_scn_path); return; } - auto const result{maj0sted::io::export_scn(m_document, m_solution, opt, out)}; + auto const result{editor::plan::io::export_scn(m_document, m_solution, opt, out)}; out.flush(); if (false == out.good()) { diff --git a/application/planpanel.cppm b/application/planpanel.cppm index 482aaf88..5e6f5c45 100644 --- a/application/planpanel.cppm +++ b/application/planpanel.cppm @@ -8,16 +8,17 @@ http://mozilla.org/MPL/2.0/. */ module; #include +#include #include #include "imgui/imgui.h" -#include "maj0sted/editor/tile_cache.hpp" -#include "maj0sted/editor/layout.hpp" -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/render.hpp" -#include "maj0sted/editor/solution.hpp" -#include "maj0sted/io/scn_export.hpp" export module eu07.application.planpanel; +import eu07.editor.plan_tilecache; +import eu07.editor.plan_layout; +import eu07.editor.plan_model; +import eu07.editor.plan_render; +import eu07.editor.plan_solution; +import eu07.editor.plan_scn_export; import eu07.application.uilayer; import eu07.editor.orthophoto; @@ -25,7 +26,7 @@ export { // track layout tool. the drawing happens in the viewport, which the tool puts into a top-down // orthographic plan view; the panel holds only the controls. none of the geometry is computed here: -// maj0sted solves the whole document and the panel paints what comes back. +// the plan library solves the whole document and the panel paints what comes back. // // a track is a chain of elements, and every one of them says outright what it is: prosta of so many // metres, luk of radius R turning so far, krzywa przejsciowa easing to R over so many metres. there @@ -45,13 +46,13 @@ class plan_panel : public ui_panel void render_contents() override; private: - using Document = maj0sted::editor::Document; - using Element = maj0sted::editor::Element; - using ElementId = maj0sted::editor::ElementId; - using Solution = maj0sted::editor::Solution; - using Track = maj0sted::editor::Track; - using TrackId = maj0sted::editor::TrackId; - using TurnoutId = maj0sted::editor::TurnoutId; + using Document = editor::plan::Document; + using Element = editor::plan::Element; + using ElementId = editor::plan::ElementId; + using Solution = editor::plan::Solution; + using Track = editor::plan::Track; + using TrackId = editor::plan::TrackId; + using TurnoutId = editor::plan::TurnoutId; // panels void render_toolbar(); @@ -60,7 +61,7 @@ class plan_panel : public ui_panel // joining two tracks into one: the radius a join may bend at, and the button that starts // pointing at the ends to join. everything else about it happens on the map void render_join(); - void render_turnout_type(maj0sted::editor::TurnoutType &Type_); + void render_turnout_type(editor::plan::TurnoutType &Type_); // the catalogue drawing of the chosen type, in its own window: the diverging path piece by // piece, both tracks' rails, and the points a drawing is dimensioned from void render_template_window(); @@ -94,7 +95,7 @@ class plan_panel : public ui_panel // taken off the straight before it - which leaves the track ending on the click before void drop_last_vertex(); // appends one element to the end of the current track, exactly as asked for - void append_element(maj0sted::editor::Kind const Kind); + void append_element(editor::plan::Kind const Kind); void drop_last_element(); void delete_selected_element(); void place_turnout_at(TrackId const On, double const Wx, double const Wy); @@ -117,10 +118,10 @@ class plan_panel : public ui_panel bool hit_track_end(ImVec2 const &Mouse, float const Tolerance, TrackId &OutTrack, int &OutEnd) const; // whether that end is loose at all: one that already stands on another track's end is joined // to it, and there is nothing to join twice - bool loose_end(maj0sted::editor::SolvedTrack const &Track_, int const End_) const; + bool loose_end(editor::plan::SolvedTrack const &Track_, int const End_) const; // how an end reads for a join laid out of it or into it: one facing the wrong way for that // is taken backwards, which is what turning the track round would do to it anyway - static maj0sted::domain::geometry::Pose join_pose(maj0sted::editor::SolvedTrack const &Track_, int const End_, bool const Leaving_); + static editor::plan::geometry::Pose join_pose(editor::plan::SolvedTrack const &Track_, int const End_, bool const Leaving_); // lays the join and leaves one track, saying what it cost void join_ends(TrackId const A, int const Aend, TrackId const B, int const Bend); // nearest station along a solved track's axis, for placing and sliding turnouts @@ -130,7 +131,7 @@ class plan_panel : public ui_panel // members Document m_document; Solution m_solution; - std::vector m_rails; + std::vector m_rails; TrackId m_track{}; ElementId m_sel_element{}; @@ -210,10 +211,10 @@ class plan_panel : public ui_panel double m_mapviewy{0.0}; double m_mapscale{0.0}; - editor::wms_image m_topomap{maj0sted::editor::WmsConfig::geoportal_topo()}; + editor::wms_image m_topomap{editor::plan::WmsConfig::geoportal_topo()}; editor::orthophoto_source m_ortho; // 1 km topo cells for views wider than a kilometre (orto's 100 m grid is too dense there) - editor::orthophoto_source m_topo{maj0sted::editor::WmsConfig::geoportal_topo(), 1000, "topo"}; + editor::orthophoto_source m_topo{editor::plan::WmsConfig::geoportal_topo(), 1000, "topo"}; bool m_showortho{true}; }; diff --git a/editor/orthophoto.cpp b/editor/orthophoto.cpp index 27fbf210..f4e650e2 100644 --- a/editor/orthophoto.cpp +++ b/editor/orthophoto.cpp @@ -14,7 +14,6 @@ module; #include #include #include -#include "maj0sted/editor/tile_cache.hpp" #include #include "stb/stb_image.h" #ifdef _WIN32 @@ -26,6 +25,7 @@ module; #endif module eu07.editor.orthophoto; +import eu07.editor.plan_tilecache; import eu07.utilities.logs; /* @@ -209,9 +209,9 @@ bool http_get(std::string const &Url, std::vector &Bytes, std::str } // namespace -orthophoto_source::orthophoto_source(maj0sted::editor::WmsConfig Config, int const Gridzoom, std::string Cachesubdir) +orthophoto_source::orthophoto_source(editor::plan::WmsConfig Config, int const Gridzoom, std::string Cachesubdir) : m_service([&] { - if (Gridzoom >= maj0sted::editor::TileGrid::kCellZoomMin) + if (Gridzoom >= editor::plan::TileGrid::kCellZoomMin) { Config.tile_pixels = 512; // coarse cells do not need orto's 1024 px } @@ -221,7 +221,7 @@ orthophoto_source::orthophoto_source(maj0sted::editor::WmsConfig Config, int con { // the library asks for a URL and expects the answer whenever it arrives; the transfer is queued // here and handed back on the thread that drains it, so the service stays single threaded - m_service.set_fetcher([this](std::string const &Url, maj0sted::editor::TileService::DoneFn Done) { + m_service.set_fetcher([this](std::string const &Url, editor::plan::TileService::DoneFn Done) { { std::lock_guard lock(m_mutex); m_queued.push_back({Url, std::move(Done), false, {}, {}}); @@ -291,7 +291,7 @@ void orthophoto_source::worker() } } -std::vector orthophoto_source::collect(maj0sted::editor::TileBBox const &View, int const Maxtiles) +std::vector orthophoto_source::collect(editor::plan::TileBBox const &View, int const Maxtiles) { // hand finished transfers to the library here, on the caller's thread std::deque arrived; @@ -311,7 +311,7 @@ std::vector orthophoto_source::collect(maj0sted:: // fetch only what fits the budget for the current view. the window is recentred when the // view is larger than the cap, and zoom-to-cursor moves the camera, so the set of keys asked // for changes from frame to frame - that must not decide what is drawn - for (auto const &key : maj0sted::editor::TileGrid::tiles_for_view(View, m_gridzoom, Maxtiles)) + for (auto const &key : editor::plan::TileGrid::tiles_for_view(View, m_gridzoom, Maxtiles)) { // a tile kept from an earlier session seeds the cache, so no request goes out for it at all if (false == m_service.has(key)) @@ -320,13 +320,13 @@ std::vector orthophoto_source::collect(maj0sted:: } auto const status = m_service.request(key); - if (status == maj0sted::editor::TileStatus::Failed) + if (status == editor::plan::TileStatus::Failed) { // counted once per tile, not once per frame it stays unavailable m_failedkeys.insert(key); continue; } - if (status != maj0sted::editor::TileStatus::Ready) + if (status != editor::plan::TileStatus::Ready) { continue; } @@ -342,7 +342,7 @@ std::vector orthophoto_source::collect(maj0sted:: // draw every texture we already hold that still covers the view. returning only the fetch // window made tiles blink out during zoom as soon as they fell outside the cap, then blink // back in once the window moved over them again - auto const overlaps = [](maj0sted::editor::TileBBox const &Left, maj0sted::editor::TileBBox const &Right) { + auto const overlaps = [](editor::plan::TileBBox const &Left, editor::plan::TileBBox const &Right) { return Left.min_x < Right.max_x && Left.max_x > Right.min_x && Left.min_y < Right.max_y && Left.max_y > Right.min_y; }; @@ -354,7 +354,7 @@ std::vector orthophoto_source::collect(maj0sted:: { continue; } - auto const box = maj0sted::editor::TileGrid::bbox(key); + auto const box = editor::plan::TileGrid::bbox(key); if (overlaps(box, View)) { tiles.push_back({box, texture}); @@ -364,7 +364,7 @@ std::vector orthophoto_source::collect(maj0sted:: return tiles; } -unsigned int orthophoto_source::upload(maj0sted::editor::TileKey const &Key) +unsigned int orthophoto_source::upload(editor::plan::TileKey const &Key) { auto const *image = m_service.peek(Key); if (image == nullptr || image->bytes.empty()) @@ -397,12 +397,12 @@ unsigned int orthophoto_source::upload(maj0sted::editor::TileKey const &Key) return texture; } -std::string orthophoto_source::tile_path(maj0sted::editor::TileKey const &Key) const +std::string orthophoto_source::tile_path(editor::plan::TileKey const &Key) const { return "editor/cache/" + m_cachesubdir + "/" + std::to_string(Key.zoom) + "_" + std::to_string(Key.x) + "_" + std::to_string(Key.y) + ".img"; } -bool orthophoto_source::load_from_disk(maj0sted::editor::TileKey const &Key) +bool orthophoto_source::load_from_disk(editor::plan::TileKey const &Key) { std::ifstream file(tile_path(Key), std::ios::binary); if (false == file.is_open()) @@ -421,7 +421,7 @@ bool orthophoto_source::load_from_disk(maj0sted::editor::TileKey const &Key) return true; } -void orthophoto_source::save_to_disk(maj0sted::editor::TileKey const &Key) +void orthophoto_source::save_to_disk(editor::plan::TileKey const &Key) { auto const *image = m_service.peek(Key); if (image == nullptr || image->bytes.empty()) @@ -484,7 +484,7 @@ unsigned int upload_image(std::vector const &Bytes) return texture; } -bool same_box(maj0sted::editor::TileBBox const &Left, maj0sted::editor::TileBBox const &Right) +bool same_box(editor::plan::TileBBox const &Left, editor::plan::TileBBox const &Right) { auto const close = [](double const A, double const B) { return std::abs(A - B) < 1.0; }; return close(Left.min_x, Right.min_x) && close(Left.min_y, Right.min_y) && close(Left.max_x, Right.max_x) && close(Left.max_y, Right.max_y); @@ -492,7 +492,7 @@ bool same_box(maj0sted::editor::TileBBox const &Left, maj0sted::editor::TileBBox } // namespace -wms_image::wms_image(maj0sted::editor::WmsConfig Config) : m_config(std::move(Config)) +wms_image::wms_image(editor::plan::WmsConfig Config) : m_config(std::move(Config)) { m_worker = std::thread([this]() { worker(); }); } @@ -547,7 +547,7 @@ void wms_image::worker() } } -unsigned int wms_image::texture_for(maj0sted::editor::TileBBox const &Box, int const Pixels) +unsigned int wms_image::texture_for(editor::plan::TileBBox const &Box, int const Pixels) { // a finished download becomes the texture on this thread, where the graphics API is safe to touch { @@ -583,7 +583,7 @@ unsigned int wms_image::texture_for(maj0sted::editor::TileBBox const &Box, int c config.tile_pixels = Pixels; { std::lock_guard lock(m_mutex); - m_url = maj0sted::editor::wms_getmap_url(config, Box); + m_url = editor::plan::wms_getmap_url(config, Box); m_haswork = true; } m_loading = true; diff --git a/editor/orthophoto.cppm b/editor/orthophoto.cppm index 31e9b70f..7eccd37a 100644 --- a/editor/orthophoto.cppm +++ b/editor/orthophoto.cppm @@ -17,9 +17,9 @@ module; #include #include #include -#include "maj0sted/editor/tile_cache.hpp" export module eu07.editor.orthophoto; +import eu07.editor.plan_tilecache; export { @@ -39,13 +39,13 @@ class orthophoto_source public: struct ready_tile { - maj0sted::editor::TileBBox box; + editor::plan::TileBBox box; unsigned int texture{0}; }; // default: Geoportal ortophoto on the fine 100 m grid. pass topo config and a coarse // grid zoom (e.g. 1000) for the zoomed-out topographic underlay - explicit orthophoto_source(maj0sted::editor::WmsConfig Config = maj0sted::editor::WmsConfig::geoportal_ortho(), int const Gridzoom = maj0sted::editor::TileGrid::kLevel, + explicit orthophoto_source(editor::plan::WmsConfig Config = editor::plan::WmsConfig::geoportal_ortho(), int const Gridzoom = editor::plan::TileGrid::kLevel, std::string Cachesubdir = "orto"); ~orthophoto_source(); orthophoto_source(orthophoto_source const &) = delete; @@ -54,7 +54,7 @@ class orthophoto_source // kicks off fetches for the view (capped) and returns every already-uploaded tile that still // intersects it - including ones outside the fetch window, so a zoom cannot blink them away. // tiles still on their way simply aren't in the answer yet; call again next frame - std::vector collect(maj0sted::editor::TileBBox const &View, int const Maxtiles = 400); + std::vector collect(editor::plan::TileBBox const &View, int const Maxtiles = 400); // how many tiles are still being fetched, for the panel to report std::size_t pending() const; // how many tiles gave up after exhausting their retries @@ -65,7 +65,7 @@ class orthophoto_source struct transfer { std::string url; - maj0sted::editor::TileService::DoneFn done; + editor::plan::TileService::DoneFn done; bool ok{false}; std::vector bytes; std::string content_type; @@ -73,17 +73,17 @@ class orthophoto_source // methods void worker(); // decodes the cached bytes of a tile and uploads them; returns 0 when the image is unusable - unsigned int upload(maj0sted::editor::TileKey const &Key); + unsigned int upload(editor::plan::TileKey const &Key); // imagery of a given piece of ground never changes, so a fetched tile is kept on disk and the // next session starts with it instead of going back to a service that is slow and flaky - std::string tile_path(maj0sted::editor::TileKey const &Key) const; - bool load_from_disk(maj0sted::editor::TileKey const &Key); - void save_to_disk(maj0sted::editor::TileKey const &Key); + std::string tile_path(editor::plan::TileKey const &Key) const; + bool load_from_disk(editor::plan::TileKey const &Key); + void save_to_disk(editor::plan::TileKey const &Key); // members - maj0sted::editor::TileService m_service; - int m_gridzoom{maj0sted::editor::TileGrid::kLevel}; + editor::plan::TileService m_service; + int m_gridzoom{editor::plan::TileGrid::kLevel}; std::string m_cachesubdir{"orto"}; - std::unordered_map m_textures; + std::unordered_map m_textures; mutable std::mutex m_mutex; std::condition_variable m_wakeup; @@ -92,7 +92,7 @@ class orthophoto_source std::vector m_workers; std::atomic m_quitting{false}; std::atomic m_inflight{0}; - std::unordered_set m_failedkeys; + std::unordered_set m_failedkeys; }; // a single WMS image covering an arbitrary box, for views too coarse for the tile grid - the whole @@ -102,25 +102,25 @@ class wms_image { public: - explicit wms_image(maj0sted::editor::WmsConfig Config); + explicit wms_image(editor::plan::WmsConfig Config); ~wms_image(); wms_image(wms_image const &) = delete; wms_image &operator=(wms_image const &) = delete; // asks for the given box at the given size and returns the texture currently available, which // may still be the previous box's until the new one arrives; 0 when there is nothing to show yet - unsigned int texture_for(maj0sted::editor::TileBBox const &Box, int const Pixels); + unsigned int texture_for(editor::plan::TileBBox const &Box, int const Pixels); // the box the returned texture actually covers - maj0sted::editor::TileBBox const &covered() const { return m_covered; } + editor::plan::TileBBox const &covered() const { return m_covered; } bool loading() const { return m_loading.load(); } private: void worker(); - maj0sted::editor::WmsConfig m_config; - maj0sted::editor::TileBBox m_requested{}; - maj0sted::editor::TileBBox m_inflightbox{}; - maj0sted::editor::TileBBox m_covered{}; + editor::plan::WmsConfig m_config; + editor::plan::TileBBox m_requested{}; + editor::plan::TileBBox m_inflightbox{}; + editor::plan::TileBBox m_covered{}; unsigned int m_texture{0}; mutable std::mutex m_mutex; diff --git a/maj0sted/src/editor/chain.cpp b/editor/plan_chain.cpp similarity index 91% rename from maj0sted/src/editor/chain.cpp rename to editor/plan_chain.cpp index f6f1da36..841ac89f 100644 --- a/maj0sted/src/editor/chain.cpp +++ b/editor/plan_chain.cpp @@ -1,16 +1,25 @@ -#include "maj0sted/editor/chain.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include #include -namespace maj0sted::editor { +module eu07.editor.plan_chain; + +namespace editor::plan { namespace { constexpr double kEps = 1e-9; -using domain::geometry::Pose; +using geometry::Pose; Diagnostic make(Code code, TrackId track, ElementId element, std::string text) { Diagnostic diagnostic; @@ -113,8 +122,8 @@ TrackOutcome lay_track(const Document& /*document*/, const Track& track, const P solved.k1 = k1; solved.length = element.length; - std::vector points; - walker = domain::geometry::layout_segment(k0, k1, element.length, walker, &points); + std::vector points; + walker = geometry::layout_segment(k0, k1, element.length, walker, &points); solved.end = walker; solved.points.reserve(points.size()); for (const auto& point : points) { @@ -138,4 +147,4 @@ TrackOutcome lay_track(const Document& /*document*/, const Track& track, const P return out; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/chain.hpp b/editor/plan_chain.cppm similarity index 62% rename from maj0sted/include/maj0sted/editor/chain.hpp rename to editor/plan_chain.cppm index c75ee9fc..5a1995de 100644 --- a/maj0sted/include/maj0sted/editor/chain.hpp +++ b/editor/plan_chain.cppm @@ -1,12 +1,22 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include -#include "maj0sted/domain/geometry/segment_layout.hpp" -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" +export module eu07.editor.plan_chain; +export import eu07.editor.plan_segment; +export import eu07.editor.plan_model; +export import eu07.editor.plan_solution; -namespace maj0sted::editor { +export { + +namespace editor::plan { /// What laying one track produced, and everything that went wrong doing it. struct TrackOutcome { @@ -26,6 +36,8 @@ struct TrackOutcome { /// ends the chain there; everything before it is still returned and still /// drawable. [[nodiscard]] TrackOutcome lay_track(const Document& document, const Track& track, - const domain::geometry::Pose& start); + const geometry::Pose& start); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/io/document_io.cpp b/editor/plan_document_io.cpp similarity index 98% rename from maj0sted/src/io/document_io.cpp rename to editor/plan_document_io.cpp index 4b907f6a..cf38abf4 100644 --- a/maj0sted/src/io/document_io.cpp +++ b/editor/plan_document_io.cpp @@ -1,5 +1,15 @@ -#include "maj0sted/io/document_io.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include +#include #include #include #include @@ -9,10 +19,12 @@ #include #include -namespace maj0sted::io { +module eu07.editor.plan_document_io; + +namespace editor::plan::io { namespace { -using namespace maj0sted::editor; +using namespace editor::plan; constexpr int kVersion = 7; constexpr int kNoExportPath = 6; // before a plan remembered where it exports to @@ -553,4 +565,4 @@ std::optional load(const std::string& path) { return deserialize(buffer.str()); } -} // namespace maj0sted::io +} // namespace editor::plan::io diff --git a/maj0sted/include/maj0sted/io/document_io.hpp b/editor/plan_document_io.cppm similarity index 55% rename from maj0sted/include/maj0sted/io/document_io.hpp rename to editor/plan_document_io.cppm index c311cdae..f95bc5f4 100644 --- a/maj0sted/include/maj0sted/io/document_io.hpp +++ b/editor/plan_document_io.cppm @@ -1,11 +1,21 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include -#include "maj0sted/editor/model.hpp" +export module eu07.editor.plan_document_io; +export import eu07.editor.plan_model; -namespace maj0sted::io { +export { + +namespace editor::plan::io { /// The `.m0s` format, version 3. /// @@ -18,14 +28,16 @@ namespace maj0sted::io { /// /// Doubles go through std::to_chars/from_chars, so a round trip is exact and /// does not depend on the locale. -[[nodiscard]] std::string serialize(const editor::Document& document); +[[nodiscard]] std::string serialize(const plan::Document& document); /// Returns nothing when @p text is not a version 3 document or is malformed. -[[nodiscard]] std::optional deserialize(const std::string& text); +[[nodiscard]] std::optional deserialize(const std::string& text); [[nodiscard]] std::string default_project_path(); -bool save(const editor::Document& document, const std::string& path = default_project_path()); -[[nodiscard]] std::optional load( +bool save(const plan::Document& document, const std::string& path = default_project_path()); +[[nodiscard]] std::optional load( const std::string& path = default_project_path()); -} // namespace maj0sted::io +} // namespace editor::plan::io + +} // export diff --git a/maj0sted/src/editor/join.cpp b/editor/plan_join.cpp similarity index 72% rename from maj0sted/src/editor/join.cpp rename to editor/plan_join.cpp index 16b38855..d73b5f2a 100644 --- a/maj0sted/src/editor/join.cpp +++ b/editor/plan_join.cpp @@ -1,8 +1,21 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include + +module eu07.editor.plan_join; + // TYMCZASOWA ZASLEPKA - patrz komentarz w join.hpp. -#include "maj0sted/editor/join.hpp" -namespace maj0sted::editor { +namespace editor::plan { namespace { constexpr const char* kMissing = "scalanie koncow niedostepne: brak modulu join"; @@ -24,7 +37,7 @@ const char* join_kind_name(JoinKind kind) { return "nic"; } -JoinPlan plan_join(const domain::geometry::Pose& leaving, const domain::geometry::Pose& arriving, +JoinPlan plan_join(const geometry::Pose& leaving, const geometry::Pose& arriving, const JoinSettings& settings) { (void)leaving; (void)arriving; @@ -48,4 +61,4 @@ JoinReport join_ends(Document& document, const Solution& solution, TrackId a, in return report; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/join.hpp b/editor/plan_join.cppm similarity index 72% rename from maj0sted/include/maj0sted/editor/join.hpp rename to editor/plan_join.cppm index 72fe2500..0f2275ff 100644 --- a/maj0sted/include/maj0sted/editor/join.hpp +++ b/editor/plan_join.cppm @@ -1,4 +1,21 @@ -#pragma once +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include + +export module eu07.editor.plan_join; +export import eu07.editor.plan_segment; +export import eu07.editor.plan_model; +export import eu07.editor.plan_solution; + +export { // TYMCZASOWA ZASLEPKA. Modul scalania koncow (plan_join / join_ends) nie zostal nigdy // zacommitowany: commit 4ddfeb02 dopisal `src/editor/join.cpp` do CMakeLists i `#include` w @@ -7,14 +24,9 @@ // API, ktorego uzywa panel planu, i mowi "niedostepne" - zeby reszta edytora dala sie uruchomic. // Do zastapienia prawdziwym rozwiazaniem geometrii (luk-prosta-luk) i chirurgia dokumentu. -#include -#include -#include "maj0sted/domain/geometry/segment_layout.hpp" // Pose -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" -namespace maj0sted::editor { +namespace editor::plan { /// Co stanelo miedzy dwoma koncami. enum class JoinKind { @@ -41,8 +53,8 @@ struct JoinPlan { double tightest{0.0}; }; -[[nodiscard]] JoinPlan plan_join(const domain::geometry::Pose& leaving, - const domain::geometry::Pose& arriving, +[[nodiscard]] JoinPlan plan_join(const geometry::Pose& leaving, + const geometry::Pose& arriving, const JoinSettings& settings); /// Co scalenie kosztowalo. @@ -58,4 +70,6 @@ struct JoinReport { [[nodiscard]] JoinReport join_ends(Document& document, const Solution& solution, TrackId a, int a_end, TrackId b, int b_end, const JoinSettings& settings); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/editor/layout.cpp b/editor/plan_layout.cpp similarity index 93% rename from maj0sted/src/editor/layout.cpp rename to editor/plan_layout.cpp index 34249647..88b3ac15 100644 --- a/maj0sted/src/editor/layout.cpp +++ b/editor/plan_layout.cpp @@ -1,5 +1,13 @@ -#include "maj0sted/editor/layout.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include #include #include #include @@ -8,16 +16,17 @@ #include #include -#include "maj0sted/domain/geometry/turnout.hpp" -#include "maj0sted/editor/chain.hpp" -#include "maj0sted/editor/sketch.hpp" +module eu07.editor.plan_layout; +import eu07.editor.plan_turnout_geometry; +import eu07.editor.plan_chain; +import eu07.editor.plan_sketch; -namespace maj0sted::editor { +namespace editor::plan { namespace { constexpr double kEps = 1e-9; -using domain::geometry::Pose; +using geometry::Pose; std::string num(double value, int decimals = 1) { char buffer[64]; @@ -180,21 +189,21 @@ Pose rigid_move(const Pose& anchor, const Pose& from, const Pose& to) { // Turnouts // --------------------------------------------------------------------------- -domain::TurnoutPart part_of(int part) { +plan::TurnoutPart part_of(int part) { switch (part) { - case 0: return domain::TurnoutPart::PreBlade; - case 1: return domain::TurnoutPart::Blade; - case 3: return domain::TurnoutPart::FrogRail; - default: return domain::TurnoutPart::Curve; + case 0: return plan::TurnoutPart::PreBlade; + case 1: return plan::TurnoutPart::Blade; + case 3: return plan::TurnoutPart::FrogRail; + default: return plan::TurnoutPart::Curve; } } -int mark_kind_for(domain::TurnoutPart part) { +int mark_kind_for(plan::TurnoutPart part) { switch (part) { - case domain::TurnoutPart::PreBlade: return 0; // PR - case domain::TurnoutPart::Blade: return 1; // ostrze iglicy - case domain::TurnoutPart::Curve: return 2; // pięta iglicy - case domain::TurnoutPart::FrogRail: return 4; // koniec krzywej + case plan::TurnoutPart::PreBlade: return 0; // PR + case plan::TurnoutPart::Blade: return 1; // ostrze iglicy + case plan::TurnoutPart::Curve: return 2; // pięta iglicy + case plan::TurnoutPart::FrogRail: return 4; // koniec krzywej } return 3; } @@ -203,25 +212,25 @@ int mark_kind_for(domain::TurnoutPart part) { // --------------------------------------------------------------------------- -domain::Turnout to_domain(const TurnoutType& type, int hand) { - domain::Turnout turnout{ - domain::CrossingMark{type.crossing_n}, - hand >= 0 ? domain::DivergeSide::Left : domain::DivergeSide::Right, +plan::Turnout to_domain(const TurnoutType& type, int hand) { + plan::Turnout turnout{ + plan::CrossingMark{type.crossing_n}, + hand >= 0 ? plan::DivergeSide::Left : plan::DivergeSide::Right, {}, type.length, - domain::Blade{type.blade.tip_thickness, type.blade.nose, type.blade.railtop_width}, + plan::Blade{type.blade.tip_thickness, type.blade.nose, type.blade.railtop_width}, }; turnout.path.reserve(type.pieces.size()); for (const auto& piece : type.pieces) { - turnout.path.push_back(domain::TurnoutPiece{part_of(piece.part), piece.length, + turnout.path.push_back(plan::TurnoutPiece{part_of(piece.part), piece.length, piece.radius_start, piece.radius_end, piece.turn_in}); } return turnout; } -std::vector turnout_marks(const domain::TurnoutGeometry& geometry, - const domain::geometry::Pose& start) { +std::vector turnout_marks(const plan::TurnoutGeometry& geometry, + const geometry::Pose& start) { std::vector marks; if (!geometry.valid) { return marks; @@ -230,27 +239,27 @@ std::vector turnout_marks(const domain::TurnoutGeometry& geometry, // PR stands whatever the path starts with, so it is said once here marks.push_back(TurnoutMark{start.x, start.y, 0, 0.0}); - domain::geometry::Pose walker = start; + geometry::Pose walker = start; double station = 0.0; - domain::TurnoutPart previous = domain::TurnoutPart::PreBlade; + plan::TurnoutPart previous = plan::TurnoutPart::PreBlade; bool first = true; for (const auto& segment : geometry.path) { if (std::abs(segment.turn_in) > kEps) { const double cos_t = std::cos(segment.turn_in); const double sin_t = std::sin(segment.turn_in); - walker = domain::geometry::Pose{walker.x, walker.y, + walker = geometry::Pose{walker.x, walker.y, walker.hx * cos_t - walker.hy * sin_t, walker.hx * sin_t + walker.hy * cos_t}; } if ((first || segment.part != previous) && - !(first && segment.part == domain::TurnoutPart::PreBlade)) { + !(first && segment.part == plan::TurnoutPart::PreBlade)) { marks.push_back( TurnoutMark{walker.x, walker.y, mark_kind_for(segment.part), station}); } previous = segment.part; first = false; - walker = domain::geometry::layout_segment(segment.k0, segment.k1, segment.length, + walker = geometry::layout_segment(segment.k0, segment.k1, segment.length, walker, nullptr); station += segment.length; } @@ -409,8 +418,8 @@ Solution solve(const Document& document) { bend = -bend; } - const domain::TurnoutGeometry geometry = - domain::lay_turnout(at, to_domain(*type, placement.hand), bend); + const plan::TurnoutGeometry geometry = + plan::lay_turnout(at, to_domain(*type, placement.hand), bend); if (!geometry.valid) { Diagnostic diagnostic; diagnostic.code = Code::TurnoutInvalid; @@ -491,8 +500,8 @@ Solution solve(const Document& document) { out_segment.k0 = segment.k0; out_segment.k1 = segment.k1; out_segment.length = segment.length; - std::vector points; - walker = domain::geometry::layout_segment(segment.k0, segment.k1, + std::vector points; + walker = geometry::layout_segment(segment.k0, segment.k1, segment.length, walker, &points); out_segment.part = segment.part; @@ -703,4 +712,4 @@ Solution solve(const Document& document) { return solution; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/layout.hpp b/editor/plan_layout.cppm similarity index 67% rename from maj0sted/include/maj0sted/editor/layout.hpp rename to editor/plan_layout.cppm index 945f3416..a5f3112a 100644 --- a/maj0sted/include/maj0sted/editor/layout.hpp +++ b/editor/plan_layout.cppm @@ -1,10 +1,23 @@ -#pragma once +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include -#include "maj0sted/domain/geometry/turnout.hpp" -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" +export module eu07.editor.plan_layout; +export import eu07.editor.plan_turnout_geometry; +export import eu07.editor.plan_model; +export import eu07.editor.plan_solution; -namespace maj0sted::editor { +export { + +namespace editor::plan { /// Solves a whole document: lays every turnout on its through track, lays every /// track from its anchor, and moves the tracks that are held parallel to another @@ -24,14 +37,16 @@ namespace maj0sted::editor { /// curvatures signed for @p hand (+1 diverges left). Public because the editor /// dimensions a *type* with it — laying one from an identity pose is how the /// catalogue numbers are checked before any instance stands on a track. -[[nodiscard]] domain::Turnout to_domain(const TurnoutType& type, int hand); +[[nodiscard]] plan::Turnout to_domain(const TurnoutType& type, int hand); /// The construction points of a turnout laid from @p start: where its parts meet, /// where its blade is dimensioned, and the points the drawing takes its lengths /// between. Public for the same reason as to_domain — so a bare type is drawn from /// the very same list the solver reports for a placement, rather than from a second /// idea of what a construction point is. -[[nodiscard]] std::vector turnout_marks(const domain::TurnoutGeometry& geometry, - const domain::geometry::Pose& start); +[[nodiscard]] std::vector turnout_marks(const plan::TurnoutGeometry& geometry, + const geometry::Pose& start); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/editor/model.cpp b/editor/plan_model.cpp similarity index 84% rename from maj0sted/src/editor/model.cpp rename to editor/plan_model.cpp index 8550237e..09fd1a40 100644 --- a/maj0sted/src/editor/model.cpp +++ b/editor/plan_model.cpp @@ -1,6 +1,20 @@ -#include "maj0sted/editor/model.hpp" +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include +#include +#include -namespace maj0sted::editor { +module eu07.editor.plan_model; + +namespace editor::plan { namespace { template @@ -71,4 +85,4 @@ const Track* find_element_track(const Document& document, ElementId id) { return nullptr; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/model.hpp b/editor/plan_model.cppm similarity index 95% rename from maj0sted/include/maj0sted/editor/model.hpp rename to editor/plan_model.cppm index 4ff40db5..56579a19 100644 --- a/maj0sted/include/maj0sted/editor/model.hpp +++ b/editor/plan_model.cppm @@ -1,11 +1,22 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include #include -namespace maj0sted::editor { +export module eu07.editor.plan_model; + +export { + +namespace editor::plan { // --------------------------------------------------------------------------- // Identity @@ -129,7 +140,7 @@ struct Track { // --------------------------------------------------------------------------- /// One piece of a catalogue turnout's diverging path. Mirrors -/// domain::TurnoutPiece; kept here so the document does not depend on the +/// plan::TurnoutPiece; kept here so the document does not depend on the /// geometry header. struct TurnoutPieceSpec { int part{2}; ///< 0 przediglicowy, 1 iglica, 2 łuk, 3 krzyżownicowa @@ -139,7 +150,7 @@ struct TurnoutPieceSpec { double turn_in{0.0}; ///< kąt nagięcia iglicy, radians, unsigned }; -/// The blade's own dimensions, which place its cut tip. Mirrors domain::Blade. +/// The blade's own dimensions, which place its cut tip. Mirrors plan::Blade. struct BladeSpec { double tip_thickness{0.0}; ///< u: width where the planed nose ends double nose{0.0}; ///< d: the planed nose, from the tip to that point @@ -219,4 +230,6 @@ struct Document { [[nodiscard]] const Element* find_element(const Document& document, ElementId id); [[nodiscard]] const Track* find_element_track(const Document& document, ElementId id); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/render/rail_renderer.cpp b/editor/plan_rail_renderer.cpp similarity index 84% rename from maj0sted/src/render/rail_renderer.cpp rename to editor/plan_rail_renderer.cpp index 7cf5e619..acd9f5eb 100644 --- a/maj0sted/src/render/rail_renderer.cpp +++ b/editor/plan_rail_renderer.cpp @@ -1,10 +1,21 @@ -#include "maj0sted/render/rail_renderer.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include #include #include #include -namespace maj0sted::render { +module eu07.editor.plan_rail_renderer; + +namespace editor::plan::render { namespace { @@ -57,4 +68,4 @@ void RailRenderer::add(const CentrelineElement& element) { } } -} // namespace maj0sted::render +} // namespace editor::plan::render diff --git a/maj0sted/include/maj0sted/render/rail_renderer.hpp b/editor/plan_rail_renderer.cppm similarity index 74% rename from maj0sted/include/maj0sted/render/rail_renderer.hpp rename to editor/plan_rail_renderer.cppm index 93125718..ee4561ea 100644 --- a/maj0sted/include/maj0sted/render/rail_renderer.hpp +++ b/editor/plan_rail_renderer.cppm @@ -1,11 +1,21 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include -#include "maj0sted/render/track_renderer.hpp" +export module eu07.editor.plan_rail_renderer; +export import eu07.editor.plan_track_renderer; -namespace maj0sted::render { +export { + +namespace editor::plan::render { /// A drawable polyline produced by RailRenderer: one rail, carrying the logical /// metadata of the centreline element it came from so the host can colour and @@ -40,4 +50,6 @@ private: std::vector rails_; }; -} // namespace maj0sted::render +} // namespace editor::plan::render + +} // export diff --git a/maj0sted/src/editor/render.cpp b/editor/plan_render.cpp similarity index 92% rename from maj0sted/src/editor/render.cpp rename to editor/plan_render.cpp index 58bf6c27..5e857e3e 100644 --- a/maj0sted/src/editor/render.cpp +++ b/editor/plan_render.cpp @@ -1,11 +1,21 @@ -#include "maj0sted/editor/render.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include #include +#include #include -#include "maj0sted/render/rail_renderer.hpp" +module eu07.editor.plan_render; +import eu07.editor.plan_rail_renderer; -namespace maj0sted::editor { +namespace editor::plan { namespace { render::ElementKind kind_of(Kind kind) { @@ -119,4 +129,4 @@ std::vector render_rails(const Solution& solution, double gauge_me return out; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/render.hpp b/editor/plan_render.cppm similarity index 76% rename from maj0sted/include/maj0sted/editor/render.hpp rename to editor/plan_render.cppm index 539ccb24..8a2c03b3 100644 --- a/maj0sted/include/maj0sted/editor/render.hpp +++ b/editor/plan_render.cppm @@ -1,10 +1,20 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include -#include "maj0sted/editor/solution.hpp" +export module eu07.editor.plan_render; +export import eu07.editor.plan_solution; -namespace maj0sted::editor { +export { + +namespace editor::plan { /// One drawable rail, tagged with what it came from so the host can colour it /// and hit-test it. Exactly one of @c element / @c turnout is set. @@ -32,4 +42,6 @@ struct PlanPolyline { [[nodiscard]] std::vector render_rails(const Solution& solution, double gauge_metres = 1.5); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/editor/plan_scene.cppm b/editor/plan_scene.cppm new file mode 100644 index 00000000..e3f4fbcb --- /dev/null +++ b/editor/plan_scene.cppm @@ -0,0 +1,26 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +export module eu07.editor.plan_scene; + +export { + +namespace editor::plan::render { + +/// A point in the project's CRS (metres for EPSG:2180). +struct Point { + double x; + double y; +}; + +/// Which kind of plan element a polyline came from (lets a GUI colour it). +enum class ElementKind { Straight, Arc, Transition }; + +} // namespace editor::plan::render + +} // export diff --git a/maj0sted/src/io/scn_export.cpp b/editor/plan_scn_export.cpp similarity index 97% rename from maj0sted/src/io/scn_export.cpp rename to editor/plan_scn_export.cpp index e55ccf01..672549ce 100644 --- a/maj0sted/src/io/scn_export.cpp +++ b/editor/plan_scn_export.cpp @@ -1,5 +1,13 @@ -#include "maj0sted/io/scn_export.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include #include #include #include @@ -10,16 +18,18 @@ #include #include -namespace maj0sted::io { +module eu07.editor.plan_scn_export; + +namespace editor::plan::io { namespace { -using maj0sted::editor::Document; -using maj0sted::editor::Kind; -using maj0sted::editor::PlanPoint; -using maj0sted::editor::SolvedElement; -using maj0sted::editor::SolvedTrack; -using maj0sted::editor::SolvedTurnout; -using maj0sted::editor::TurnoutPlacement; +using editor::plan::Document; +using editor::plan::Kind; +using editor::plan::PlanPoint; +using editor::plan::SolvedElement; +using editor::plan::SolvedTrack; +using editor::plan::SolvedTurnout; +using editor::plan::TurnoutPlacement; /// What `TTrack::Equal` calls one point, and so what the simulator will wire /// together. Everything the exporter writes has to land well inside it. @@ -413,7 +423,7 @@ struct Span { /// What the catalogue calls the turnout's radius: the one the longest curved /// piece runs at, which is the łuk itself and not an easement into it. -double catalogue_radius(const editor::TurnoutType& type) { +double catalogue_radius(const plan::TurnoutType& type) { double longest = 0.0; double radius = 0.0; for (const auto& piece : type.pieces) { @@ -448,7 +458,7 @@ std::string switch_include(double radius, int hand) { /// Which way the switch faces, in the degrees an include's `rotate` takes: zero /// along the simulator's +z, turning towards +x. -double heading_degrees(const domain::geometry::Pose& pose) { +double heading_degrees(const geometry::Pose& pose) { return std::atan2(pose.hx, -pose.hy) * 180.0 / std::numbers::pi; } @@ -470,7 +480,7 @@ double diverging_radius(const SolvedTurnout& turnout) { // --------------------------------------------------------------------------- -ScnExportOptions resolve_scn_origin(const maj0sted::editor::Solution& solution, +ScnExportOptions resolve_scn_origin(const editor::plan::Solution& solution, ScnExportOptions options) { if (std::abs(options.origin_east) >= 1.0 || std::abs(options.origin_north) >= 1.0) { return options; @@ -490,7 +500,7 @@ ScnExportOptions resolve_scn_origin(const maj0sted::editor::Solution& solution, } ScnExportResult export_scn(const Document& document, - const maj0sted::editor::Solution& solution, + const editor::plan::Solution& solution, const ScnExportOptions& options, std::ostream& out) { const auto opt = resolve_scn_origin(solution, options); ScnExportResult result; @@ -637,7 +647,7 @@ ScnExportResult export_scn(const Document& document, turnout.start.hy}; const double exit_station = span.facing ? span.to : span.from; - domain::geometry::Pose exit_pose{}; + geometry::Pose exit_pose{}; if (!pose_at(track, exit_station, exit_pose)) { result.warnings.push_back("rozjazd „" + span.placement->type + "” na torze „" + base + "” nie ma końca na torze zasadniczym"); @@ -753,4 +763,4 @@ ScnExportResult export_scn(const Document& document, return result; } -} // namespace maj0sted::io +} // namespace editor::plan::io diff --git a/maj0sted/include/maj0sted/io/scn_export.hpp b/editor/plan_scn_export.cppm similarity index 82% rename from maj0sted/include/maj0sted/io/scn_export.hpp rename to editor/plan_scn_export.cppm index 3cde1a1d..4d12583f 100644 --- a/maj0sted/include/maj0sted/io/scn_export.hpp +++ b/editor/plan_scn_export.cppm @@ -1,13 +1,23 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" +export module eu07.editor.plan_scn_export; +export import eu07.editor.plan_model; +export import eu07.editor.plan_solution; -namespace maj0sted::io { +export { + +namespace editor::plan::io { struct ScnExportOptions { double origin_east{0.0}; @@ -64,12 +74,14 @@ struct ScnExportResult { /// Height is still a constant and both roll slots are still zero — the vertical /// alignment is a separate piece of work, and nothing in the editor produces one /// yet. -[[nodiscard]] ScnExportResult export_scn(const editor::Document& document, - const editor::Solution& solution, +[[nodiscard]] ScnExportResult export_scn(const plan::Document& document, + const plan::Solution& solution, const ScnExportOptions& options, std::ostream& out); -[[nodiscard]] ScnExportOptions resolve_scn_origin(const editor::Solution& solution, +[[nodiscard]] ScnExportOptions resolve_scn_origin(const plan::Solution& solution, ScnExportOptions options); -} // namespace maj0sted::io +} // namespace editor::plan::io + +} // export diff --git a/maj0sted/include/maj0sted/domain/geometry/segment_layout.hpp b/editor/plan_segment.cppm similarity index 89% rename from maj0sted/include/maj0sted/domain/geometry/segment_layout.hpp rename to editor/plan_segment.cppm index 4716824f..72981fbb 100644 --- a/maj0sted/include/maj0sted/domain/geometry/segment_layout.hpp +++ b/editor/plan_segment.cppm @@ -1,12 +1,23 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include #include #include -namespace maj0sted::domain::geometry { +export module eu07.editor.plan_segment; + +export { + +namespace editor::plan::geometry { struct XY { double x; @@ -87,4 +98,6 @@ inline Pose layout_segment(double k0, double k1, double length, Pose start, start.hx * sin_t + start.hy * cos_t}; } -} // namespace maj0sted::domain::geometry +} // namespace editor::plan::geometry + +} // export diff --git a/maj0sted/src/editor/sketch.cpp b/editor/plan_sketch.cpp similarity index 97% rename from maj0sted/src/editor/sketch.cpp rename to editor/plan_sketch.cpp index cbc8e29f..75753a4d 100644 --- a/maj0sted/src/editor/sketch.cpp +++ b/editor/plan_sketch.cpp @@ -1,17 +1,27 @@ -#include "maj0sted/editor/sketch.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include +#include #include #include #include #include -namespace maj0sted::editor { +module eu07.editor.plan_sketch; + +namespace editor::plan { namespace { constexpr double kEps = 1e-9; } // namespace -using domain::geometry::Pose; +using geometry::Pose; Corner fit_corner(double in_hx, double in_hy, double out_hx, double out_hy, double radius) { @@ -217,7 +227,7 @@ Pose lay_group(const Track& track, const Group& group, const std::vector const double k0 = element.kind == Kind::Clothoid ? k_prev : k1; const double length = element.kind == Kind::Arc ? arc_length[arc_at++] : element.length; - pose = domain::geometry::layout_segment(k0, k1, length, pose, nullptr); + pose = geometry::layout_segment(k0, k1, length, pose, nullptr); k_prev = k1; } return pose; @@ -492,4 +502,4 @@ bool lay_along_skeleton(Track& track, const Skeleton& skeleton, std::string& why return true; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/sketch.hpp b/editor/plan_sketch.cppm similarity index 93% rename from maj0sted/include/maj0sted/editor/sketch.hpp rename to editor/plan_sketch.cppm index 1f793cc2..9bb24c0c 100644 --- a/maj0sted/include/maj0sted/editor/sketch.hpp +++ b/editor/plan_sketch.cppm @@ -1,12 +1,22 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" +export module eu07.editor.plan_sketch; +export import eu07.editor.plan_model; +export import eu07.editor.plan_solution; -namespace maj0sted::editor { +export { + +namespace editor::plan { /// Laying track by clicking along the ground. /// @@ -86,7 +96,7 @@ struct Skeleton { /// curve comes out, rather than the curve being slid along a line drawn /// before the edit. bool pinned{false}; - domain::geometry::Pose begins{}; + geometry::Pose begins{}; }; /// Pulls @p track's skeleton out of @p solved. @@ -122,4 +132,6 @@ struct Skeleton { [[nodiscard]] bool lay_along_skeleton(Track& track, const Skeleton& skeleton, std::string& why); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/editor/solution.cpp b/editor/plan_solution.cpp similarity index 85% rename from maj0sted/src/editor/solution.cpp rename to editor/plan_solution.cpp index 583b4185..5947c6a7 100644 --- a/maj0sted/src/editor/solution.cpp +++ b/editor/plan_solution.cpp @@ -1,9 +1,20 @@ -#include "maj0sted/editor/solution.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include #include #include -namespace maj0sted::editor { +module eu07.editor.plan_solution; + +namespace editor::plan { const char* code_name(Code code) { switch (code) { @@ -58,13 +69,13 @@ const SolvedElement* find_element(const Solution& solution, ElementId id) { return nullptr; } -bool pose_at(const SolvedTrack& track, double station, domain::geometry::Pose& out) { +bool pose_at(const SolvedTrack& track, double station, geometry::Pose& out) { const auto& line = track.centreline; if (line.empty()) { return false; } if (line.size() == 1) { - out = domain::geometry::Pose{line[0].x, line[0].y, track.start.hx, track.start.hy}; + out = geometry::Pose{line[0].x, line[0].y, track.start.hx, track.start.hy}; return true; } @@ -78,7 +89,7 @@ bool pose_at(const SolvedTrack& track, double station, domain::geometry::Pose& o } if (station <= walked + step) { const double t = std::clamp((station - walked) / step, 0.0, 1.0); - out = domain::geometry::Pose{line[i - 1].x + dx * t, line[i - 1].y + dy * t, + out = geometry::Pose{line[i - 1].x + dx * t, line[i - 1].y + dy * t, dx / step, dy / step}; return true; } @@ -115,4 +126,4 @@ bool steady_room(const SolvedTrack& track, double station, double& curvature, do return false; } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/solution.hpp b/editor/plan_solution.cppm similarity index 88% rename from maj0sted/include/maj0sted/editor/solution.hpp rename to editor/plan_solution.cppm index 1112baff..319236b0 100644 --- a/maj0sted/include/maj0sted/editor/solution.hpp +++ b/editor/plan_solution.cppm @@ -1,13 +1,23 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include -#include "maj0sted/domain/geometry/segment_layout.hpp" // Pose -#include "maj0sted/domain/geometry/turnout.hpp" // TurnoutPart -#include "maj0sted/editor/model.hpp" +export module eu07.editor.plan_solution; +export import eu07.editor.plan_segment; +export import eu07.editor.plan_turnout_geometry; +export import eu07.editor.plan_model; -namespace maj0sted::editor { +export { + +namespace editor::plan { /// A point in the project's CRS (metres for EPSG:2180). struct PlanPoint { @@ -25,8 +35,8 @@ struct PlanPoint { struct SolvedElement { ElementId id{ElementId::none}; Kind kind{Kind::Line}; - domain::geometry::Pose start{}; ///< pose the element is laid from - domain::geometry::Pose end{}; ///< pose it ends on = the next element's start + geometry::Pose start{}; ///< pose the element is laid from + geometry::Pose end{}; ///< pose it ends on = the next element's start double k0{0.0}; ///< signed curvature at the start (1/m) double k1{0.0}; ///< signed curvature at the end double length{0.0}; @@ -40,8 +50,8 @@ struct SolvedTrack { TrackId id{TrackId::none}; std::vector elements; std::vector centreline; - domain::geometry::Pose start{}; - domain::geometry::Pose end{}; + geometry::Pose start{}; + geometry::Pose end{}; double length{0.0}; /// True when the chain was laid whole. False means it was cut short by a /// diagnostic — the elements up to the cut are still here and still drawable. @@ -50,9 +60,9 @@ struct SolvedTrack { /// One laid segment of a turnout's diverging path. struct SolvedTurnoutSegment { - domain::geometry::Pose start{}; + geometry::Pose start{}; double k0{0.0}, k1{0.0}, length{0.0}; - domain::TurnoutPart part{domain::TurnoutPart::Curve}; + plan::TurnoutPart part{plan::TurnoutPart::Curve}; std::vector points; }; @@ -73,8 +83,8 @@ struct TurnoutMark { struct SolvedTurnout { TurnoutId id{TurnoutId::none}; bool valid{false}; - domain::geometry::Pose start{}; ///< PR, on the through track - domain::geometry::Pose frog{}; ///< KR, where a branch anchors + geometry::Pose start{}; ///< PR, on the through track + geometry::Pose frog{}; ///< KR, where a branch anchors double tangent_front{0.0}, tangent_back{0.0}; double diverging_length{0.0}; double through_length{0.0}; ///< PR to the frog's projection, along the through track @@ -154,7 +164,7 @@ struct Solution { /// Pose at @p station metres along a solved track's centreline. Clamped to the /// ends. Returns false for an empty track. [[nodiscard]] bool pose_at(const SolvedTrack& track, double station, - domain::geometry::Pose& out); + geometry::Pose& out); /// How much track of one steady curvature there is around @p station: @p behind /// back to where the element begins, @p ahead on to where it ends, and @@ -166,4 +176,6 @@ struct Solution { [[nodiscard]] bool steady_room(const SolvedTrack& track, double station, double& curvature, double& behind, double& ahead); -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/src/editor/tile_cache.cpp b/editor/plan_tilecache.cpp similarity index 95% rename from maj0sted/src/editor/tile_cache.cpp rename to editor/plan_tilecache.cpp index b5dae0c8..6da61aa1 100644 --- a/maj0sted/src/editor/tile_cache.cpp +++ b/editor/plan_tilecache.cpp @@ -1,5 +1,17 @@ -#include "maj0sted/editor/tile_cache.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; +#include +#include +#include +#include +#include #include #include #include @@ -7,12 +19,14 @@ #include #include -namespace maj0sted::editor { +module eu07.editor.plan_tilecache; + +namespace editor::plan { namespace { // Shortest round-trippable, locale-independent representation of a double — -// same convention as maj0sted::io so URLs are stable and precise. +// same convention as editor::plan::io so URLs are stable and precise. std::string num(double value) { char buffer[64]; const auto result = std::to_chars(buffer, buffer + sizeof(buffer), value); @@ -258,4 +272,4 @@ void TileService::schedule_retry(const TileKey& key) { begin_fetch(key); } -} // namespace maj0sted::editor +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/editor/tile_cache.hpp b/editor/plan_tilecache.cppm similarity index 96% rename from maj0sted/include/maj0sted/editor/tile_cache.hpp rename to editor/plan_tilecache.cppm index 6fe60f41..325cc468 100644 --- a/maj0sted/include/maj0sted/editor/tile_cache.hpp +++ b/editor/plan_tilecache.cppm @@ -1,12 +1,23 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include #include #include -namespace maj0sted::editor { +export module eu07.editor.plan_tilecache; + +export { + +namespace editor::plan { /// A stable tile in the EPSG:2180 tiling pyramid. Tiles are addressed by their /// zoom level and integer column/row, so the same ground square always maps to @@ -179,4 +190,6 @@ private: std::function on_ready_; }; -} // namespace maj0sted::editor +} // namespace editor::plan + +} // export diff --git a/maj0sted/include/maj0sted/render/track_renderer.hpp b/editor/plan_track_renderer.cppm similarity index 78% rename from maj0sted/include/maj0sted/render/track_renderer.hpp rename to editor/plan_track_renderer.cppm index bd5b9201..3fe245b5 100644 --- a/maj0sted/include/maj0sted/render/track_renderer.hpp +++ b/editor/plan_track_renderer.cppm @@ -1,11 +1,21 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include -#include "maj0sted/render/scene.hpp" // Point, ElementKind +export module eu07.editor.plan_track_renderer; +export import eu07.editor.plan_scene; -namespace maj0sted::render { +export { + +namespace editor::plan::render { /// One sampled centreline element of a solved niweleta, tagged with its logical /// origin so a UI can colour, label and hit-test it. Rendering-neutral: it holds @@ -36,4 +46,6 @@ public: virtual void add(const CentrelineElement& element) = 0; }; -} // namespace maj0sted::render +} // namespace editor::plan::render + +} // export diff --git a/maj0sted/src/domain/turnout.cpp b/editor/plan_turnout_geometry.cpp similarity index 97% rename from maj0sted/src/domain/turnout.cpp rename to editor/plan_turnout_geometry.cpp index b88561b0..8c549982 100644 --- a/maj0sted/src/domain/turnout.cpp +++ b/editor/plan_turnout_geometry.cpp @@ -1,11 +1,20 @@ -#include "maj0sted/domain/geometry/turnout.hpp" - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include #include #include #include -namespace maj0sted::domain { +module eu07.editor.plan_turnout_geometry; + +namespace editor::plan { using geometry::layout_segment; using geometry::Pose; @@ -311,4 +320,4 @@ TurnoutGeometry lay_turnout(const Pose& start, const Turnout& turnout, double be return geometry; } -} // namespace maj0sted::domain +} // namespace editor::plan diff --git a/maj0sted/include/maj0sted/domain/geometry/turnout.hpp b/editor/plan_turnout_geometry.cppm similarity index 96% rename from maj0sted/include/maj0sted/domain/geometry/turnout.hpp rename to editor/plan_turnout_geometry.cppm index d356b232..3373a195 100644 --- a/maj0sted/include/maj0sted/domain/geometry/turnout.hpp +++ b/editor/plan_turnout_geometry.cppm @@ -1,10 +1,20 @@ -#pragma once - +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +module; #include -#include "maj0sted/domain/geometry/segment_layout.hpp" // Pose +export module eu07.editor.plan_turnout_geometry; +export import eu07.editor.plan_segment; -namespace maj0sted::domain { +export { + +namespace editor::plan { /// The crossing mark of a turnout — the skos 1:n. It is the tangent of the angle /// between the through and diverging tracks, so it fixes the total angle the @@ -176,4 +186,6 @@ struct TurnoutGeometry { [[nodiscard]] TurnoutGeometry lay_turnout(const geometry::Pose& start, const Turnout& turnout, double bend = 0.0); -} // namespace maj0sted::domain +} // namespace editor::plan + +} // export diff --git a/editor/tests/CMakeLists.txt b/editor/tests/CMakeLists.txt new file mode 100644 index 00000000..14d1477c --- /dev/null +++ b/editor/tests/CMakeLists.txt @@ -0,0 +1,52 @@ +# Unit tests for the plan library (the geometry and the solver behind the track +# layout tool). They are off by default: switched on, the interface units are +# compiled a second time into a small library of their own, because a test +# executable can only import modules from a target it links, and linking the game +# would drag the whole simulator in. The code under test needs nothing but a +# C++20 compiler - no glm, no engine, no imgui. +option(EU07_EDITOR_PLAN_TESTS "Build the editor plan library unit tests" OFF) +if (NOT EU07_EDITOR_PLAN_TESTS) + return() +endif() + +enable_testing() + +set(PLAN_INTERFACES + ../plan_segment.cppm + ../plan_turnout_geometry.cppm + ../plan_model.cppm + ../plan_solution.cppm + ../plan_chain.cppm + ../plan_join.cppm + ../plan_layout.cppm + ../plan_render.cppm + ../plan_sketch.cppm + ../plan_tilecache.cppm + ../plan_document_io.cppm + ../plan_scn_export.cppm + ../plan_scene.cppm + ../plan_track_renderer.cppm + ../plan_rail_renderer.cppm) + +file(GLOB PLAN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../plan_*.cpp") + +add_library(editor_plan STATIC ${PLAN_SOURCES}) +target_sources(editor_plan + PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/.. + FILES ${PLAN_INTERFACES}) +set_target_properties(editor_plan PROPERTIES + CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF + POSITION_INDEPENDENT_CODE ON FOLDER "editor") + +foreach(name chain hold lines graph format turnout tile_cache) + add_executable(editor_plan_test_${name} test_${name}.cpp) + target_link_libraries(editor_plan_test_${name} PRIVATE editor_plan) + target_include_directories(editor_plan_test_${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + set_target_properties(editor_plan_test_${name} PROPERTIES + CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF FOLDER "editor") + add_test(NAME plan_${name} COMMAND editor_plan_test_${name}) +endforeach() + +# test_scn.cpp and test_join.cpp are missing: they were never committed, along +# with the join module those two exercised (see the stub in plan_join.cpp). diff --git a/maj0sted/tests/check.hpp b/editor/tests/check.hpp similarity index 77% rename from maj0sted/tests/check.hpp rename to editor/tests/check.hpp index 3f500df1..95e03e80 100644 --- a/maj0sted/tests/check.hpp +++ b/editor/tests/check.hpp @@ -1,3 +1,11 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ #pragma once // A tiny zero-dependency check framework so the test suite needs nothing but a @@ -6,18 +14,18 @@ #include -namespace maj0test { +namespace plantest { inline int checks = 0; inline int failures = 0; -} // namespace maj0test +} // namespace plantest // Variadic so that brace-init lists with commas, e.g. CHECK(Point{1, 2} == ...), // are passed through as a single condition instead of several macro arguments. #define CHECK(...) \ do { \ - ++::maj0test::checks; \ + ++::plantest::checks; \ if (!(__VA_ARGS__)) { \ - ++::maj0test::failures; \ + ++::plantest::failures; \ std::printf(" [FAIL] %s:%d CHECK(%s)\n", __FILE__, __LINE__, \ #__VA_ARGS__); \ } \ @@ -25,7 +33,7 @@ inline int failures = 0; #define CHECK_THROWS(...) \ do { \ - ++::maj0test::checks; \ + ++::plantest::checks; \ bool threw = false; \ try { \ (void)(__VA_ARGS__); \ @@ -33,7 +41,7 @@ inline int failures = 0; threw = true; \ } \ if (!threw) { \ - ++::maj0test::failures; \ + ++::plantest::failures; \ std::printf(" [FAIL] %s:%d CHECK_THROWS(%s)\n", __FILE__, \ __LINE__, #__VA_ARGS__); \ } \ @@ -46,6 +54,6 @@ inline int failures = 0; } while (0) #define REPORT() \ - (std::printf("\n%d checks, %d failures\n", ::maj0test::checks, \ - ::maj0test::failures), \ - ::maj0test::failures == 0 ? 0 : 1) + (std::printf("\n%d checks, %d failures\n", ::plantest::checks, \ + ::plantest::failures), \ + ::plantest::failures == 0 ? 0 : 1) diff --git a/maj0sted/tests/test_chain.cpp b/editor/tests/test_chain.cpp similarity index 96% rename from maj0sted/tests/test_chain.cpp rename to editor/tests/test_chain.cpp index 80e3bcae..174812b4 100644 --- a/maj0sted/tests/test_chain.cpp +++ b/editor/tests/test_chain.cpp @@ -1,14 +1,23 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include +#include +#include "check.hpp" +import eu07.editor.plan_chain; + // The element chain: a walk, one element at a time, with every length said // outright. Nothing here is solved for — what the document says is what is laid. -#include -#include -#include "check.hpp" -#include "maj0sted/editor/chain.hpp" -using namespace maj0sted::editor; -using maj0sted::domain::geometry::Pose; +using namespace editor::plan; +using editor::plan::geometry::Pose; namespace { diff --git a/maj0sted/tests/test_format.cpp b/editor/tests/test_format.cpp similarity index 85% rename from maj0sted/tests/test_format.cpp rename to editor/tests/test_format.cpp index eb901261..f5c4e478 100644 --- a/maj0sted/tests/test_format.cpp +++ b/editor/tests/test_format.cpp @@ -1,16 +1,27 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include + +#include +#include +#include "check.hpp" +import eu07.editor.plan_layout; +import eu07.editor.plan_document_io; + // The .m0s format, version 5: everything by id, an explicit version, and a // round trip that is byte-identical. Older files still open: a version-3 one has // its arcs and blade fields converted to the piece list on the way in, and a // version-4 one simply had no nose on its blade yet. -#include -#include -#include "check.hpp" -#include "maj0sted/editor/layout.hpp" -#include "maj0sted/io/document_io.hpp" -using namespace maj0sted::editor; +using namespace editor::plan; namespace { @@ -108,20 +119,20 @@ bool same(const Document& a, const Document& b) { void round_trip_is_byte_identical() { const Document document = sample(); - const std::string text = maj0sted::io::serialize(document); + const std::string text = editor::plan::io::serialize(document); - const auto reloaded = maj0sted::io::deserialize(text); + const auto reloaded = editor::plan::io::deserialize(text); CHECK(reloaded.has_value()); if (!reloaded) { return; } CHECK(same(document, *reloaded)); - CHECK(maj0sted::io::serialize(*reloaded) == text); + CHECK(editor::plan::io::serialize(*reloaded) == text); } void every_field_survives() { const Document document = sample(); - const auto reloaded = maj0sted::io::deserialize(maj0sted::io::serialize(document)); + const auto reloaded = editor::plan::io::deserialize(editor::plan::io::serialize(document)); CHECK(reloaded.has_value()); if (!reloaded) { return; @@ -180,14 +191,14 @@ void an_older_file_is_refused() { // outright rather than half-understood. Version 3 is not refused — it is // converted, which an_old_file_upgrades_to_the_piece_list checks. const std::string version_1 = - "maj0sted 1\ncrs 2180\nniwelety 0\neditor 1\neniw 2 1\nename niweleta 1\n"; - CHECK(!maj0sted::io::deserialize(version_1).has_value()); + "the plan library 1\ncrs 2180\nniwelety 0\neditor 1\neniw 2 1\nename niweleta 1\n"; + CHECK(!editor::plan::io::deserialize(version_1).has_value()); const std::string version_2 = "m0s 2\nnext 9\nview 0 0 0\norigin 0 0 0 0\nlines 0\ntypes 0\n" "tracks 0\n"; - CHECK(!maj0sted::io::deserialize(version_2).has_value()); - CHECK(!maj0sted::io::deserialize("").has_value()); - CHECK(!maj0sted::io::deserialize("m0s 8\n").has_value()); + CHECK(!editor::plan::io::deserialize(version_2).has_value()); + CHECK(!editor::plan::io::deserialize("").has_value()); + CHECK(!editor::plan::io::deserialize("m0s 8\n").has_value()); } void a_file_from_before_lukowanie_still_opens() { @@ -197,7 +208,7 @@ void a_file_from_before_lukowanie_still_opens() { const std::string version_5 = "m0s 5\nnext 5\nview 0 0 0\norigin 0 0 0 0\ntypes 0\n" "turnouts 1\nturnout 2 1 100 1 1\ntutype Rz 1:9 R190\ntracks 0\n"; - const auto document = maj0sted::io::deserialize(version_5); + const auto document = editor::plan::io::deserialize(version_5); CHECK(document.has_value()); if (!document) { return; @@ -206,7 +217,7 @@ void a_file_from_before_lukowanie_still_opens() { CHECK(document->turnouts[0].station == 100.0); CHECK(document->turnouts[0].bend_from_track); CHECK(document->turnouts[0].bend == 0.0); - CHECK(maj0sted::io::serialize(*document).find("m0s 7") != std::string::npos); + CHECK(editor::plan::io::serialize(*document).find("m0s 7") != std::string::npos); } void a_file_from_before_the_export_path_still_opens() { @@ -216,14 +227,14 @@ void a_file_from_before_the_export_path_still_opens() { "m0s 6\nnext 3\nview 0 0 0\norigin 0 0 0 0\ntypes 0\nturnouts 0\n" "tracks 1\ntrack 1\ntkname tor\nanchor pose 0 0 0\nelements 1\n" "element 2 line 0 0 250\n"; - const auto document = maj0sted::io::deserialize(version_6); + const auto document = editor::plan::io::deserialize(version_6); CHECK(document.has_value()); if (!document) { return; } CHECK(document->scn_path.empty()); CHECK(document->tracks.size() == 1); - CHECK(maj0sted::io::serialize(*document).find("m0s 7") != std::string::npos); + CHECK(editor::plan::io::serialize(*document).find("m0s 7") != std::string::npos); } void a_file_from_before_the_nose_still_opens() { @@ -234,7 +245,7 @@ void a_file_from_before_the_nose_still_opens() { "m0s 4\nnext 1\nview 0 0 0\norigin 0 0 0 0\n" "types 1\ntype 9 27.138 0.0049 0.07 1\ntseg 2 21.02 190 190 0\n" "tname Rz 1:9 R190\nturnouts 0\ntracks 0\n"; - const auto document = maj0sted::io::deserialize(version_4); + const auto document = editor::plan::io::deserialize(version_4); CHECK(document.has_value()); if (!document) { return; @@ -246,7 +257,7 @@ void a_file_from_before_the_nose_still_opens() { CHECK(document->turnout_types[0].pieces.size() == 1); // and it is written back in the new form, with a place for the nose - CHECK(maj0sted::io::serialize(*document).find("m0s 7") != std::string::npos); + CHECK(editor::plan::io::serialize(*document).find("m0s 7") != std::string::npos); } void an_old_file_upgrades_to_the_piece_list() { @@ -257,7 +268,7 @@ void an_old_file_upgrades_to_the_piece_list() { "m0s 3\nnext 1\nview 0 0 0\norigin 0 0 0 0\n" "types 1\ntype 9 0 0 27.138 0 0 0 1\ntarc 190 0 0\ntname Rz 1:9 R190\n" "turnouts 0\ntracks 0\n"; - const auto document = maj0sted::io::deserialize(version_3); + const auto document = editor::plan::io::deserialize(version_3); CHECK(document.has_value()); if (!document) { return; @@ -270,20 +281,20 @@ void an_old_file_upgrades_to_the_piece_list() { CHECK(std::abs(type.pieces[0].length - 190.0 * std::atan(1.0 / 9.0)) < 1e-9); CHECK(type.pieces[1].part == 3); - const auto laid = maj0sted::domain::lay_turnout( - maj0sted::domain::geometry::Pose{0.0, 0.0, 1.0, 0.0}, to_domain(type, 1)); + const auto laid = editor::plan::lay_turnout( + editor::plan::geometry::Pose{0.0, 0.0, 1.0, 0.0}, to_domain(type, 1)); CHECK(laid.valid); CHECK(std::abs(laid.angle_residual) < 1e-9); CHECK(std::abs(laid.length_residual) < 1e-9); // and it is written back in the new form - CHECK(maj0sted::io::serialize(*document).find("tseg ") != std::string::npos); + CHECK(editor::plan::io::serialize(*document).find("tseg ") != std::string::npos); } void a_truncated_file_is_refused() { - const std::string text = maj0sted::io::serialize(sample()); + const std::string text = editor::plan::io::serialize(sample()); // Cut off half way: the counts no longer match what follows. - CHECK(!maj0sted::io::deserialize(text.substr(0, text.size() / 2)).has_value()); + CHECK(!editor::plan::io::deserialize(text.substr(0, text.size() / 2)).has_value()); } } // namespace diff --git a/maj0sted/tests/test_graph.cpp b/editor/tests/test_graph.cpp similarity index 97% rename from maj0sted/tests/test_graph.cpp rename to editor/tests/test_graph.cpp index 06791d81..34063508 100644 --- a/maj0sted/tests/test_graph.cpp +++ b/editor/tests/test_graph.cpp @@ -1,13 +1,22 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include +#include "check.hpp" +import eu07.editor.plan_layout; + // What refers to what decides the order things are laid in. A turnout on the // branch of a turnout is not a special case, and a reference that runs in a // circle is reported rather than relaxed at for a fixed number of passes. -#include -#include "check.hpp" -#include "maj0sted/editor/layout.hpp" -using namespace maj0sted::editor; +using namespace editor::plan; namespace { diff --git a/maj0sted/tests/test_hold.cpp b/editor/tests/test_hold.cpp similarity index 97% rename from maj0sted/tests/test_hold.cpp rename to editor/tests/test_hold.cpp index 67875a35..4f4b03b4 100644 --- a/maj0sted/tests/test_hold.cpp +++ b/editor/tests/test_hold.cpp @@ -1,16 +1,25 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include +#include +#include +#include "check.hpp" +import eu07.editor.plan_layout; +import eu07.editor.plan_sketch; + // What one track keeps against another, and what clicking along the ground // works out at the click. Both are the same idea from two ends: geometry is // decided once, in numbers, and nothing is left pointing at a drawing. -#include -#include -#include -#include "check.hpp" -#include "maj0sted/editor/layout.hpp" -#include "maj0sted/editor/sketch.hpp" -using namespace maj0sted::editor; +using namespace editor::plan; namespace { diff --git a/maj0sted/tests/test_lines.cpp b/editor/tests/test_lines.cpp similarity index 98% rename from maj0sted/tests/test_lines.cpp rename to editor/tests/test_lines.cpp index 2d730812..ec7079ac 100644 --- a/maj0sted/tests/test_lines.cpp +++ b/editor/tests/test_lines.cpp @@ -1,19 +1,30 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include + +#include +#include +#include +#include +#include "check.hpp" +import eu07.editor.plan_layout; +import eu07.editor.plan_sketch; + // Pulling a straight about by one of its ends. The arcs beside it re-fit, every // other straight keeps its bearing, and an arc that turns past a half circle // stays as far round as it was drawn — that last one is the whole reason the // construction goes through the arc's centre and not through where the tangents // would have crossed. -#include -#include -#include -#include -#include "check.hpp" -#include "maj0sted/editor/layout.hpp" -#include "maj0sted/editor/sketch.hpp" -using namespace maj0sted::editor; +using namespace editor::plan; namespace { diff --git a/maj0sted/tests/test_tile_cache.cpp b/editor/tests/test_tile_cache.cpp similarity index 96% rename from maj0sted/tests/test_tile_cache.cpp rename to editor/tests/test_tile_cache.cpp index c2634670..132cb263 100644 --- a/maj0sted/tests/test_tile_cache.cpp +++ b/editor/tests/test_tile_cache.cpp @@ -1,12 +1,20 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ #include #include #include #include - #include "check.hpp" -#include "maj0sted/editor/tile_cache.hpp" +#include +import eu07.editor.plan_tilecache; -using namespace maj0sted::editor; +using namespace editor::plan; namespace { diff --git a/maj0sted/tests/test_turnout.cpp b/editor/tests/test_turnout.cpp similarity index 97% rename from maj0sted/tests/test_turnout.cpp rename to editor/tests/test_turnout.cpp index 0c0b49d3..6cf0a8e3 100644 --- a/maj0sted/tests/test_turnout.cpp +++ b/editor/tests/test_turnout.cpp @@ -1,3 +1,18 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ +#include +#include +#include "check.hpp" +#include +#include +import eu07.editor.plan_turnout_geometry; + // A turnout is laid from the list its catalogue entry gives, piece by piece, and // nothing in it is fitted: whether the list keeps the promises of the crossing // mark and the catalogue length is reported, not corrected. The blade is @@ -6,14 +21,10 @@ // rail at PR, but the blade only starts at a, and its planed nose runs on to A // where the rail is u thick. -#include -#include -#include "check.hpp" -#include "maj0sted/domain/geometry/turnout.hpp" -using namespace maj0sted::domain; -using maj0sted::domain::geometry::Pose; +using namespace editor::plan; +using editor::plan::geometry::Pose; namespace { @@ -76,7 +87,7 @@ Pose pose_after(const TurnoutGeometry& geometry, std::size_t index) { pose = Pose{pose.x, pose.y, pose.hx * c - pose.hy * s, pose.hx * s + pose.hy * c}; } - pose = geometry::layout_segment(segment.k0, segment.k1, segment.length, pose, + pose = editor::plan::geometry::layout_segment(segment.k0, segment.k1, segment.length, pose, nullptr); } return pose; diff --git a/editor/turnouts.cpp b/editor/turnouts.cpp index c3cb466b..a531c5ce 100644 --- a/editor/turnouts.cpp +++ b/editor/turnouts.cpp @@ -2,9 +2,9 @@ module; #include #include #include -#include "maj0sted/domain/geometry/turnout.hpp" module eu07.editor.turnouts; +import eu07.editor.plan_turnout_geometry; /* This Source Code Form is subject to the @@ -47,8 +47,8 @@ turnout_preset curved_tangent(std::string name, double crossing_n, double radius auto const alfa{std::atan(1.0 / crossing_n)}; auto const tangent{radius * std::tan(0.5 * alfa)}; auto const b{back_tangent > 0.0 ? back_tangent : tangent}; - auto const lead{maj0sted::domain::blade_run_to_offset(radius, 0.0, tip_thickness) - nose}; - auto const blade{maj0sted::domain::blade_run_to_offset(radius, 0.0, heel_offset) - lead}; + auto const lead{editor::plan::blade_run_to_offset(radius, 0.0, tip_thickness) - nose}; + auto const blade{editor::plan::blade_run_to_offset(radius, 0.0, heel_offset) - lead}; turnout_preset preset{std::move(name), crossing_n, tangent + b, tip_thickness, nose, railtop_width, {}}; preset.pieces.push_back({0, lead, radius, radius, 0.0}); diff --git a/editor/turnouts.cppm b/editor/turnouts.cppm index 11667401..c77819a2 100644 --- a/editor/turnouts.cppm +++ b/editor/turnouts.cppm @@ -19,7 +19,7 @@ namespace editor { // one piece of a preset's diverging path, in catalogue order from PR. mirrors -// maj0sted::editor::TurnoutPieceSpec so this header stays free of the library +// editor::plan::TurnoutPieceSpec so this header stays free of the library struct turnout_preset_piece { int part; // 0 przediglicowy, 1 iglica, 2 luk, 3 krzyzownicowa diff --git a/maj0sted/.clang-format b/maj0sted/.clang-format deleted file mode 100644 index e58a6fea..00000000 --- a/maj0sted/.clang-format +++ /dev/null @@ -1,12 +0,0 @@ ---- -Language: Cpp -BasedOnStyle: Google -Standard: c++20 -ColumnLimit: 90 -IndentWidth: 4 -AccessModifierOffset: -4 -PointerAlignment: Left -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: false -SortIncludes: true -IncludeBlocks: Preserve diff --git a/maj0sted/.gitignore b/maj0sted/.gitignore deleted file mode 100644 index 8e43dbdd..00000000 --- a/maj0sted/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Build output -/build/ -/out/ -/cmake-build-*/ - -# Compiled objects / archives -*.o -*.obj -*.a -*.lib -*.so -*.dylib - -# Editors / IDEs -.vscode/ -.idea/ -*.swp -.cache/ -compile_commands.json - -# WASM / web build artifacts (produced by web/build.sh) -web/maj0sted.js -web/maj0sted.wasm -web/serve diff --git a/maj0sted/CMakeLists.txt b/maj0sted/CMakeLists.txt deleted file mode 100644 index a58be61b..00000000 --- a/maj0sted/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -project(maj0sted - VERSION 0.1.0 - DESCRIPTION "Model and solver for a railway track-layout editor" - LANGUAGES CXX) - -# ---------------------------------------------------------------------------- -# Options -# ---------------------------------------------------------------------------- -option(MAJ0STED_BUILD_TESTS "Build unit tests" ON) -option(MAJ0STED_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) - -# Only drive tests/examples/install defaults when built on its own, not when -# pulled in via add_subdirectory() from a larger project. -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - set(MAJ0STED_STANDALONE ON) -else() - set(MAJ0STED_STANDALONE OFF) -endif() - -# ---------------------------------------------------------------------------- -# The static library -# ---------------------------------------------------------------------------- -add_library(maj0sted STATIC - src/domain/turnout.cpp - src/editor/model.cpp - src/editor/solution.cpp - src/editor/chain.cpp - src/editor/sketch.cpp - src/editor/join.cpp - src/editor/layout.cpp - src/editor/render.cpp - src/editor/tile_cache.cpp - src/render/rail_renderer.cpp - src/io/document_io.cpp - src/io/scn_export.cpp -) -add_library(maj0sted::maj0sted ALIAS maj0sted) - -target_compile_features(maj0sted PUBLIC cxx_std_20) - -target_include_directories(maj0sted PUBLIC - $ - $ -) - -if(MSVC) - target_compile_options(maj0sted PRIVATE /W4) -else() - target_compile_options(maj0sted PRIVATE - -Wall -Wextra -Wpedantic -Wconversion -Wshadow) -endif() - -if(MAJ0STED_WARNINGS_AS_ERRORS) - if(MSVC) - target_compile_options(maj0sted PRIVATE /WX) - else() - target_compile_options(maj0sted PRIVATE -Werror) - endif() -endif() - -# ---------------------------------------------------------------------------- -# Tests -# ---------------------------------------------------------------------------- -if(MAJ0STED_BUILD_TESTS AND MAJ0STED_STANDALONE) - enable_testing() - add_subdirectory(tests) -endif() - -# ---------------------------------------------------------------------------- -# Install / package -# ---------------------------------------------------------------------------- -include(GNUInstallDirs) -include(CMakePackageConfigHelpers) - -install(TARGETS maj0sted - EXPORT maj0stedTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - -install(EXPORT maj0stedTargets - FILE maj0stedTargets.cmake - NAMESPACE maj0sted:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/maj0sted) - -configure_package_config_file( - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/maj0stedConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/maj0stedConfig.cmake - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/maj0sted) - -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/maj0stedConfigVersion.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/maj0stedConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/maj0stedConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/maj0sted) diff --git a/maj0sted/HANDOFF.md b/maj0sted/HANDOFF.md deleted file mode 100644 index b0786fae..00000000 --- a/maj0sted/HANDOFF.md +++ /dev/null @@ -1,184 +0,0 @@ -# HANDOFF — maj0sted - -Stan prac i punkt zaczepienia dla kolejnej sesji (np. po przejściu na `claude` CLI). -Kod jest samoopisowy; ten plik to skrót "gdzie jesteśmy i co dalej". - -## Czym jest projekt -Statyczna biblioteka **C++20** (DDD) do edytora torowiska. Czysty model domenowy, -bez zależności zewnętrznych. Namespace: `maj0sted::domain`. - -**Uwaga (sandbox):** na tej maszynie wyłączone są nieuprzywilejowane user -namespaces, więc domyślny sandbox komend pada w preflight (komenda „nie zwraca -statusu”). Uruchamiaj polecenia powłoki **z wyłączonym sandboxem** (w Cursorze: -`required_permissions: ["all"]`). Wtedy `git`, `g++`, `node` działają normalnie. - -**Uwaga:** `cmake` NIE jest zainstalowany. Weryfikacja odbywa się przez `g++ 14.2`. -Toolchain WASM: `emsdk` jest w `~/emsdk` (`source ~/emsdk/emsdk_env.sh` dodaje `em++`). - -## Jak weryfikować (bez cmake) -```bash -cd /home/maj00r/Projects/maj0sted -FLAGS="-std=c++20 -Iinclude -Wall -Wextra -Wpedantic -Wconversion -Wshadow" -SRC="src/domain/*.cpp src/io/*.cpp src/render/*.cpp src/editor/solve.cpp src/editor/tile_cache.cpp src/app/editor_document.cpp" -for t in map_project niweleta plan_alignment parallelism fitting serialization render web tile_cache document; do - g++ $FLAGS -Itests $SRC tests/test_$t.cpp -o /tmp/t_$t && /tmp/t_$t | tail -1 -done -``` -Wszystkie testy przechodzą, kompilacja bez ostrzeżeń. Oszczędnie: kompiluj tylko -zmieniony test z minimalnym zestawem źródeł (np. `tile_cache` wymaga tylko -`src/editor/tile_cache.cpp`; `document` — `src/domain/*.cpp src/io/project_serializer.cpp -src/app/editor_document.cpp`). Szybki syntax-check: `g++ $FLAGS -fsyntax-only ...`. - -Budowa WASM: `source ~/emsdk/emsdk_env.sh && cd web && ./build.sh` -(produkuje `web/maj0sted.js` + `.wasm`, oba w `.gitignore`). - -## Model — co już jest (✓ = zaimplementowane + testy) - -### Value Objects (`include/maj0sted/domain/value_objects/`) -- `Crs` — układ EPSG, domyślnie **EPSG:2180** (metry) ✓ -- `CartesianPosition` — (x=easting, y=northing), metry, double ✓ -- `Length` (≥0), `Radius` (>0) ✓ -- `Azimuth` — radiany, **zgodnie z ruchem wskazówek zegara od północy (+y)**, znormalizowany [0,2π) ✓ -- `NiweletaId`, `StraightId` — silne tożsamości ✓ -- `TrackOffset` — dystans (>0) + `Side::Left/Right` ✓ - -### Agregaty -- `MapProject` — **projekt**: trzyma `Crs` (domyślnie EPSG:2180) + kolekcję niwelet - (`add_niweleta`, `niwelety()`) ✓ -- `Niweleta` (`domain/niweleta.hpp`) — id, nazwa, plan + profil. **Sama nadaje `StraightId`**: - `add_straight(start,end,joint) -> StraightId`; `add_plan_element` mintuje id anonimowej prostej - (i podbija licznik przy id wczytanym z pliku). `lengths_consistent()`. - **`apply_fit(FitResult)`** — wpina wynik fitowania w plan: podmienia sąsiednie proste - (entry, exit) na `entry → curve... → exit` stykami Tangent; proste zachowują id ✓ - -### Geometria planu (`domain/geometry/`) -- `PlanElement = variant` - - `Straight` — **zakotwiczony w XY (start/end)**, azymut i długość liczone; opcjonalny `StraightId`. - Zasada: prosta trzyma linię nośną (pozycja+azymut), zmienia się tylko długość; krzywe to wypadkowa. - - `CircularArc` — promień + kierunek + **opcjonalna** długość - - `TransitionCurve` (klotoida) — długość + promienie końcowe (`optional`=∞) + kierunek -- `HorizontalAlignment` — lista kierunkowa + `JointContinuity{Tangent, AzimuthBreak}`. Reguły styku ✓: - - sąsiednie proste Tangent: muszą się stykać i mieć równy azymut - - różny azymut prostych → wymaga `AzimuthBreak` (tylko prosta-prosta, muszą się stykać, różne azymuty) - - sąsiednie łuki o tym samym promieniu i kierunku → zabronione - - styki z krzywą akceptowane "pending fit" - -### Geometria profilu -- `ProfileElement = variant`; `VerticalAlignment`. (Profil na razie nietknięty.) - -### Równoległość (`domain/parallelism/`) -- `TrackParallelism { StraightId origin, StraightId parallel, TrackOffset }` — **referencje wprost po StraightId**; - niezmienniki: oba id niepuste, różne ✓ -- `ParallelismService`: `mark_parallel(originStraight, parallelStraight, offset)`, `are_parallel`, - `derive_parallel_line`, `perpendicular_distance` ✓ - -### Fitowanie (`domain/fitting/`) -- `FitParameters { entry, exit, radius, optional transition_length }` — klotoida symetryczna lub sam łuk -- `CompoundFitParameters { entry, exit, radius1, radius2, split_station }` — **łuk koszowy** - (miejsce podziału = kilometraż pierwszego łuku; `δ1 = split_station/R1`) -- `FitResult { entry(przycięta), curve[], exit(przycięta), tangent_in, tangent_out, direction }` -- `FittingService`: - - `fit_between_straights` — klotoida–łuk–klotoida (lub sam łuk), przycina obie proste ✓ - - `fit_compound` — dwa łuki różnych promieni; **obie linie prostych bez zmian**, obie proste - doprzycięte na długości; podział ustala `δ1`. Metoda stycznej pośredniej ✓ - -### Serializacja (`maj0sted::io`, `include/maj0sted/io/project_serializer.hpp`) -- `serialize(MapProject) -> std::string` / `deserialize(std::string) -> MapProject` ✓ -- Format tekstowy, liniowy, bez zależności; liczby przez `to_chars`/`from_chars` (dokładny round-trip, - niezależny od locale). Round-trip jest bajtowo stabilny (test to sprawdza). -- Zapisuje: CRS + niwelety (id, nazwa, plan z elementami i stykami, profil). **NIE** zapisuje relacji - równoległości (patrz niżej — StraightId nie są globalnie unikalne). - -### Rendering: dwie szyny -`src/editor/editor.cpp` rysuje **dwie szyny w rozstawie 1500 mm** (`kHalfGauge=0.75`, -±750 mm od osi) zamiast samej osi. `offset_points` przesuwa linię osi wzdłuż -normalnej per-wierzchołek (różnica centralna, normalna lewa `(-dy,dx)`), -`push_rails` emituje lewą i prawą szynę zachowując `kind` (kolor). Uchwyty edycji -(węzły/końce prostych) w JS dalej rysują się z osi (model). - -### Warstwa web (WASM) — biblioteka robi wszystko, JS tylko rysuje -Zasada: **cała logika jest w libce**; `web/` to cienki renderer + przekazywanie -wejścia. `web/maj0sted_bindings.cpp` (embind) to jedyny plik zależny od emscripten. - -- **Kafle podkładu WMS** (`maj0sted::editor`, `web/tile_cache.hpp/.cpp`) ✓ - - `TileGrid` — **jeden stały grid kafli 100 m × 100 m** w **EPSG:2180** - (`kCellMetres=100`, **1024 px/kafel** → 100/1024 m/px, origin (0,0), jeden - poziom `kLevel=0`, **bez piramidy per-zoom**); `tile_at`, `bbox`, - `tiles_for_view`, `zoom_for_resolution` (argument zoom ignorowany, sygnatury - zachowane dla boundary). Czysta, testowana natywnie. - - **Retry:** nieudany fetch jest ponawiany **maks. `kMaxRetries=10` razy na - kafel** (licznik `TileImage.attempts`); po przekroczeniu limitu kafel dostaje - status `Failed`. Pod Emscripten retry jest odroczony async - (`emscripten_async_call`, `kRetryDelayMs=1500`), bez blokowania/rekurencji; - z wstrzykniętym fetcherem (testy) powtarza od razu. - - `WmsConfig` + `wms_getmap_url` — WMS **1.1.1** GetMap (BBOX = minx,miny,maxx,maxy), - presety Geoportalu (ortofoto/topo). Liczby przez `to_chars`. - - `TileService` — cache + **fetch**: na trafienie zwraca z cache, na pudło sam - wykonuje GetMap. Pod `__EMSCRIPTEN__` używa **Emscripten Fetch** (`-sFETCH`); - natywnie/w testach przez wstrzykiwany `Fetcher` (bez sieci). Callback - `on_ready` budzi przerysowanie w JS. - - **Proxy WMS (`web/serve.py`):** przeglądarka pobiera kafle **same-origin** - (`/wms?...`), a lokalny serwer pobiera je serwer-serwer z Geoportalu. Powód: - WAF Geoportalu **zwraca 404 dla User-Agentów zawierających „Mozilla"** (czyli - dla prawdziwych przeglądarek), a przepuszcza proste UA (`curl`), więc bezpośredni - `fetch`/`emscripten_fetch` z przeglądarki dostaje 404. Proxy używa UA `curl/8.5.0`. - Frontend ustawia `Module.wmsSetConfig({base_url: origin+'/wms'})` w `finishBoot`. - Libka nadal robi fetch (`emscripten_fetch`) — tylko na `localhost`. - Uruchamianie: `python3 web/serve.py 8080` (zamiast `http.server`). - - **Cache na dysku:** proxy odsyła udane kafle z `Cache-Control: public, - max-age=31536000, immutable`, więc przeglądarka trzyma je w HTTP cache na dysku — - po odświeżeniu strony kafle są brane z cache, bez ponownego pobierania. Błędy - (`502`) idą z `no-store` (nie cache'ują się). Uwaga: cache `TileService` w C++ jest - tylko w pamięci WASM (ginie przy refreshu) — trwałość zapewnia właśnie HTTP cache. - - **Retry w proxy:** WAF Geoportalu bywa niestabilny (sporadyczne 404/reset nawet dla - UA `curl`), więc proxy ponawia pobranie `WMS_PROXY_RETRIES=6` razy zanim zwróci 502; - do tego dochodzi client-side retry libki (10×). -- **Trwałość projektu** (`maj0sted::app`, `app/editor_document.hpp/.cpp`) ✓ - - `EditorDocument` = model GUI (niezależne proste + parametry fitów) — bezstratny. - - `serialize_document`/`deserialize_document` — **reużywa `io::serialize`** (osadza - prawdziwy projekt maj0sted) + sekcja `editor` z prostymi i parametrami fitów. - - `to_map_project`/`from_map_project` — konwersja do/z `MapProject` (best-effort, - nie rzuca). - - `save_project`/`load_project` — **I/O plikowe w libce** (`std::fstream` + - `std::filesystem`), domyślna ścieżka `/data/maj0sted/project.m0s`. -- **Fit nieudany → „brak" (decyzja w libce):** `solve_project` (editor) zwraca per - niweleta `polylines` **oraz `applied_fits`** — autorytatywną listę fitów, które - faktycznie zaszły. Fit, którego nie da się policzyć (zły parametr/geometria, punkty - styczne poza odcinkami prostych), jest **odrzucany w libce** i nie ma go w `applied_fits`. - Frontend tylko lustrzanie przyjmuje tę listę (bez własnej reguły o porażce). -- **Boundary (embind, cienki):** `solveProject`, `wmsTilesForView`, - `wmsZoomForResolution`, `wmsTileBytes`, `wmsSetOnReady`, `wmsSetConfig`, - `saveProject`, `loadDefaultProject`. -- **Frontend (`web/index.html`):** rysuje podkład WMS pod geometrią (georeferencja - EPSG:2180, trzyma się przy pan/zoom); `Ctrl+S` → `saveProject` + `FS.syncfs`; - na starcie montuje **IDBFS** w `/data`, `syncfs(true)` i `loadDefaultProject` - (fallback: demo). Flow budowy: prosta → krzywa (czeka jako „pending”, rysowana - przerywaną) → kolejna prosta kotwiczy ją z obu stron i **dopiero wtedy** liczony - jest fit. - -## Konwencje geometryczne -- EPSG:2180, jednostka = metr; kierunek jazdy `d = (sin az, cos az)`; normalna lewa `(-cos az, sin az)`. -- Tolerancje: pozycja `1e-6 m`, azymut `1e-9 rad`. - -## Znane ograniczenia -- **`StraightId` są lokalne per-niweleta** (licznik startuje od 1 w każdej niwelecie), więc NIE są - globalnie unikalne. `TrackParallelism` referuje proste po samym `StraightId` — działa dla luźnych - obiektów, ale w projekcie z wieloma niweletami trzeba by referować `(NiweletaId, StraightId)`. - Do przemyślenia, jeśli równoległość ma być trwała/serializowana. - -## Następne kroki (do decyzji / do zrobienia) -1. **Klotoidy w łuku koszowym** (między łukami i/lub na końcach). (NIE zrobione.) -2. Asymetryczne klotoidy w `fit_between_straights` (teraz tylko symetryczne). (NIE zrobione.) -3. **Rejestr relacji równoległości** + poprawka referencji na `(NiweletaId, StraightId)` i ich serializacja. (NIE.) -4. **Solver** ustawiający prostą równoległą na `derive_parallel_line` i przeliczający resztę. (NIE.) -5. Instalacja `cmake`/`ninja` i budowa przez CMake (na razie tylko `g++`). - -## Preferencje pracy (ustalone z użytkownikiem) -- **Nie edytować `README.md`** (utrzymuje go użytkownik). -- Robić **tylko to, o co proszono** — bez dokładania funkcji z własnej inicjatywy. -- **Oszczędzać CPU**: kompilować tylko zmieniony test, `-fsyntax-only` do szybkiej walidacji, - pełne testy na koniec/na żądanie; bez procesów w tle, przeglądarki i podagentów. -- Język domeny: **niweleta** = jednolity odcinek toru złożony z wielu krzywych w planie i profilu. - -## Git -Repozytorium zainicjalizowane; pliki dodane do stage'a, **brak commitów** (commit dopiero na wyraźną prośbę). diff --git a/maj0sted/README.md b/maj0sted/README.md deleted file mode 100644 index 5f3a916b..00000000 --- a/maj0sted/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# maj0sted - -Statyczna biblioteka **C++20** do obsługi **edytora torowiska**, zbudowana -zgodnie z **Domain-Driven Design (DDD)**. - -Biblioteka dostarcza czysty model domenowy — bez zależności od UI, bazy danych -czy frameworka. Warstwy aplikacji i infrastruktury podpina się do zdefiniowanych -tu typów. - -## Model domenowy - -``` -maj0sted::domain -├── value_objects/ Value Objects (niezmienne, porównywane przez wartość) -│ ├── Crs układ odniesienia (kod EPSG), domyślnie EPSG:2180 -│ └── CartesianPosition pozycja kartezjańska (x, y w jednostkach CRS) -└── MapProject projekt mapy — definiuje CRS dla wszystkich pozycji -``` - -Projekt mapy (`MapProject`) definiuje kartezjański układ odniesienia, w którym -wyrażane są wszystkie pozycje. Domyślnie jest to **EPSG:2180** (PUWG 1992 / -Poland CS92), którego jednostką jest metr. - -## Szybki start - -```cpp -#include "maj0sted/maj0sted.hpp" -using namespace maj0sted::domain; - -MapProject project; // domyślnie EPSG:2180 -int epsg = project.crs().epsg(); // 2180 - -CartesianPosition p{500000.0, 300000.0}; // x, y w metrach -``` - -Pełniejszy przykład: [`examples/basic_editor.cpp`](examples/basic_editor.cpp). - -## Budowanie - -Wymagania: kompilator C++20 (GCC 11+/Clang 14+/MSVC 19.3+) oraz CMake ≥ 3.20. - -```bash -cmake -S . -B build # dodaj -G Ninja, jeśli masz ninja -cmake --build build -ctest --test-dir build --output-on-failure -./build/examples/maj0sted_example -``` - -### Opcje CMake - -| Opcja | Domyślnie | Znaczenie | -|------------------------------|-----------|-------------------------------| -| `MAJ0STED_BUILD_TESTS` | `ON` | buduj testy jednostkowe | -| `MAJ0STED_BUILD_EXAMPLES` | `ON` | buduj przykłady | -| `MAJ0STED_WARNINGS_AS_ERRORS`| `OFF` | traktuj ostrzeżenia jak błędy | - -### Użycie w innym projekcie - -Po `cmake --install build` (albo przez `add_subdirectory`): - -```cmake -find_package(maj0sted REQUIRED) -target_link_libraries(twoj_target PRIVATE maj0sted::maj0sted) -``` - -## Struktura projektu - -``` -maj0sted/ -├── CMakeLists.txt -├── include/maj0sted/ nagłówki publiczne (API) -├── src/domain/ implementacje (.cpp) -├── tests/ testy jednostkowe (CTest, bez zależności) -├── examples/ przykłady użycia -└── cmake/ pliki pakietu find_package -``` - -## Testy - -Testy używają własnego, malutkiego frameworka (`tests/check.hpp`) — nie wymagają -żadnych zewnętrznych bibliotek. Każdy plik testowy to osobny plik wykonywalny -zwracający kod wyjścia dla CTest. - -## Licencja - -Do uzupełnienia (np. MIT) — dodaj plik `LICENSE`. diff --git a/maj0sted/cmake/maj0stedConfig.cmake.in b/maj0sted/cmake/maj0stedConfig.cmake.in deleted file mode 100644 index 33cbabc9..00000000 --- a/maj0sted/cmake/maj0stedConfig.cmake.in +++ /dev/null @@ -1,5 +0,0 @@ -@PACKAGE_INIT@ - -include("${CMAKE_CURRENT_LIST_DIR}/maj0stedTargets.cmake") - -check_required_components(maj0sted) diff --git a/maj0sted/include/maj0sted/maj0sted.hpp b/maj0sted/include/maj0sted/maj0sted.hpp deleted file mode 100644 index 167c15a5..00000000 --- a/maj0sted/include/maj0sted/maj0sted.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -// maj0sted — the model behind a railway track-layout editor ("edytor -// torowiska"). One header pulls in the whole public surface. -// -// The shape of it: a Document is authored (construction lines, catalogue -// turnout types and their placements, tracks made of elements), `solve` turns it -// into a Solution, and nothing ever travels back the other way. - -#include "maj0sted/version.hpp" - -// The authored model, and what solving it produces. -#include "maj0sted/editor/model.hpp" -#include "maj0sted/editor/solution.hpp" - -// Solving: one track's chain, and a whole document in dependency order. -#include "maj0sted/editor/chain.hpp" -#include "maj0sted/editor/layout.hpp" - -// Geometry primitives shared by the solver and the renderer. -#include "maj0sted/domain/geometry/segment_layout.hpp" -#include "maj0sted/domain/geometry/turnout.hpp" - -// Presentation and IO. -#include "maj0sted/editor/render.hpp" -#include "maj0sted/io/document_io.hpp" -#include "maj0sted/io/scn_export.hpp" diff --git a/maj0sted/include/maj0sted/render/scene.hpp b/maj0sted/include/maj0sted/render/scene.hpp deleted file mode 100644 index 41812153..00000000 --- a/maj0sted/include/maj0sted/render/scene.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -namespace maj0sted::render { - -/// A point in the project's CRS (metres for EPSG:2180). -struct Point { - double x; - double y; -}; - -/// Which kind of plan element a polyline came from (lets a GUI colour it). -enum class ElementKind { Straight, Arc, Transition }; - -} // namespace maj0sted::render diff --git a/maj0sted/include/maj0sted/version.hpp b/maj0sted/include/maj0sted/version.hpp deleted file mode 100644 index 4f280447..00000000 --- a/maj0sted/include/maj0sted/version.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -// Version of the maj0sted library. Keep in sync with project() in CMakeLists.txt. -#define MAJ0STED_VERSION_MAJOR 0 -#define MAJ0STED_VERSION_MINOR 1 -#define MAJ0STED_VERSION_PATCH 0 -#define MAJ0STED_VERSION_STRING "0.1.0" diff --git a/maj0sted/tests/CMakeLists.txt b/maj0sted/tests/CMakeLists.txt deleted file mode 100644 index e7503354..00000000 --- a/maj0sted/tests/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -add_executable(maj0sted_test_chain test_chain.cpp) -target_link_libraries(maj0sted_test_chain PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_chain PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME chain COMMAND maj0sted_test_chain) - -add_executable(maj0sted_test_hold test_hold.cpp) -target_link_libraries(maj0sted_test_hold PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_hold PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME hold COMMAND maj0sted_test_hold) - -add_executable(maj0sted_test_lines test_lines.cpp) -target_link_libraries(maj0sted_test_lines PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_lines PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME lines COMMAND maj0sted_test_lines) - -add_executable(maj0sted_test_graph test_graph.cpp) -target_link_libraries(maj0sted_test_graph PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_graph PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME graph COMMAND maj0sted_test_graph) - -add_executable(maj0sted_test_format test_format.cpp) -target_link_libraries(maj0sted_test_format PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_format PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME format COMMAND maj0sted_test_format) - -add_executable(maj0sted_test_turnout test_turnout.cpp) -target_link_libraries(maj0sted_test_turnout PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_turnout PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME turnout COMMAND maj0sted_test_turnout) - -add_executable(maj0sted_test_scn test_scn.cpp) -target_link_libraries(maj0sted_test_scn PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_scn PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME scn COMMAND maj0sted_test_scn) - -add_executable(maj0sted_test_join test_join.cpp) -target_link_libraries(maj0sted_test_join PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_join PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME join COMMAND maj0sted_test_join) - -add_executable(maj0sted_test_tile_cache test_tile_cache.cpp) -target_link_libraries(maj0sted_test_tile_cache PRIVATE maj0sted::maj0sted) -target_include_directories(maj0sted_test_tile_cache PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -add_test(NAME tile_cache COMMAND maj0sted_test_tile_cache) -