diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1b5d489..493339a8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,7 +281,6 @@ if(NOT DEFINED RX_MODULES)
importers
scene
terrain
- edit
world
render
ui/imgui
@@ -304,6 +303,7 @@ if(NOT DEFINED RX_MODULES)
locomotion
ui/ugui
app
+ editor
)
endif()
diff --git a/apps/editor/CMakeLists.txt b/apps/editor/CMakeLists.txt
index d17d09c1..cffb2a9c 100644
--- a/apps/editor/CMakeLists.txt
+++ b/apps/editor/CMakeLists.txt
@@ -1,21 +1,9 @@
-# rx editor: an app::Application on app::Host with its entire UI in rx::ui
-# (libultragui in draw-data mode). The ugui backend, platform shim and pipeline
-# shaders live in rxe/ui/ugui now, because the engine splash needs them too.
-
-add_executable(rx_editor
- main.cc
- editor_app.cc
- editor_terrain.cc
- editor_ui.cc
- editor_input.cc)
+# The default rx editor: rx::editor (rxe/editor) on app::Host. A game builds its
+# own editor the same way, linking its modules next to rx::editor.
+add_executable(rx_editor_app main.cc)
+# rx_editor is the rx::editor module; the binary keeps the name users run.
+set_target_properties(rx_editor_app PROPERTIES OUTPUT_NAME rx_editor)
+target_link_libraries(rx_editor_app PRIVATE rx::editor rx::app rx::foundation)
# An engine build: the tiers ship loose beside it, to be edited.
-rx_stage_content(rx_editor LOOSE_ENGINE_CONFIG)
-
-target_link_libraries(rx_editor PRIVATE
- rx::app rx::ui rx::edit rx::terrain rx::render rx::anim rx::gltf rx::usd rx::blend rx::asset rx::scene rx::ecs rx::window rx::events rx::foundation
- # Bake World: the same cook rxworld runs, so an archive from either is the same bytes.
- rx::world)
-
-target_compile_definitions(rx_editor PRIVATE
- RX_EDITOR_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}/ui"
- RX_BLEND_CONVERTER_SCRIPT="${PROJECT_SOURCE_DIR}/tools/blend_to_glb.py")
+rx_stage_content(rx_editor_app LOOSE_ENGINE_CONFIG)
+rx_set_warnings(rx_editor_app)
diff --git a/apps/editor/main.cc b/apps/editor/main.cc
index 4665d7aa..775619a8 100644
--- a/apps/editor/main.cc
+++ b/apps/editor/main.cc
@@ -5,8 +5,8 @@
#include
#include "base/strings/xstring.h"
-#include "editor_app.h"
#include "rxe/app/host.h"
+#include "rxe/editor/editor_app.h"
int main(int argc, char** argv) {
base::String open_path;
@@ -15,9 +15,6 @@ int main(int argc, char** argv) {
if (!a.empty() && a[0] != '-') open_path = a;
}
-#if defined(RX_SHARED_BUILD)
- rx::base::InitOptionsFromEnv();
-#endif
rx::app::AppConfig config;
config.id = "xn5ec6v99hcwg9d8xzbqshr0";
diff --git a/apps/rxworld/CMakeLists.txt b/apps/rxworld/CMakeLists.txt
index df29924f..a9233a52 100644
--- a/apps/rxworld/CMakeLists.txt
+++ b/apps/rxworld/CMakeLists.txt
@@ -1,3 +1,3 @@
add_executable(rxworld main.cc)
-target_link_libraries(rxworld PRIVATE rx::world rx::edit rx::asset rx::ecs rx::foundation)
+target_link_libraries(rxworld PRIVATE rx::world rx::asset rx::ecs rx::foundation)
rx_set_warnings(rxworld)
diff --git a/apps/shell/CMakeLists.txt b/apps/shell/CMakeLists.txt
index 92a8a2d8..0bff9ad2 100644
--- a/apps/shell/CMakeLists.txt
+++ b/apps/shell/CMakeLists.txt
@@ -40,7 +40,7 @@ set(RX_RUNTIME_MODULES
rx::blend
rx::scene
# .rxscene text scenes: component reflection + the text loader.
- rx::edit
+
# --world: baked worlds streamed around the camera.
rx::world
# --authoring-endpoint / --dump-commands: the live script command surface.
@@ -125,7 +125,7 @@ endif()
add_library(viewer_scene_authoring STATIC scene_authoring.cc)
target_include_directories(viewer_scene_authoring PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(viewer_scene_authoring PUBLIC
- rx::gltf rx::materialx rx::edit rx::scene rx::ecs rx::asset rx::render rx::foundation)
+ rx::gltf rx::materialx rx::scene rx::ecs rx::asset rx::render rx::foundation)
rx_set_warnings(viewer_scene_authoring)
add_executable(rx main.cc ${RX_RUNTIME_SOURCES})
diff --git a/cmake/install.cmake b/cmake/install.cmake
index 3bd5968a..0993c178 100644
--- a/cmake/install.cmake
+++ b/cmake/install.cmake
@@ -37,7 +37,7 @@ set(RX_DEPS_INCDIR ${CMAKE_INSTALL_INCLUDEDIR}/rx-deps)
# rx module targets + export set
set(RX_MODULE_NAMES foundation events window gpu ecs script asset gltf usd materialx blend scene terrain render imgui_renderer render2d physics vehicles locomotion anim audio
- weather rpc devtools character inventory inventory_world ui app)
+ weather rpc devtools character inventory inventory_world ui app world editor)
set(RX_INSTALL_TARGETS)
foreach(_m ${RX_MODULE_NAMES})
# Some modules are conditional (inventory_world only when rx_physics exists);
diff --git a/docs/CONFIG.md b/docs/CONFIG.md
index 4f186a01..c9d85650 100644
--- a/docs/CONFIG.md
+++ b/docs/CONFIG.md
@@ -70,7 +70,7 @@ reproduces the layout beside build-tree executables, re-copied every build:
```cmake
rx_stage_content(mygame mytool) # Data/ beside both (same directory)
-rx_stage_content(rx_editor LOOSE_ENGINE_CONFIG) # engine builds: + rxe/config/
+rx_stage_content(rx_editor_app LOOSE_ENGINE_CONFIG) # engine builds: + rxe/config/
add_custom_target(mygame_config ALL COMMAND ${CMAKE_COMMAND} -E
copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/config $/config)
add_dependencies(mygame mygame_config)
diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md
index 76ba2e33..08d29f1e 100644
--- a/docs/STRUCTURE.md
+++ b/docs/STRUCTURE.md
@@ -74,11 +74,12 @@ rxe/ the engine (Chromium: content/)
world_bake/ offline world baking (tools and the editor link it, games do not)
devtools/ the command bridge and endpoint (rxcall, agents)
app/ Host, Application, AppConfig, platform config, world clock
+ terrain/ heightfield terrain (the editor edits it, so it is engine)
editor/ the editor itself: selection, undo, panels, editor ui
resources/ everything in rxe://: fonts/, config/
plugins/ optional, enabled per app (Chromium: components/)
- character/ combat/ inventory/ locomotion/ placement/ terrain/
+ character/ combat/ inventory/ locomotion/ placement/
nav/ nav/ + nav_debug/ (the only half that knows the renderer)
replication/ replication/ + replication_debug/
vehicles/ cars, boats, aircraft, kites: physics, profiles, engine audio
@@ -124,8 +125,10 @@ of that:
`ecs`, `scene`, `script`, `world` or `app`. They work on their own handles, so
they can be tested without an entity world, and `scene`/`app` are the only
places that bind them to entities. This already holds today; the rule keeps it.
-- **Nothing depends on `app`.** It is the engine's composition root: the only
- module that knows every subsystem, with no feature logic of its own.
+- **Nothing depends on `app` except apps and `editor`.** It is the engine's
+ composition root: the only module that knows every subsystem, with no feature
+ logic of its own. The editor is the one engine module that is itself an
+ application (games extend it), so it sits on the host the way an app does.
- **Nothing a shipping game must link depends on `editor`, `world_bake` or
`importers/usd`.** An app gets them only by asking.
@@ -424,7 +427,12 @@ and after.
local `export.h` workarounds are gone) and ships in the install package.
`RX_PLUGIN`, `PluginRegistry` and `rx_add_app` wait for a plugin that
needs startup registration; none does today.
- - 6c: `rxe/editor` and a thin `apps/editor`, per-game editors.
+ - 6c (done): `rxe/editor` (`rx::editor`: the editor app code plus
+ selection and undo from `edit`) and `apps/editor`, now a `main.cc`. A
+ game's editor is its own `main.cc` over `rx::editor`. `terrain` moves
+ from `plugins/` into `rxe/`: terrain editing is built into the editor, and
+ an engine module cannot depend on a plugin. It can return to `plugins/`
+ with its editor mode once the editor has an extension point.
- 6d: `EngineContext` goes away; the demos move to `apps/shell/demos` in
`rx::shell`.
7. **Renderer features.** A separate design note for `RenderFeature`, then split
diff --git a/plugins/inventory/README.md b/plugins/inventory/README.md
index e633fa01..4d6eaaa3 100644
--- a/plugins/inventory/README.md
+++ b/plugins/inventory/README.md
@@ -79,7 +79,7 @@ after any bulk removal so equipped slots referencing vanished items clear.
Inventories and world items serialize to compact, explicit-little-endian blobs
(`byte_io.h`): a 4-byte magic + `u32` version + records. This was chosen over
-`rxe/edit/` reflection + `.rxscene` deliberately:
+`rxe/scene/` reflection + `.rxscene` deliberately:
- Inventories are **frequently-mutated gameplay state** written to a *game save
file*, not editor scene documents. They want a tiny, stable, self-describing
diff --git a/plugins/inventory/serialize.h b/plugins/inventory/serialize.h
index ab3fb0d4..83a32d35 100644
--- a/plugins/inventory/serialize.h
+++ b/plugins/inventory/serialize.h
@@ -7,7 +7,7 @@
#include "foundation/build_config/export.h"
// Compact, versioned, explicit-little-endian persistence for inventories and
-// equipment. A self-contained binary blob is used rather than edit::/.rxscene
+// equipment. A self-contained binary blob is used rather than editor::/.rxscene
// reflection: inventories are frequently-mutated gameplay state saved to a game
// save file, not editor scene documents, and the blob wants to be stable,
// tiny and independent of the editor module's schema. See the module README for
diff --git a/rxe/edit/CMakeLists.txt b/rxe/edit/CMakeLists.txt
deleted file mode 100644
index 15249448..00000000
--- a/rxe/edit/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-rx_add_module(edit
- selection.cc
- undo.cc
-)
-
-# Editor state over the scene: undo/redo and selection. Reflection, the
-# transform hierarchy and .rxscene io live in rx::scene, because a game needs
-# them without the editor. Deliberately NOT on rx::render (the editor UI links
-# render separately and drives it through the FrameView contract).
-target_link_libraries(rx_edit PUBLIC rx::foundation rx::ecs rx::scene rx::asset)
-
-if(RX_BUILD_TESTS)
- # Editor foundations test: reflection, scene round-trip, undo/redo and hierarchy
- # composition. Fully headless (no GPU), so it always runs under plain ctest.
- add_executable(edit_test edit_test.cc)
- target_link_libraries(edit_test PRIVATE rx::edit rx::scene rx::ecs rx::asset rx::foundation)
- add_test(NAME edit_test COMMAND edit_test)
-endif()
diff --git a/rxe/editor/CMakeLists.txt b/rxe/editor/CMakeLists.txt
new file mode 100644
index 00000000..5927c2d0
--- /dev/null
+++ b/rxe/editor/CMakeLists.txt
@@ -0,0 +1,32 @@
+# rx::editor: the editor itself, as a library a game links into its own editor
+# app (apps/editor is the default one: a main.cc over this module). Editing
+# state (undo/redo, selection), the ugui interface, terrain and surface
+# placement tools, import and world baking. Reflection, the transform hierarchy
+# and .rxscene io live in rx::scene, because a game needs them without the
+# editor.
+rx_add_module(editor
+ editor_app.cc
+ editor_terrain.cc
+ editor_ui.cc
+ editor_input.cc
+ selection.cc
+ undo.cc
+)
+
+target_link_libraries(rx_editor PUBLIC
+ rx::app rx::ui rx::terrain rx::render rx::anim rx::gltf rx::usd rx::blend rx::asset
+ rx::scene rx::ecs rx::window rx::events rx::foundation
+ # Bake World: the same cook rxworld runs, so an archive from either is the same bytes.
+ rx::world)
+
+target_compile_definitions(rx_editor PRIVATE
+ RX_EDITOR_UI_DIR="${CMAKE_CURRENT_SOURCE_DIR}/ui"
+ RX_BLEND_CONVERTER_SCRIPT="${PROJECT_SOURCE_DIR}/tools/blend_to_glb.py")
+
+if(RX_BUILD_TESTS)
+ # Editing model test: reflection, scene round-trip, undo/redo and hierarchy
+ # composition. Fully headless (no GPU), so it always runs under plain ctest.
+ add_executable(edit_test edit_test.cc)
+ target_link_libraries(edit_test PRIVATE rx::editor rx::scene rx::ecs rx::asset rx::foundation)
+ add_test(NAME edit_test COMMAND edit_test)
+endif()
diff --git a/rxe/edit/edit_test.cc b/rxe/editor/edit_test.cc
similarity index 99%
rename from rxe/edit/edit_test.cc
rename to rxe/editor/edit_test.cc
index 386b8730..a3afa9a8 100644
--- a/rxe/edit/edit_test.cc
+++ b/rxe/editor/edit_test.cc
@@ -16,15 +16,15 @@
#include "rxe/asset/asset_id.h"
#include "rxe/asset/vfs.h"
#include "rxe/ecs/world.h"
-#include "rxe/edit/selection.h"
-#include "rxe/edit/undo.h"
+#include "rxe/editor/selection.h"
+#include "rxe/editor/undo.h"
#include "rxe/scene/components.h"
#include "rxe/scene/hierarchy.h"
#include "rxe/scene/reflect.h"
#include "rxe/scene/scene_io.h"
using namespace rx;
-using namespace rx::edit;
+using namespace rx::editor;
namespace {
diff --git a/apps/editor/editor_app.cc b/rxe/editor/editor_app.cc
similarity index 99%
rename from apps/editor/editor_app.cc
rename to rxe/editor/editor_app.cc
index c318f596..0b86a92f 100644
--- a/apps/editor/editor_app.cc
+++ b/rxe/editor/editor_app.cc
@@ -870,7 +870,7 @@ void Editor::OnUpdate(f32 dt) {
if (!ctrl && editor_mode_ == EditorMode::kSelect && over_vp &&
edge(ui::Key::kDelete)) {
if (ecs::Entity e = selection_.primary()) {
- undo_.Push(*world_, edit::MakeDestroyEntity(*world_, e));
+ undo_.Push(*world_, editor::MakeDestroyEntity(*world_, e));
selection_.Clear();
MarkDirty();
doc_dirty_ = true;
@@ -1099,7 +1099,7 @@ void Editor::UpdateGizmo(f32 mx, f32 my, bool lmb_down, bool lmb_edge) {
const scene::ComponentDesc *comp = scene::FindComponentByName("Transform");
if (comp) {
undo_.Push(*world_,
- edit::MakeSetProp(*world_, e, *comp, comp->props[0],
+ editor::MakeSetProp(*world_, e, *comp, comp->props[0],
scene::PropValue::Vec3(np.x, np.y, np.z)));
doc_dirty_ = true;
}
@@ -1577,10 +1577,10 @@ void Editor::RunAutopilot() {
selection_.Set(e);
undo_.BeginGroup("Move");
undo_.Push(*world_,
- edit::MakeSetProp(*world_, e, *xf, xf->props[0],
+ editor::MakeSetProp(*world_, e, *xf, xf->props[0],
scene::PropValue::Vec3(-1.2f, 0.55f, 1.0f)));
undo_.Push(*world_,
- edit::MakeSetProp(*world_, e, *xf, xf->props[0],
+ editor::MakeSetProp(*world_, e, *xf, xf->props[0],
scene::PropValue::Vec3(-1.2f, 0.55f, 2.0f)));
undo_.EndGroup();
doc_dirty_ = true;
diff --git a/apps/editor/editor_app.h b/rxe/editor/editor_app.h
similarity index 98%
rename from apps/editor/editor_app.h
rename to rxe/editor/editor_app.h
index 9b88abe0..0309ce8f 100644
--- a/apps/editor/editor_app.h
+++ b/rxe/editor/editor_app.h
@@ -20,13 +20,13 @@
#include "base/memory/move.h"
#include "base/optional.h"
#include "base/strings/xstring.h"
-#include "plugins/terrain/terrain.h"
-#include "rxe/edit/selection.h"
-#include "rxe/edit/undo.h"
+#include "rxe/editor/selection.h"
+#include "rxe/editor/undo.h"
#include "rxe/scene/fly_camera.h"
#include "rxe/scene/hierarchy.h"
#include "rxe/scene/reflect.h"
#include "rxe/scene/scene_io.h"
+#include "rxe/terrain/terrain.h"
#include "rxe/ui/ugui/ugui_backend.h"
#include "rxe/ui/ugui/ugui_platform.h"
#include "rxe/world/world_bake.h"
@@ -262,8 +262,8 @@ class Editor final : public app::Application {
// editor state
scene::FlyCamera camera_;
- edit::Selection selection_;
- edit::UndoStack undo_;
+ editor::Selection selection_;
+ editor::UndoStack undo_;
base::Optional assets_; // constructed once vfs is known
GizmoMode gizmo_mode_ = GizmoMode::kTranslate;
EditorMode editor_mode_ = EditorMode::kSelect;
diff --git a/apps/editor/editor_input.cc b/rxe/editor/editor_input.cc
similarity index 98%
rename from apps/editor/editor_input.cc
rename to rxe/editor/editor_input.cc
index fe70d17b..92dd4bdf 100644
--- a/apps/editor/editor_input.cc
+++ b/rxe/editor/editor_input.cc
@@ -3,7 +3,7 @@
#include "rxe/ui/events/input.h"
#include "rxe/ui/events/input_bindings.h"
-namespace rx {
+namespace rx::editor {
void RegisterEditorInput(ui::InputMap& map) {
map.RegisterAction(Action::kMoveForward, "move_forward");
@@ -57,4 +57,4 @@ void RegisterEditorInput(ui::InputMap& map) {
});
}
-} // namespace rx
+} // namespace rx::editor
diff --git a/apps/editor/editor_input.h b/rxe/editor/editor_input.h
similarity index 92%
rename from apps/editor/editor_input.h
rename to rxe/editor/editor_input.h
index 62052efb..134f52a3 100644
--- a/apps/editor/editor_input.h
+++ b/rxe/editor/editor_input.h
@@ -7,7 +7,7 @@ namespace rx::ui {
class InputMap;
} // namespace rx::ui
-namespace rx {
+namespace rx::editor {
// The editor's action/axis set. The engine owns no verbs, so the app defines
@@ -31,6 +31,6 @@ enum class Axis : ui::AxisId { kMoveX, kMoveY, kLookX, kLookY, kCount };
void RegisterEditorInput(ui::InputMap& map);
-} // namespace rx
+} // namespace rx::editor
#endif // RX_EDITOR_INPUT_H_
diff --git a/apps/editor/editor_terrain.cc b/rxe/editor/editor_terrain.cc
similarity index 99%
rename from apps/editor/editor_terrain.cc
rename to rxe/editor/editor_terrain.cc
index b32dc45e..cbdc55a2 100644
--- a/apps/editor/editor_terrain.cc
+++ b/rxe/editor/editor_terrain.cc
@@ -42,7 +42,7 @@ u32 PackRgba(const base::Array& color) {
(static_cast(color[2]) << 8) | color[3];
}
-class TerrainCommand final : public edit::Command {
+class TerrainCommand final : public editor::Command {
public:
using Refresh = base::Function)>;
@@ -452,7 +452,7 @@ void Editor::UpdateModeInteraction(bool lmb_down, bool lmb_edge) {
initial.push_back(
{renderable, {{&renderable->props[0], scene::PropValue::AssetIdV(placement_.mesh.hash)}}});
initial.push_back({name, {{&name->props[0], scene::PropValue::String(placement_.name)}}});
- undo_.Push(*world_, edit::MakeCreateEntity(base::move(initial), nullptr));
+ undo_.Push(*world_, editor::MakeCreateEntity(base::move(initial), nullptr));
doc_dirty_ = true;
MarkDirty();
};
diff --git a/apps/editor/editor_ui.cc b/rxe/editor/editor_ui.cc
similarity index 99%
rename from apps/editor/editor_ui.cc
rename to rxe/editor/editor_ui.cc
index b51bc357..374e7822 100644
--- a/apps/editor/editor_ui.cc
+++ b/rxe/editor/editor_ui.cc
@@ -1193,7 +1193,7 @@ bool Editor::RouteClick(const base::String &name, ugui::MouseButton) {
initial.push_back({xf, {}});
initial.push_back(
{nm, {{&nm->props[0], scene::PropValue::String("Empty")}}});
- undo_.Push(*world_, edit::MakeCreateEntity(base::move(initial), &out));
+ undo_.Push(*world_, editor::MakeCreateEntity(base::move(initial), &out));
selection_.Set(out);
doc_dirty_ = true;
MarkDirty();
@@ -1201,7 +1201,7 @@ bool Editor::RouteClick(const base::String &name, ugui::MouseButton) {
}
if (name == "hier_del") {
if (ecs::Entity e = selection_.primary()) {
- undo_.Push(*world_, edit::MakeDestroyEntity(*world_, e));
+ undo_.Push(*world_, editor::MakeDestroyEntity(*world_, e));
selection_.Clear();
doc_dirty_ = true;
MarkDirty();
@@ -1229,7 +1229,7 @@ bool Editor::RouteClick(const base::String &name, ugui::MouseButton) {
ecs::ComponentId id = tail_u("insp_add_");
if (const scene::ComponentDesc *c = scene::FindComponent(id))
if (ecs::Entity e = selection_.primary()) {
- undo_.Push(*world_, edit::MakeAddComponent(*world_, e, *c));
+ undo_.Push(*world_, editor::MakeAddComponent(*world_, e, *c));
add_menu_open_ = false;
doc_dirty_ = true;
MarkDirty();
@@ -1240,7 +1240,7 @@ bool Editor::RouteClick(const base::String &name, ugui::MouseButton) {
ecs::ComponentId id = tail_u("insp_rm_");
if (const scene::ComponentDesc *c = scene::FindComponent(id))
if (ecs::Entity e = selection_.primary()) {
- undo_.Push(*world_, edit::MakeRemoveComponent(*world_, e, *c));
+ undo_.Push(*world_, editor::MakeRemoveComponent(*world_, e, *c));
doc_dirty_ = true;
MarkDirty();
}
@@ -1256,7 +1256,7 @@ bool Editor::RouteClick(const base::String &name, ugui::MouseButton) {
c->props[pi].type == scene::PropType::kBool) {
scene::PropValue v;
scene::GetProp(*world_, e, *c, c->props[pi], &v);
- undo_.Push(*world_, edit::MakeSetProp(*world_, e, *c, c->props[pi],
+ undo_.Push(*world_, editor::MakeSetProp(*world_, e, *c, c->props[pi],
scene::PropValue::Bool(!v.b)));
doc_dirty_ = true;
MarkDirty();
@@ -1516,14 +1516,14 @@ void Editor::UpdateScrub() {
euler[scrub_.axis] = scrub_.base_value + dx * scrub_.step;
Quat q = EulerToQuat(euler);
undo_.Push(*world_,
- edit::MakeSetProp(*world_, scrub_.entity, *scrub_.comp, pd,
+ editor::MakeSetProp(*world_, scrub_.entity, *scrub_.comp, pd,
scene::PropValue::Quat(q.x, q.y, q.z, q.w)));
} else {
if (pd.min != pd.max)
nv = rx::Clamp(nv, pd.min, pd.max);
scene::PropValue out = v;
out.f[scrub_.axis] = nv;
- undo_.Push(*world_, edit::MakeSetProp(*world_, scrub_.entity, *scrub_.comp,
+ undo_.Push(*world_, editor::MakeSetProp(*world_, scrub_.entity, *scrub_.comp,
pd, out));
}
doc_dirty_ = true;
diff --git a/rxe/edit/selection.cc b/rxe/editor/selection.cc
similarity index 91%
rename from rxe/edit/selection.cc
rename to rxe/editor/selection.cc
index a3f08038..ce489790 100644
--- a/rxe/edit/selection.cc
+++ b/rxe/editor/selection.cc
@@ -1,8 +1,8 @@
-#include "rxe/edit/selection.h"
+#include "rxe/editor/selection.h"
#include "base/algorithm.h"
-namespace rx::edit {
+namespace rx::editor {
void Selection::Clear() {
entities_.clear();
@@ -41,4 +41,4 @@ bool Selection::Contains(ecs::Entity entity) const {
return base::Find(entities_.begin(), entities_.end(), entity) != entities_.end();
}
-} // namespace rx::edit
+} // namespace rx::editor
diff --git a/rxe/edit/selection.h b/rxe/editor/selection.h
similarity index 93%
rename from rxe/edit/selection.h
rename to rxe/editor/selection.h
index 54a4730b..4ac81abf 100644
--- a/rxe/edit/selection.h
+++ b/rxe/editor/selection.h
@@ -7,12 +7,12 @@
#include "foundation/build_config/export.h"
#include "rxe/ecs/entity.h"
-namespace rx::edit {
+namespace rx::editor {
// The set of currently selected entities. The "primary" is the anchor for
// single-target operations (the gizmo pivot, the inspector's subject): the most
// recently added or set entity, and it stays valid as long as it is in the set.
-class RX_EDIT_EXPORT Selection {
+class RX_EDITOR_EXPORT Selection {
public:
void Clear();
// Replaces the selection with a single entity (becomes primary).
@@ -34,6 +34,6 @@ class RX_EDIT_EXPORT Selection {
ecs::Entity primary_{};
};
-} // namespace rx::edit
+} // namespace rx::editor
#endif // RX_EDIT_SELECTION_H_
diff --git a/apps/editor/ui/editor.ugui b/rxe/editor/ui/editor.ugui
similarity index 100%
rename from apps/editor/ui/editor.ugui
rename to rxe/editor/ui/editor.ugui
diff --git a/rxe/edit/undo.cc b/rxe/editor/undo.cc
similarity index 99%
rename from rxe/edit/undo.cc
rename to rxe/editor/undo.cc
index ad384ec8..20af9ab1 100644
--- a/rxe/edit/undo.cc
+++ b/rxe/editor/undo.cc
@@ -1,4 +1,4 @@
-#include "rxe/edit/undo.h"
+#include "rxe/editor/undo.h"
#include "base/containers/pair.h"
#include "base/containers/vector.h"
@@ -12,7 +12,7 @@
#include "rxe/scene/components.h"
#include "rxe/scene/hierarchy.h"
-namespace rx::edit {
+namespace rx::editor {
namespace {
u64 RandomGuid() {
@@ -444,4 +444,4 @@ base::UniquePointer MakeRemoveComponent(ecs::World &world,
return base::MakeUnique(world, entity, comp);
}
-} // namespace rx::edit
+} // namespace rx::editor
diff --git a/rxe/edit/undo.h b/rxe/editor/undo.h
similarity index 89%
rename from rxe/edit/undo.h
rename to rxe/editor/undo.h
index a8bf7184..03cbc0a4 100644
--- a/rxe/edit/undo.h
+++ b/rxe/editor/undo.h
@@ -15,7 +15,7 @@
// other undo/redo steps is re-resolved through the world rather than dangling
// (see scene::FindByGuid). The factory helpers snapshot whatever prior state
// their Revert needs at construction time.
-namespace rx::edit {
+namespace rx::editor {
class Command {
public:
@@ -25,7 +25,7 @@ class Command {
virtual const char *label() const = 0;
};
-class RX_EDIT_EXPORT UndoStack {
+class RX_EDITOR_EXPORT UndoStack {
public:
// Applies `cmd` immediately, then records it (clearing the redo stack).
// Inside a group the command is applied and buffered into the group.
@@ -65,7 +65,7 @@ class RX_EDIT_EXPORT UndoStack {
};
// Sets a single reflected field. Captures the current value for Revert.
-RX_EDIT_EXPORT base::UniquePointer
+RX_EDITOR_EXPORT base::UniquePointer
MakeSetProp(ecs::World &world, ecs::Entity entity, const scene::ComponentDesc &comp,
const scene::PropDesc &prop, scene::PropValue new_value);
@@ -73,7 +73,7 @@ MakeSetProp(ecs::World &world, ecs::Entity entity, const scene::ComponentDesc &c
// entity's Guid is stable across undo/redo; *out_entity (may be null) receives
// the live handle from the initial Apply inside UndoStack::Push only; a stack
// address is safe, later undo/redo never writes through it.
-RX_EDIT_EXPORT base::UniquePointer MakeCreateEntity(
+RX_EDITOR_EXPORT base::UniquePointer MakeCreateEntity(
base::Vector>>>
initial,
@@ -81,25 +81,25 @@ RX_EDIT_EXPORT base::UniquePointer MakeCreateEntity(
// Destroys an entity; snapshots all reflected components and their props (and
// its Guid) so Revert recreates it faithfully.
-RX_EDIT_EXPORT base::UniquePointer MakeDestroyEntity(ecs::World &world,
+RX_EDITOR_EXPORT base::UniquePointer MakeDestroyEntity(ecs::World &world,
ecs::Entity entity);
// Reparents an entity, preserving its world transform. An invalid new_parent
// unparents it.
-RX_EDIT_EXPORT base::UniquePointer
+RX_EDITOR_EXPORT base::UniquePointer
MakeReparent(ecs::World &world, ecs::Entity entity, ecs::Entity new_parent);
// Adds a default-constructed component (no-op if already present). Revert
// removes it (only if this command added it).
-RX_EDIT_EXPORT base::UniquePointer
+RX_EDITOR_EXPORT base::UniquePointer
MakeAddComponent(ecs::World &world, ecs::Entity entity,
const scene::ComponentDesc &comp);
// Removes a component; snapshots its props so Revert restores them.
-RX_EDIT_EXPORT base::UniquePointer
+RX_EDITOR_EXPORT base::UniquePointer
MakeRemoveComponent(ecs::World &world, ecs::Entity entity,
const scene::ComponentDesc &comp);
-} // namespace rx::edit
+} // namespace rx::editor
#endif // RX_EDIT_UNDO_H_
diff --git a/plugins/terrain/CMakeLists.txt b/rxe/terrain/CMakeLists.txt
similarity index 100%
rename from plugins/terrain/CMakeLists.txt
rename to rxe/terrain/CMakeLists.txt
diff --git a/plugins/terrain/README.md b/rxe/terrain/README.md
similarity index 100%
rename from plugins/terrain/README.md
rename to rxe/terrain/README.md
diff --git a/plugins/terrain/terrain.cc b/rxe/terrain/terrain.cc
similarity index 99%
rename from plugins/terrain/terrain.cc
rename to rxe/terrain/terrain.cc
index 3b3f54e9..e4a7e8a6 100644
--- a/plugins/terrain/terrain.cc
+++ b/rxe/terrain/terrain.cc
@@ -4,7 +4,7 @@
#include "base/numeric_limits.h"
#include "base/optional.h"
#include "foundation/math/scalar.h"
-#include "plugins/terrain/terrain.h"
+#include "rxe/terrain/terrain.h"
#include
#include
diff --git a/plugins/terrain/terrain.h b/rxe/terrain/terrain.h
similarity index 100%
rename from plugins/terrain/terrain.h
rename to rxe/terrain/terrain.h
diff --git a/plugins/terrain/terrain_io.cc b/rxe/terrain/terrain_io.cc
similarity index 99%
rename from plugins/terrain/terrain_io.cc
rename to rxe/terrain/terrain_io.cc
index c7a9edf6..c639cc2a 100644
--- a/plugins/terrain/terrain_io.cc
+++ b/rxe/terrain/terrain_io.cc
@@ -4,7 +4,7 @@
#include "base/strings/string_ref.h"
#include "base/strings/xstring.h"
#include "foundation/math/scalar.h"
-#include "plugins/terrain/terrain.h"
+#include "rxe/terrain/terrain.h"
#include
diff --git a/plugins/terrain/terrain_test.cc b/rxe/terrain/terrain_test.cc
similarity index 99%
rename from plugins/terrain/terrain_test.cc
rename to rxe/terrain/terrain_test.cc
index d34725e4..2229a985 100644
--- a/plugins/terrain/terrain_test.cc
+++ b/rxe/terrain/terrain_test.cc
@@ -6,7 +6,7 @@
#include "foundation/files/file_system.h"
#include "foundation/math/scalar.h"
#include "foundation/strings/format.h"
-#include "plugins/terrain/terrain.h"
+#include "rxe/terrain/terrain.h"
#include
#include
diff --git a/rxe/world/CMakeLists.txt b/rxe/world/CMakeLists.txt
index 97bcaf76..233ebc65 100644
--- a/rxe/world/CMakeLists.txt
+++ b/rxe/world/CMakeLists.txt
@@ -11,7 +11,7 @@ rx_add_module(world
world_overlay.cc
world_stream.cc
)
-target_link_libraries(rx_world PUBLIC rx::foundation rx::ecs rx::asset rx::scene rx::edit)
+target_link_libraries(rx_world PUBLIC rx::foundation rx::ecs rx::asset rx::scene)
if(RX_BUILD_TESTS)
add_executable(world_format_test world_format_test.cc)
@@ -23,7 +23,7 @@ if(RX_BUILD_TESTS)
add_test(NAME world_map_test COMMAND world_map_test)
add_executable(world_stream_test world_stream_test.cc)
- target_link_libraries(world_stream_test PRIVATE rx::world rx::edit rx::asset rx::scene rx::ecs rx::foundation)
+ target_link_libraries(world_stream_test PRIVATE rx::world rx::asset rx::scene rx::ecs rx::foundation)
add_test(NAME world_stream_test COMMAND world_stream_test)
add_executable(world_overlay_test world_overlay_test.cc)
@@ -42,7 +42,7 @@ if(RX_BUILD_TESTS)
# The cook's per-entity verdict, which the editor shows for the selection.
# A label that lies about what an object will become is worse than no label.
add_executable(world_classify_test world_classify_test.cc)
- target_link_libraries(world_classify_test PRIVATE rx::world rx::edit rx::ecs rx::foundation)
+ target_link_libraries(world_classify_test PRIVATE rx::world rx::ecs rx::foundation)
add_test(NAME world_classify_test COMMAND world_classify_test)
endif()
diff --git a/tools/checkincludes/checkincludes.py b/tools/checkincludes/checkincludes.py
index b2861469..9bc8641a 100644
--- a/tools/checkincludes/checkincludes.py
+++ b/tools/checkincludes/checkincludes.py
@@ -23,9 +23,10 @@
# Modules that work on their own handles and must not know the entity world.
ENTITY_FREE = {"foundation", "events", "window", "gpu", "imgui_renderer", "ui", "asset", "audio", "net", "http", "rpc", "physics",
"anim", "render", "render2d"}
-ENTITY_WORLD = {"ecs", "scene", "script", "world", "edit", "devtools", "app"}
-# Headers only the editor and tools may use; a shipping game never links them.
-EDITOR_ONLY = {"rxe/edit/selection.h", "rxe/edit/undo.h", "rxe/world/world_bake.h"}
+ENTITY_WORLD = {"ecs", "scene", "script", "world", "editor", "devtools", "app"}
+# Code only the editor and tools may use; a shipping game never links it.
+EDITOR_ONLY_DIRS = ("rxe/editor/",)
+EDITOR_ONLY = {"rxe/world/world_bake.h"}
HEADER_EXTS = (".h", ".hpp", ".inl", ".def")
SOURCE_EXTS = (".cc", ".cpp", ".c") + HEADER_EXTS
CODE_DIRS = ("foundation", "rxe", "plugins", "apps", "tools")
@@ -186,9 +187,11 @@ def module_rules_of(target):
for mod in sorted(mods):
if mod in ENTITY_FREE and dep_mods & ENTITY_WORLD:
found.append(("entity-free", "%s may not know the entity world" % mod))
- if "app" in dep_mods:
- found.append(("host", "only apps may depend on the host"))
- if rel(dep) in EDITOR_ONLY:
+ # The editor is the one engine module that is itself an application
+ # (games extend it), so it may sit on the host like an app does.
+ if "app" in dep_mods and mod != "editor":
+ found.append(("host", "only apps and the editor may depend on the host"))
+ if mod != "editor" and (rel(dep) in EDITOR_ONLY or rel(dep).startswith(EDITOR_ONLY_DIRS)):
found.append(("editor-only", "a library may not use editor-only code"))
if mod not in plugins and dep_mods & plugins:
found.append(("plugin", "engine module %s may not depend on a plugin" % mod))
diff --git a/tools/rewrite_includes/renames.txt b/tools/rewrite_includes/renames.txt
index 8e2a558d..f8434094 100644
--- a/tools/rewrite_includes/renames.txt
+++ b/tools/rewrite_includes/renames.txt
@@ -398,3 +398,8 @@ symbol rx::kMaxAxes rx::ui::kMaxAxes
symbol rx::ComputeSkyLighting rx::app::ComputeSkyLighting
symbol rx::SkyLighting rx::app::SkyLighting
symbol rx::WorldClock rx::app::WorldClock
+
+# Phase 6c: the editor becomes rx::editor (rxe/editor), terrain joins the engine
+prefix rxe/edit/ rxe/editor/
+prefix plugins/terrain/ rxe/terrain/
+symbol edit:: editor::