diff --git a/PLAN.md b/PLAN.md index 475993c..b30e74e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -8,13 +8,9 @@ 1. **훅 동작 검증** — SessionStart/Stop/Guard 3개 shell 스크립트를 실제로 트리거시켜 확인 - 의존: jq 설치 여부 확인 -## P0.5 — 아키텍처 정렬 - -3a. **3-tier 분리 refactor 2단계** (`docs/contracts/generic-sut-split.md`) — 1단계(신규 모듈 신설)는 commit `pending`로 완료. 2단계는 기존 `EgPlugin`/`EngineBridge`/`EngineBridge.Client` **rename + 폴더 이동** + ArchitectureTests. 단일 BREAKING 커밋. CLAUDE.md §8.1 규칙 준수. - ## P1 — 라이브 검증 (사용자 환경 필요) -4. **engine-bridge v3 라이브 검증** — `HmegDirectStateProvider` wire-up 완료. EgBim adapter의 Space/Viewport 람다를 실값으로 매핑 (`Editor03.PluginInterface` 또는 SUT-side AppManager 진입점 필요 — Q1~Q7). 라이브에서 `curl /scene /camera /selection` 으로 확인. +4. **engine-bridge v3 라이브 검증** — 코드 쪽 완료 (3-tier 분리 2단계 + EgBim 람다 실 매핑). SUT 환경에서 plugin 배치 후 `curl http://localhost:38080/scene /camera /selection`로 실값 확인. PerspectiveCamera cast로 Fov 추출 여부 검증. 5. ~~recorder Gap I-1~~ — **deferred**. UIA poller PoC 결과 본질적 한계 확인 (AutomationPeer 부재 컨트롤은 못 봄). generic WPF DLL injection 또는 AutomationPeer AI 부착 PoC가 선결. ## Follow-ups (non-blocking) diff --git a/PROGRESS.md b/PROGRESS.md index 6f9a43b..e6dc0f5 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -46,14 +46,13 @@ | 2026-04-08 | **이슈 #14 Raw 시나리오 E2E 성공** 🎉 수동 cleanup 없이 box-v6.yaml 재생으로 Box 생성 | player: null-target fallback + foreground switch + leading alt+tab strip + timing preservation, 24 player tests | | 2026-04-09 | engine-bridge v3 D1/D6 scaffold (reflection accessor + 9 tests, EgPlugin) | `IAppManagerAccessor`, `ReflectionEngineStateProvider`, 14 EgPlugin tests | | 2026-04-09 | HmEG 소스 survey + `docs/hmeg-api-survey.md` | Q1~Q7 식별, `HmegDirectStateProvider` 설계 근거 | -| 2026-04-09 | **3-tier 분리 1단계 (incremental)** — `Recordingtest.Bridge.Abstractions` (Generic) + `Recordingtest.Hmeg.Bridge` (HmEG-aware) 신설, `HmegDirectStateProvider` + `ChainedEngineStateProvider` wire-up, 115 tests | CLAUDE.md §8.1 + commit pending | +| 2026-04-09 | **3-tier 분리 1단계 (incremental)** — `Recordingtest.Bridge.Abstractions` (Generic) + `Recordingtest.Hmeg.Bridge` (HmEG-aware) 신설, `HmegDirectStateProvider` + `ChainedEngineStateProvider` wire-up, 115 tests | commit `f6b6e74` | +| 2026-04-09 | **3-tier 분리 2단계** — `EgPlugin` → `Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost`, `EngineBridge` → `Hmeg/Recordingtest.Hmeg.Catalog`, `EngineBridge.Client` → `Hmeg/Recordingtest.Hmeg.Bridge.Client`, `EngineBridge.Probe` → `Hmeg/Recordingtest.Hmeg.Catalog.Probe`, 테스트 동일. `Recordingtest.Architecture.Tests` 11건 추가 (의존 그래프 강제). 126 tests | commit pending | +| 2026-04-09 | **engine-bridge v3 EgBim 람다 wire-up** — `EditorPlugin` base 직접 사용: `RootSpace`, `View(EGViewport:HmEGViewport)`, `AppManager.FileManager.CurrentFile`. `HmegDirectStateProvider` 이제 실값 가능. `Editor02.HmEGAppManager.dll` 참조 추가. 라이브 검증 대기 | commit pending | ## In progress -- **3-tier 분리 (incremental, 1단계 완료, 2단계 대기)** - - 1단계 ✅: 새 계층 모듈 신설 (`Recordingtest.Bridge.Abstractions`, `Recordingtest.Hmeg.Bridge`, 테스트), 인터페이스 추출, EgPlugin이 HmEG-aware provider chain 사용. 115 tests green. commit pending. - - 2단계 ⏳: 기존 `Recordingtest.EgPlugin` → `src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost` + `.Adapter` 폴더/네임스페이스 이동, `Recordingtest.EngineBridge` → `src/Hmeg/Recordingtest.Hmeg.Catalog`, `Recordingtest.EngineBridge.Client` 분할, ArchitectureTests. 다음 세션 작업. -- **engine-bridge v3 라이브 검증** — 1단계 wire-up 완료 후 EgBim adapter에서 Space/Viewport 람다 실 매핑 (Q1~Q7 답 필요). 사용자 환경에서 `curl /scene /camera /selection`. +- **engine-bridge v3 라이브 검증 대기** — 코드 쪽은 완료 (`EditorPlugin.RootSpace`/`View`/`AppManager.FileManager.CurrentFile` 실 매핑). 사용자 환경에서 `curl /scene /camera /selection`로 실값 확인 필요. ## Follow-ups diff --git a/docs/history/2026-04-09_3tier-split-step2-and-v3-wireup.md b/docs/history/2026-04-09_3tier-split-step2-and-v3-wireup.md new file mode 100644 index 0000000..4cf1bc2 --- /dev/null +++ b/docs/history/2026-04-09_3tier-split-step2-and-v3-wireup.md @@ -0,0 +1,138 @@ +# 2026-04-09 — 3-tier 분리 2단계 + engine-bridge v3 EgBim 람다 wire-up + +**이슈**: #10 follow-up (engine-bridge v3) + `docs/contracts/generic-sut-split.md` +**소요 시간**: ~110분 (새 세션 / 동일 날짜 두 번째 블록) +**Context 사용량**: input ~80k / output ~18k tokens (Opus 4.6, 1M context, 새 세션) + +## 작업 + +### 1. 3-tier 분리 2단계 (mass-rename + move) + +기존 EgPlugin/EngineBridge 모듈을 새 계층 폴더로 이동하고 네임스페이스를 일괄 rename. + +**소스 이동 (git mv)**: +| 원본 | 대상 | 계층 | +|---|---|---| +| `src/Recordingtest.EgPlugin/` | `src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/` | App-specific | +| `src/Recordingtest.EngineBridge/` | `src/Hmeg/Recordingtest.Hmeg.Catalog/` | HmEG-aware | +| `src/Recordingtest.EngineBridge.Client/` | `src/Hmeg/Recordingtest.Hmeg.Bridge.Client/` | HmEG-aware | +| `src/Recordingtest.EngineBridge.Probe/` | `src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/` | HmEG-aware | +| `tests/Recordingtest.EgPlugin.Tests/` | `tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/` | App-specific | +| `tests/Recordingtest.EngineBridge.Tests/` | `tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/` | HmEG-aware | +| `tests/Recordingtest.EngineBridge.IntegrationTests/` | `tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/` | HmEG-aware | + +**네임스페이스 rename**: +- `Recordingtest.EgPlugin` → `Recordingtest.Sut.EgBim.PluginHost` +- `Recordingtest.EngineBridge` → `Recordingtest.Hmeg.Catalog` +- `Recordingtest.EngineBridge.Client` → `Recordingtest.Hmeg.Bridge.Client` +- `Recordingtest.EngineBridge.Probe` → `Recordingtest.Hmeg.Catalog.Probe` + +**csproj rename** + `` / `` + ProjectReference 경로 갱신 + `recordingtest.sln` 에서 remove/add. + +**문제/해결**: +- `git mv`가 bin/obj 폴더 때문에 일부 실패 → 해당 폴더 삭제 후 재시도 +- `EngineBridge.Client` 전체 폴더 이동이 계속 permission denied → 파일 단위로 `git mv`해서 해결 +- `Directory.Build.props`의 자동 RootNamespace와 csproj의 수동 RootNamespace 정리 (Sut.EgBim.PluginHost는 수동, Hmeg.Catalog는 수동 덮어쓰기) + +### 2. Architecture Tests 추가 + +`tests/Recordingtest.Architecture.Tests/` — 3-tier 규칙 강제. + +- Generic 모듈 (`Bridge.Abstractions`, `Recorder`, `Player`, `Normalizer`, `DiffReporter`, `Runner`, `SutProber`) 각각이 `HmEG.dll` 또는 `Editor03.PluginInterface` / `Editor02.HmEGAppManager` / `EditorCore` 를 **참조하지 않음** (Theory, 7건) +- HmEG-aware 모듈 (`Hmeg.Bridge`, `Hmeg.Catalog`, `Hmeg.Bridge.Client`) 각각이 app-specific DLL을 **참조하지 않음** (3건) +- `Hmeg.Bridge` 는 `HmEG.dll` 을 **참조함** (positive check, 1건) + +총 11건, 모두 pass. 향후 누가 실수로 generic 모듈에 HmEG 참조를 추가하면 여기서 red. + +### 3. engine-bridge v3 EgBim 람다 wire-up (Q1~Q7 답) + +사용자가 `D:\GiteaAll\EG-BIM_Modeler\EditorPluginInterface` 경로 공유 → read-only survey. + +**확정 (single-file find)**: `EditorPluginInterface/EditorPlugin.cs` + +```csharp +public HmEGAppManager AppManager { get => TriggerStateService.AppManager; set; } +public Space RootSpace { get => AppManager.ViewportManager.RootSpace; } +public ViewportManager ViewportManager { get => AppManager.ViewportManager; } +public EGViewport View { get; set; } // deprecated but still usable +``` + +**HmEGAppManager** (`D:\GiteaAll\EG-BIM_Modeler\HmEGApplicationManagementLibrary\HmEGAppManager.cs`): +- `ViewportManager` — RootSpace 진입점 +- `SelectionManager` — 중앙 선택 상태 (필요 시 hook, 현재는 walk) +- `FileManager` — 저장 파일 경로 +- `AppModeManager` — 명령 lifecycle (Q4 후속) + +**`EGViewport : Control, HmEGViewport`** (`HmEG/Controls/HmEGViewport.cs:43`) — 그대로 HmEG-aware provider에 넘길 수 있음. + +**`FileManager.CurrentFile : string`** — 저장 문서 경로. + +**Q 답 매핑**: +- Q1 Space: `this.RootSpace` ✅ +- Q2 Viewport: `this.View` (EGViewport: HmEGViewport) ✅ +- Q3 Selection: 중앙 리스트 없음. Space walk + `ISelectable.IsSelected` (이미 구현됨) +- Q4 Command lifecycle: `AppModeManager`, `TriggerStateService.TriggerEnded` (별도 contract) +- Q5 Fov: `PerspectiveCamera` cast, `HmegDirectStateProvider.GetCamera`의 reflection `FieldOfView` 후보 chain이 이미 잡음 +- Q6 DocumentPath: `AppManager.FileManager.CurrentFile` ✅ +- Q7 EGViewport↔HmEGViewport: `EGViewport : Control, HmEGViewport` ✅ + +**구현**: `HmEgBridgePlugin.BuildProvider()`가 이제 실 람다 주입: + +```csharp +Func spaceProvider = () => { try { return RootSpace; } catch { return null; } }; +Func viewportProvider = () => { try { return View; } catch { return null; } }; +Func documentPathProvider = () => +{ + try { var p = AppManager?.FileManager?.CurrentFile; return string.IsNullOrEmpty(p) ? null : p; } + catch { return null; } +}; +``` + +**csproj 추가 참조**: `Editor02.HmEGAppManager.dll` — `HmEGAppManager.FileManager.CurrentFile` 접근을 위해. app-specific tier이므로 허용 (ArchitectureTests는 이 tier를 검사하지 않음). + +### 테스트 + +- 전체 suite: **126 tests pass** (115 → 126, +11 ArchitectureTests) +- 구성: Recorder 26 / Player 24 / Sut.EgBim.PluginHost 21 / Normalizer 16 / Architecture 11 / DiffReporter 5 / Runner 6 / Hmeg.Catalog 6 / Hmeg.Catalog.Integration 6 / Hmeg.Bridge 5 +- 빌드/테스트 0 failures + +### 분류 라벨 (2단계 완료 후 현재) + +| 경로 | 계층 | +|---|---| +| `src/Recordingtest.Bridge.Abstractions/` | Generic | +| `src/Recordingtest.Recorder/`, `.Player/`, `.Normalizer/`, `.DiffReporter/`, `.Runner/`, `.SutProber/`, `.DiffReporter.Cli/` | Generic | +| `src/Hmeg/Recordingtest.Hmeg.Bridge/`, `.Catalog/`, `.Catalog.Probe/`, `.Bridge.Client/` | HmEG-aware | +| `src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/` | App-specific (EgBim) | + +## 라이브 검증 (대기) + +다음 세션의 P1: + +1. 본 작업물을 빌드해 `EG-BIM Modeler/Plugins/Recordingtest.Sut.EgBim.PluginHost/` 아래 배포 +2. SUT 실행, 이미 열린 .hmeg 문서가 있으면 Box 등 몇 개 객체 생성 + 선택 +3. 셸에서: + ``` + curl http://localhost:38080/health + curl http://localhost:38080/scene # object_count, document_path + curl http://localhost:38080/camera # eye/target/up/fov 실값 + curl http://localhost:38080/selection # selected_ids + ``` +4. 실값이 기대와 다르면 `HmegDirectStateProvider.GetCamera`의 reflection 멤버 후보 또는 selection walk 로직 보정 1~2회 반복 + +## 미커밋 (다음 커밋에 통합) + +- 3-tier 분리 2단계 전체 (수많은 파일 rename/move) +- `Recordingtest.Architecture.Tests` 신규 +- `HmEgBridgePlugin.BuildProvider` 실 람다 +- `Editor02.HmEGAppManager.dll` 참조 추가 +- `recordingtest.sln`, `PROGRESS.md`, `PLAN.md`, 본 history + +## 관련 + +- `CLAUDE.md §8.1` +- `docs/contracts/generic-sut-split.md` +- `docs/hmeg-api-survey.md` +- `D:\GiteaAll\EG-BIM_Modeler\EditorPluginInterface\EditorPlugin.cs` (read-only) +- `D:\GiteaAll\EG-BIM_Modeler\HmEGApplicationManagementLibrary\HmEGAppManager.cs` (read-only) +- `D:\GiteaAll\EG-BIM_Modeler\HmEGApplicationManagementLibrary\SubManager\FileManager.cs` (read-only) diff --git a/recordingtest.sln b/recordingtest.sln index e919a12..c63bf8c 100644 --- a/recordingtest.sln +++ b/recordingtest.sln @@ -27,20 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Runner", "src EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Runner.Tests", "tests\Recordingtest.Runner.Tests\Recordingtest.Runner.Tests.csproj", "{6F9973EA-977A-4185-AF24-4E76D9D851C8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EngineBridge", "src\Recordingtest.EngineBridge\Recordingtest.EngineBridge.csproj", "{938D464B-B810-425F-83B6-52877B584DE2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EngineBridge.Probe", "src\Recordingtest.EngineBridge.Probe\Recordingtest.EngineBridge.Probe.csproj", "{B1EAD466-9C07-4C07-907C-3D5794F6689D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EngineBridge.Tests", "tests\Recordingtest.EngineBridge.Tests\Recordingtest.EngineBridge.Tests.csproj", "{0811AC32-E2A4-4BFD-A29A-6451F5756F10}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EgPlugin", "src\Recordingtest.EgPlugin\Recordingtest.EgPlugin.csproj", "{51D7B803-5F6E-4B78-9A5D-326F28CD934F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EngineBridge.Client", "src\Recordingtest.EngineBridge.Client\Recordingtest.EngineBridge.Client.csproj", "{45D80D0C-A8A1-4173-B28C-68F0628EE346}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EngineBridge.IntegrationTests", "tests\Recordingtest.EngineBridge.IntegrationTests\Recordingtest.EngineBridge.IntegrationTests.csproj", "{BA346F72-6F9C-4D68-9CDD-DD05F9687095}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.EgPlugin.Tests", "tests\Recordingtest.EgPlugin.Tests\Recordingtest.EgPlugin.Tests.csproj", "{315F3B4F-BF8F-4DBF-8F06-CAF55152725D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Bridge.Abstractions", "src\Recordingtest.Bridge.Abstractions\Recordingtest.Bridge.Abstractions.csproj", "{E9192225-E9F6-44EB-A18E-7F61F1093DA8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Bridge", "src\Hmeg\Recordingtest.Hmeg.Bridge\Recordingtest.Hmeg.Bridge.csproj", "{33D35B3C-9572-432F-8675-6AD7CDF1C0EB}" @@ -51,6 +37,26 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hmeg", "Hmeg", "{FA0FB21B-D EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Bridge.Tests", "tests\Hmeg\Recordingtest.Hmeg.Bridge.Tests\Recordingtest.Hmeg.Bridge.Tests.csproj", "{20FB4AD7-3414-436D-880C-B2D95280DA3D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sut", "Sut", "{79DA188A-9C91-3DBA-2827-6072BD5E3D4F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EgBim", "EgBim", "{7CC28442-33DD-D811-CEDA-9CC787317768}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Sut.EgBim.PluginHost", "src\Sut\EgBim\Recordingtest.Sut.EgBim.PluginHost\Recordingtest.Sut.EgBim.PluginHost.csproj", "{0A800F25-64B6-4F05-BB8E-68E317862CED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Catalog", "src\Hmeg\Recordingtest.Hmeg.Catalog\Recordingtest.Hmeg.Catalog.csproj", "{23D628DC-D98D-427A-B0C0-470E70CC6DD2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Bridge.Client", "src\Hmeg\Recordingtest.Hmeg.Bridge.Client\Recordingtest.Hmeg.Bridge.Client.csproj", "{4E0274C5-39C2-436E-90AA-87DD1C675B4C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Catalog.Probe", "src\Hmeg\Recordingtest.Hmeg.Catalog.Probe\Recordingtest.Hmeg.Catalog.Probe.csproj", "{A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Sut.EgBim.PluginHost.Tests", "tests\Sut\EgBim\Recordingtest.Sut.EgBim.PluginHost.Tests\Recordingtest.Sut.EgBim.PluginHost.Tests.csproj", "{5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Catalog.Tests", "tests\Hmeg\Recordingtest.Hmeg.Catalog.Tests\Recordingtest.Hmeg.Catalog.Tests.csproj", "{A9894277-E1F3-4B86-AAE4-041116FBBE1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Hmeg.Catalog.IntegrationTests", "tests\Hmeg\Recordingtest.Hmeg.Catalog.IntegrationTests\Recordingtest.Hmeg.Catalog.IntegrationTests.csproj", "{3D981C63-0D1E-466C-9BD6-3DAF46936A45}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recordingtest.Architecture.Tests", "tests\Recordingtest.Architecture.Tests\Recordingtest.Architecture.Tests.csproj", "{D35B233B-267B-40DB-87EF-689AEE5C9399}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -205,90 +211,6 @@ Global {6F9973EA-977A-4185-AF24-4E76D9D851C8}.Release|x64.Build.0 = Release|Any CPU {6F9973EA-977A-4185-AF24-4E76D9D851C8}.Release|x86.ActiveCfg = Release|Any CPU {6F9973EA-977A-4185-AF24-4E76D9D851C8}.Release|x86.Build.0 = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|x64.ActiveCfg = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|x64.Build.0 = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|x86.ActiveCfg = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Debug|x86.Build.0 = Debug|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|Any CPU.Build.0 = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|x64.ActiveCfg = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|x64.Build.0 = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|x86.ActiveCfg = Release|Any CPU - {938D464B-B810-425F-83B6-52877B584DE2}.Release|x86.Build.0 = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|x64.ActiveCfg = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|x64.Build.0 = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|x86.ActiveCfg = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Debug|x86.Build.0 = Debug|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|Any CPU.Build.0 = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|x64.ActiveCfg = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|x64.Build.0 = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|x86.ActiveCfg = Release|Any CPU - {B1EAD466-9C07-4C07-907C-3D5794F6689D}.Release|x86.Build.0 = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|x64.ActiveCfg = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|x64.Build.0 = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|x86.ActiveCfg = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Debug|x86.Build.0 = Debug|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|Any CPU.Build.0 = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|x64.ActiveCfg = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|x64.Build.0 = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|x86.ActiveCfg = Release|Any CPU - {0811AC32-E2A4-4BFD-A29A-6451F5756F10}.Release|x86.Build.0 = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|x64.ActiveCfg = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|x64.Build.0 = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|x86.ActiveCfg = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Debug|x86.Build.0 = Debug|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|Any CPU.Build.0 = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|x64.ActiveCfg = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|x64.Build.0 = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|x86.ActiveCfg = Release|Any CPU - {51D7B803-5F6E-4B78-9A5D-326F28CD934F}.Release|x86.Build.0 = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|Any CPU.Build.0 = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|x64.ActiveCfg = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|x64.Build.0 = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|x86.ActiveCfg = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Debug|x86.Build.0 = Debug|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|Any CPU.ActiveCfg = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|Any CPU.Build.0 = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|x64.ActiveCfg = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|x64.Build.0 = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|x86.ActiveCfg = Release|Any CPU - {45D80D0C-A8A1-4173-B28C-68F0628EE346}.Release|x86.Build.0 = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|x64.ActiveCfg = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|x64.Build.0 = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|x86.ActiveCfg = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Debug|x86.Build.0 = Debug|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|Any CPU.Build.0 = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|x64.ActiveCfg = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|x64.Build.0 = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|x86.ActiveCfg = Release|Any CPU - {BA346F72-6F9C-4D68-9CDD-DD05F9687095}.Release|x86.Build.0 = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|x64.ActiveCfg = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|x64.Build.0 = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|x86.ActiveCfg = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Debug|x86.Build.0 = Debug|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|Any CPU.Build.0 = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|x64.ActiveCfg = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|x64.Build.0 = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|x86.ActiveCfg = Release|Any CPU - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D}.Release|x86.Build.0 = Release|Any CPU {E9192225-E9F6-44EB-A18E-7F61F1093DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E9192225-E9F6-44EB-A18E-7F61F1093DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU {E9192225-E9F6-44EB-A18E-7F61F1093DA8}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -325,6 +247,102 @@ Global {20FB4AD7-3414-436D-880C-B2D95280DA3D}.Release|x64.Build.0 = Release|Any CPU {20FB4AD7-3414-436D-880C-B2D95280DA3D}.Release|x86.ActiveCfg = Release|Any CPU {20FB4AD7-3414-436D-880C-B2D95280DA3D}.Release|x86.Build.0 = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|x64.ActiveCfg = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|x64.Build.0 = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|x86.ActiveCfg = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Debug|x86.Build.0 = Debug|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|Any CPU.Build.0 = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|x64.ActiveCfg = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|x64.Build.0 = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|x86.ActiveCfg = Release|Any CPU + {0A800F25-64B6-4F05-BB8E-68E317862CED}.Release|x86.Build.0 = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|x64.ActiveCfg = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|x64.Build.0 = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|x86.ActiveCfg = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Debug|x86.Build.0 = Debug|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|Any CPU.Build.0 = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|x64.ActiveCfg = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|x64.Build.0 = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|x86.ActiveCfg = Release|Any CPU + {23D628DC-D98D-427A-B0C0-470E70CC6DD2}.Release|x86.Build.0 = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|x64.ActiveCfg = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|x64.Build.0 = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|x86.ActiveCfg = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Debug|x86.Build.0 = Debug|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|Any CPU.Build.0 = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|x64.ActiveCfg = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|x64.Build.0 = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|x86.ActiveCfg = Release|Any CPU + {4E0274C5-39C2-436E-90AA-87DD1C675B4C}.Release|x86.Build.0 = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|x64.ActiveCfg = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|x64.Build.0 = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|x86.ActiveCfg = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Debug|x86.Build.0 = Debug|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|Any CPU.Build.0 = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|x64.ActiveCfg = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|x64.Build.0 = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|x86.ActiveCfg = Release|Any CPU + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008}.Release|x86.Build.0 = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|x64.ActiveCfg = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|x64.Build.0 = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|x86.ActiveCfg = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Debug|x86.Build.0 = Debug|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|Any CPU.Build.0 = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|x64.ActiveCfg = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|x64.Build.0 = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|x86.ActiveCfg = Release|Any CPU + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207}.Release|x86.Build.0 = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|x64.Build.0 = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|x86.ActiveCfg = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Debug|x86.Build.0 = Debug|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|Any CPU.Build.0 = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|x64.ActiveCfg = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|x64.Build.0 = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|x86.ActiveCfg = Release|Any CPU + {A9894277-E1F3-4B86-AAE4-041116FBBE1D}.Release|x86.Build.0 = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|x64.Build.0 = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Debug|x86.Build.0 = Debug|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|Any CPU.Build.0 = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|x64.ActiveCfg = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|x64.Build.0 = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|x86.ActiveCfg = Release|Any CPU + {3D981C63-0D1E-466C-9BD6-3DAF46936A45}.Release|x86.Build.0 = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|x64.ActiveCfg = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|x64.Build.0 = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|x86.ActiveCfg = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Debug|x86.Build.0 = Debug|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|Any CPU.Build.0 = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|x64.ActiveCfg = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|x64.Build.0 = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|x86.ActiveCfg = Release|Any CPU + {D35B233B-267B-40DB-87EF-689AEE5C9399}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -341,16 +359,19 @@ Global {7A5C0D53-BDFC-4AF6-8F4D-49E7EB8245F5} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {DADF0474-9EF3-4E8D-8139-93504E4F745D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {6F9973EA-977A-4185-AF24-4E76D9D851C8} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {938D464B-B810-425F-83B6-52877B584DE2} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {B1EAD466-9C07-4C07-907C-3D5794F6689D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {0811AC32-E2A4-4BFD-A29A-6451F5756F10} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {51D7B803-5F6E-4B78-9A5D-326F28CD934F} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {45D80D0C-A8A1-4173-B28C-68F0628EE346} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {BA346F72-6F9C-4D68-9CDD-DD05F9687095} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} - {315F3B4F-BF8F-4DBF-8F06-CAF55152725D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {E9192225-E9F6-44EB-A18E-7F61F1093DA8} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {33D35B3C-9572-432F-8675-6AD7CDF1C0EB} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {FA0FB21B-DC6D-6187-86C3-94DFEB22505D} = {0AB3BF05-4346-4AA6-1389-037BE0695223} {20FB4AD7-3414-436D-880C-B2D95280DA3D} = {FA0FB21B-DC6D-6187-86C3-94DFEB22505D} + {79DA188A-9C91-3DBA-2827-6072BD5E3D4F} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} + {7CC28442-33DD-D811-CEDA-9CC787317768} = {79DA188A-9C91-3DBA-2827-6072BD5E3D4F} + {0A800F25-64B6-4F05-BB8E-68E317862CED} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {23D628DC-D98D-427A-B0C0-470E70CC6DD2} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {4E0274C5-39C2-436E-90AA-87DD1C675B4C} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {A5765A50-21FC-4BC6-97E6-3FE3A1AE6008} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {5D5C57B2-D9BC-4E27-8EB1-49FE2FD78207} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {A9894277-E1F3-4B86-AAE4-041116FBBE1D} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {3D981C63-0D1E-466C-9BD6-3DAF46936A45} = {7CC28442-33DD-D811-CEDA-9CC787317768} + {D35B233B-267B-40DB-87EF-689AEE5C9399} = {0AB3BF05-4346-4AA6-1389-037BE0695223} EndGlobalSection EndGlobal diff --git a/src/Recordingtest.EngineBridge.Client/EngineBridgeException.cs b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/EngineBridgeException.cs similarity index 86% rename from src/Recordingtest.EngineBridge.Client/EngineBridgeException.cs rename to src/Hmeg/Recordingtest.Hmeg.Bridge.Client/EngineBridgeException.cs index 57ccdd4..fa7e276 100644 --- a/src/Recordingtest.EngineBridge.Client/EngineBridgeException.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/EngineBridgeException.cs @@ -1,4 +1,4 @@ -namespace Recordingtest.EngineBridge.Client; +namespace Recordingtest.Hmeg.Bridge.Client; public sealed class EngineBridgeException : Exception { diff --git a/src/Recordingtest.EngineBridge.Client/HmEgHttpSnapshot.cs b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/HmEgHttpSnapshot.cs similarity index 97% rename from src/Recordingtest.EngineBridge.Client/HmEgHttpSnapshot.cs rename to src/Hmeg/Recordingtest.Hmeg.Bridge.Client/HmEgHttpSnapshot.cs index a7880b3..cd5b42a 100644 --- a/src/Recordingtest.EngineBridge.Client/HmEgHttpSnapshot.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/HmEgHttpSnapshot.cs @@ -1,7 +1,8 @@ using System.Net.Http; using System.Text.Json; +using Recordingtest.Hmeg.Catalog; -namespace Recordingtest.EngineBridge.Client; +namespace Recordingtest.Hmeg.Bridge.Client; public sealed class HmEgHttpSnapshot : IEngineSnapshot, IDisposable { diff --git a/src/Recordingtest.EngineBridge.Client/Recordingtest.EngineBridge.Client.csproj b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/Recordingtest.Hmeg.Bridge.Client.csproj similarity index 55% rename from src/Recordingtest.EngineBridge.Client/Recordingtest.EngineBridge.Client.csproj rename to src/Hmeg/Recordingtest.Hmeg.Bridge.Client/Recordingtest.Hmeg.Bridge.Client.csproj index ddfd988..c4aba87 100644 --- a/src/Recordingtest.EngineBridge.Client/Recordingtest.EngineBridge.Client.csproj +++ b/src/Hmeg/Recordingtest.Hmeg.Bridge.Client/Recordingtest.Hmeg.Bridge.Client.csproj @@ -4,9 +4,10 @@ enable enable true - Recordingtest.EngineBridge.Client + Recordingtest.Hmeg.Bridge.Client + Recordingtest.Hmeg.Bridge.Client - + diff --git a/src/Recordingtest.EngineBridge.Probe/Program.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Program.cs similarity index 97% rename from src/Recordingtest.EngineBridge.Probe/Program.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Program.cs index f3cd4dc..0b7bdf9 100644 --- a/src/Recordingtest.EngineBridge.Probe/Program.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Program.cs @@ -1,7 +1,7 @@ using System.Reflection; -using Recordingtest.EngineBridge; +using Recordingtest.Hmeg.Catalog; -namespace Recordingtest.EngineBridge.Probe; +namespace Recordingtest.Hmeg.Catalog.Probe; internal static class Program { diff --git a/src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Recordingtest.Hmeg.Catalog.Probe.csproj b/src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Recordingtest.Hmeg.Catalog.Probe.csproj new file mode 100644 index 0000000..46d02bf --- /dev/null +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog.Probe/Recordingtest.Hmeg.Catalog.Probe.csproj @@ -0,0 +1,10 @@ + + + Exe + Recordingtest.Hmeg.Catalog.Probe + Recordingtest.Hmeg.Catalog.Probe + + + + + diff --git a/src/Recordingtest.EngineBridge/CandidateFinder.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog/CandidateFinder.cs similarity index 99% rename from src/Recordingtest.EngineBridge/CandidateFinder.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog/CandidateFinder.cs index 69dd091..fed0e6c 100644 --- a/src/Recordingtest.EngineBridge/CandidateFinder.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/CandidateFinder.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Text; -namespace Recordingtest.EngineBridge; +namespace Recordingtest.Hmeg.Catalog; public sealed record Candidate( string Category, diff --git a/src/Recordingtest.EngineBridge/CatalogWriter.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog/CatalogWriter.cs similarity index 98% rename from src/Recordingtest.EngineBridge/CatalogWriter.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog/CatalogWriter.cs index f5614d1..a82cb5e 100644 --- a/src/Recordingtest.EngineBridge/CatalogWriter.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/CatalogWriter.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Text.Json; -namespace Recordingtest.EngineBridge; +namespace Recordingtest.Hmeg.Catalog; public sealed record TypeEntry(string Assembly, string TypeName, bool IsPublic, string Namespace); diff --git a/src/Recordingtest.EngineBridge/HmEgSnapshot.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog/HmEgSnapshot.cs similarity index 97% rename from src/Recordingtest.EngineBridge/HmEgSnapshot.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog/HmEgSnapshot.cs index c84b6c6..6595e82 100644 --- a/src/Recordingtest.EngineBridge/HmEgSnapshot.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/HmEgSnapshot.cs @@ -1,4 +1,4 @@ -namespace Recordingtest.EngineBridge; +namespace Recordingtest.Hmeg.Catalog; /// /// Skeleton implementation of for HmEG. diff --git a/src/Recordingtest.EngineBridge/IEngineSnapshot.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog/IEngineSnapshot.cs similarity index 90% rename from src/Recordingtest.EngineBridge/IEngineSnapshot.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog/IEngineSnapshot.cs index f10624b..1ea1868 100644 --- a/src/Recordingtest.EngineBridge/IEngineSnapshot.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/IEngineSnapshot.cs @@ -1,4 +1,4 @@ -namespace Recordingtest.EngineBridge; +namespace Recordingtest.Hmeg.Catalog; public interface IEngineSnapshot { diff --git a/src/Recordingtest.EngineBridge/MetadataLoader.cs b/src/Hmeg/Recordingtest.Hmeg.Catalog/MetadataLoader.cs similarity index 98% rename from src/Recordingtest.EngineBridge/MetadataLoader.cs rename to src/Hmeg/Recordingtest.Hmeg.Catalog/MetadataLoader.cs index ed2b06d..ba23fce 100644 --- a/src/Recordingtest.EngineBridge/MetadataLoader.cs +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/MetadataLoader.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.InteropServices; -namespace Recordingtest.EngineBridge; +namespace Recordingtest.Hmeg.Catalog; /// /// Thin wrapper around . This class is diff --git a/src/Recordingtest.EngineBridge/Recordingtest.EngineBridge.csproj b/src/Hmeg/Recordingtest.Hmeg.Catalog/Recordingtest.Hmeg.Catalog.csproj similarity index 68% rename from src/Recordingtest.EngineBridge/Recordingtest.EngineBridge.csproj rename to src/Hmeg/Recordingtest.Hmeg.Catalog/Recordingtest.Hmeg.Catalog.csproj index 32368f3..42bea8b 100644 --- a/src/Recordingtest.EngineBridge/Recordingtest.EngineBridge.csproj +++ b/src/Hmeg/Recordingtest.Hmeg.Catalog/Recordingtest.Hmeg.Catalog.csproj @@ -1,7 +1,7 @@ - Recordingtest.EngineBridge - Recordingtest.EngineBridge + Recordingtest.Hmeg.Catalog + Recordingtest.Hmeg.Catalog diff --git a/src/Recordingtest.EgPlugin/Recordingtest.EgPlugin.csproj b/src/Recordingtest.EgPlugin/Recordingtest.EgPlugin.csproj deleted file mode 100644 index 57dfe05..0000000 --- a/src/Recordingtest.EgPlugin/Recordingtest.EgPlugin.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - net8.0-windows - true - enable - enable - true - Recordingtest.EgPlugin - true - - - - - - - - ..\..\EG-BIM Modeler\Editor03.PluginInterface.dll - false - - - ..\..\EG-BIM Modeler\HmEG.dll - false - - - diff --git a/src/Recordingtest.EngineBridge.Probe/Recordingtest.EngineBridge.Probe.csproj b/src/Recordingtest.EngineBridge.Probe/Recordingtest.EngineBridge.Probe.csproj deleted file mode 100644 index 0123d7f..0000000 --- a/src/Recordingtest.EngineBridge.Probe/Recordingtest.EngineBridge.Probe.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - Exe - Recordingtest.EngineBridge.Probe - Recordingtest.EngineBridge.Probe - - - - - diff --git a/src/Recordingtest.EgPlugin/BridgeHttpServer.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/BridgeHttpServer.cs similarity index 97% rename from src/Recordingtest.EgPlugin/BridgeHttpServer.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/BridgeHttpServer.cs index 423fba6..2b241be 100644 --- a/src/Recordingtest.EgPlugin/BridgeHttpServer.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/BridgeHttpServer.cs @@ -1,7 +1,7 @@ using System.Net; using System.Text; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// Hosts an HttpListener that delegates path routing to . diff --git a/src/Recordingtest.EgPlugin/ChainedEngineStateProvider.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/ChainedEngineStateProvider.cs similarity index 97% rename from src/Recordingtest.EgPlugin/ChainedEngineStateProvider.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/ChainedEngineStateProvider.cs index d6df74c..973e54b 100644 --- a/src/Recordingtest.EgPlugin/ChainedEngineStateProvider.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/ChainedEngineStateProvider.cs @@ -1,6 +1,6 @@ using Recordingtest.Bridge; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// Tries the primary provider first; if it returns the empty/default value diff --git a/src/Recordingtest.EgPlugin/HmEgBridgePlugin.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/HmEgBridgePlugin.cs similarity index 60% rename from src/Recordingtest.EgPlugin/HmEgBridgePlugin.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/HmEgBridgePlugin.cs index dc6d5f9..e9e7519 100644 --- a/src/Recordingtest.EgPlugin/HmEgBridgePlugin.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/HmEgBridgePlugin.cs @@ -3,7 +3,7 @@ using HmEG; using Recordingtest.Bridge; using Recordingtest.Hmeg.Bridge; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// MEF/PluginLoader-discovered plugin. Inherits the SUT's EditorPlugin @@ -19,8 +19,8 @@ public sealed class HmEgBridgePlugin : EditorPlugin, IDisposable StartBridge(); } - public override string Name => "Recordingtest.EgPlugin"; - public override string Description => "recordingtest engine-bridge v2 (HTTP sidecar)"; + public override string Name => "Recordingtest.Sut.EgBim.PluginHost"; + public override string Description => "recordingtest engine-bridge v3 (HTTP sidecar)"; protected override void Initialize() { @@ -58,13 +58,42 @@ public sealed class HmEgBridgePlugin : EditorPlugin, IDisposable /// private IEngineStateProvider BuildProvider() { - // Lambdas: until the EgBim adapter (Q1/Q2) is filled in, return null - // and let HmegDirectStateProvider fall through to its safe defaults. - // This keeps the wire-up landed; live verification will populate the - // lambdas with the real Editor.AppManager.AppManager entry points. - Func spaceProvider = () => null; - Func viewportProvider = () => null; - Func? documentPathProvider = null; + // EG-BIM Modeler entry points (resolved via EditorPlugin base): + // RootSpace = AppManager.ViewportManager.RootSpace + // View (EGViewport : HmEGViewport) — plugin-injected active viewport + // AppManager.FileManager.CurrentFile — document path on disk + // + // Each lambda is wrapped in try/catch so plugin construction never + // throws even if the host state is in flight at boot time. + Func spaceProvider = () => + { + try { return RootSpace; } + catch { return null; } + }; + + Func viewportProvider = () => + { + try + { + // EGViewport implements HmEGViewport; the base class exposes it + // as EGViewport on the Obsolete View property. We catch and + // return null to survive the obsolete warning at runtime. +#pragma warning disable CS0618 // Obsolete API on EditorPlugin.View + return View; +#pragma warning restore CS0618 + } + catch { return null; } + }; + + Func documentPathProvider = () => + { + try + { + var path = AppManager?.FileManager?.CurrentFile; + return string.IsNullOrEmpty(path) ? null : path; + } + catch { return null; } + }; var direct = new HmegDirectStateProvider(spaceProvider, viewportProvider, documentPathProvider); var fallback = new ReflectionEngineStateProvider(this); diff --git a/src/Recordingtest.EgPlugin/IAppManagerAccessor.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IAppManagerAccessor.cs similarity index 99% rename from src/Recordingtest.EgPlugin/IAppManagerAccessor.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IAppManagerAccessor.cs index e2fe20a..0e56e25 100644 --- a/src/Recordingtest.EgPlugin/IAppManagerAccessor.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IAppManagerAccessor.cs @@ -1,6 +1,6 @@ using System.Reflection; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// engine-bridge v3 — abstraction over the SUT-side AppManager singleton. diff --git a/src/Recordingtest.EgPlugin/IEngineStateProvider.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IEngineStateProvider.cs similarity index 81% rename from src/Recordingtest.EgPlugin/IEngineStateProvider.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IEngineStateProvider.cs index 668c433..7d5c329 100644 --- a/src/Recordingtest.EgPlugin/IEngineStateProvider.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/IEngineStateProvider.cs @@ -1,16 +1,12 @@ -// Issue #14 / 3-tier split — IEngineStateProvider, CameraSnapshot, SceneSnapshot, -// and NullEngineStateProvider have moved to Recordingtest.Bridge.Abstractions -// (generic tier). They are re-exported here as type aliases so existing -// internal call sites in this plugin continue to compile until the EgBim -// PluginHost folder move lands. -// -// ReflectionEngineStateProvider stays here for now as the CI / fallback -// implementation. The HmEG-aware HmegDirectStateProvider lives in -// Recordingtest.Hmeg.Bridge. +// 3-tier split step 2 — this file now holds only the EgBim-specific +// ReflectionEngineStateProvider, which probes Editor.AppManager.AppManager +// via reflection as the CI / fallback path. The generic IEngineStateProvider +// contract lives in Recordingtest.Bridge.Abstractions; the HmEG-aware +// HmegDirectStateProvider lives in Recordingtest.Hmeg.Bridge. using Recordingtest.Bridge; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// engine-bridge v3 — reflection-backed provider. Delegates all SUT-specific diff --git a/src/Recordingtest.EgPlugin/PortResolver.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/PortResolver.cs similarity index 91% rename from src/Recordingtest.EgPlugin/PortResolver.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/PortResolver.cs index 2d180ed..4d3a294 100644 --- a/src/Recordingtest.EgPlugin/PortResolver.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/PortResolver.cs @@ -1,4 +1,4 @@ -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; public static class PortResolver { diff --git a/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/Recordingtest.Sut.EgBim.PluginHost.csproj b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/Recordingtest.Sut.EgBim.PluginHost.csproj new file mode 100644 index 0000000..9b956b3 --- /dev/null +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/Recordingtest.Sut.EgBim.PluginHost.csproj @@ -0,0 +1,30 @@ + + + net8.0-windows + true + enable + enable + true + Recordingtest.Sut.EgBim.PluginHost + Recordingtest.Sut.EgBim.PluginHost + true + + + + + + + + ..\..\..\..\EG-BIM Modeler\Editor03.PluginInterface.dll + false + + + ..\..\..\..\EG-BIM Modeler\Editor02.HmEGAppManager.dll + false + + + ..\..\..\..\EG-BIM Modeler\HmEG.dll + false + + + diff --git a/src/Recordingtest.EgPlugin/StateRouter.cs b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/StateRouter.cs similarity index 98% rename from src/Recordingtest.EgPlugin/StateRouter.cs rename to src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/StateRouter.cs index 96235f4..4e28c74 100644 --- a/src/Recordingtest.EgPlugin/StateRouter.cs +++ b/src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/StateRouter.cs @@ -3,7 +3,7 @@ using System.Net; using System.Text; using Recordingtest.Bridge; -namespace Recordingtest.EgPlugin; +namespace Recordingtest.Sut.EgBim.PluginHost; /// /// Pure logic router: maps a request path to (status, json body). diff --git a/tests/Recordingtest.EngineBridge.IntegrationTests/FakeBridgeServer.cs b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/FakeBridgeServer.cs similarity index 97% rename from tests/Recordingtest.EngineBridge.IntegrationTests/FakeBridgeServer.cs rename to tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/FakeBridgeServer.cs index 3abdb74..b5f755d 100644 --- a/tests/Recordingtest.EngineBridge.IntegrationTests/FakeBridgeServer.cs +++ b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/FakeBridgeServer.cs @@ -2,7 +2,7 @@ using System.Net; using System.Net.Sockets; using System.Text; -namespace Recordingtest.EngineBridge.IntegrationTests; +namespace Recordingtest.Hmeg.Catalog.IntegrationTests; public sealed class FakeBridgeServer : IDisposable { diff --git a/tests/Recordingtest.EngineBridge.IntegrationTests/HmEgHttpSnapshotTests.cs b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/HmEgHttpSnapshotTests.cs similarity index 95% rename from tests/Recordingtest.EngineBridge.IntegrationTests/HmEgHttpSnapshotTests.cs rename to tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/HmEgHttpSnapshotTests.cs index 10fa751..a3ac2d4 100644 --- a/tests/Recordingtest.EngineBridge.IntegrationTests/HmEgHttpSnapshotTests.cs +++ b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/HmEgHttpSnapshotTests.cs @@ -1,7 +1,7 @@ -using Recordingtest.EngineBridge.Client; +using Recordingtest.Hmeg.Bridge.Client; using Xunit; -namespace Recordingtest.EngineBridge.IntegrationTests; +namespace Recordingtest.Hmeg.Catalog.IntegrationTests; public class HmEgHttpSnapshotTests { diff --git a/tests/Recordingtest.EngineBridge.IntegrationTests/Recordingtest.EngineBridge.IntegrationTests.csproj b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/Recordingtest.Hmeg.Catalog.IntegrationTests.csproj similarity index 68% rename from tests/Recordingtest.EngineBridge.IntegrationTests/Recordingtest.EngineBridge.IntegrationTests.csproj rename to tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/Recordingtest.Hmeg.Catalog.IntegrationTests.csproj index 83aaf62..820c5a7 100644 --- a/tests/Recordingtest.EngineBridge.IntegrationTests/Recordingtest.EngineBridge.IntegrationTests.csproj +++ b/tests/Hmeg/Recordingtest.Hmeg.Catalog.IntegrationTests/Recordingtest.Hmeg.Catalog.IntegrationTests.csproj @@ -5,7 +5,8 @@ enable true false - Recordingtest.EngineBridge.IntegrationTests + Recordingtest.Hmeg.Catalog.IntegrationTests + Recordingtest.Hmeg.Catalog.IntegrationTests @@ -13,6 +14,6 @@ - + diff --git a/tests/Recordingtest.EngineBridge.Tests/EngineBridgeTests.cs b/tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/EngineBridgeTests.cs similarity index 98% rename from tests/Recordingtest.EngineBridge.Tests/EngineBridgeTests.cs rename to tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/EngineBridgeTests.cs index 4c96065..503e93b 100644 --- a/tests/Recordingtest.EngineBridge.Tests/EngineBridgeTests.cs +++ b/tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/EngineBridgeTests.cs @@ -1,9 +1,9 @@ using System.Reflection; using System.Text.Json; -using Recordingtest.EngineBridge; +using Recordingtest.Hmeg.Catalog; using Xunit; -namespace Recordingtest.EngineBridge.Tests; +namespace Recordingtest.Hmeg.Catalog.Tests; public sealed class EngineBridgeTests { diff --git a/tests/Recordingtest.EngineBridge.Tests/Recordingtest.EngineBridge.Tests.csproj b/tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/Recordingtest.Hmeg.Catalog.Tests.csproj similarity index 61% rename from tests/Recordingtest.EngineBridge.Tests/Recordingtest.EngineBridge.Tests.csproj rename to tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/Recordingtest.Hmeg.Catalog.Tests.csproj index b6965d1..266dd37 100644 --- a/tests/Recordingtest.EngineBridge.Tests/Recordingtest.EngineBridge.Tests.csproj +++ b/tests/Hmeg/Recordingtest.Hmeg.Catalog.Tests/Recordingtest.Hmeg.Catalog.Tests.csproj @@ -1,8 +1,8 @@ false - Recordingtest.EngineBridge.Tests - Recordingtest.EngineBridge.Tests + Recordingtest.Hmeg.Catalog.Tests + Recordingtest.Hmeg.Catalog.Tests @@ -10,6 +10,6 @@ - + diff --git a/tests/Recordingtest.Architecture.Tests/DependencyGraphTests.cs b/tests/Recordingtest.Architecture.Tests/DependencyGraphTests.cs new file mode 100644 index 0000000..fa91efd --- /dev/null +++ b/tests/Recordingtest.Architecture.Tests/DependencyGraphTests.cs @@ -0,0 +1,115 @@ +using System.IO; +using System.Reflection; +using Xunit; + +namespace Recordingtest.Architecture.Tests; + +/// +/// Enforces the 3-tier separation rule from CLAUDE.md §8.1: +/// +/// Generic → no SUT assembly references at all +/// HmEG-aware → HmEG.dll only, no per-app assembly +/// App-specific → anything (not checked here; not referenced by this project) +/// +/// These tests walk on each +/// compiled output and fail if a forbidden reference appears. The test +/// project itself does NOT reference any Sut/* project, so a physical build +/// error would catch accidental upward references even before these tests +/// run — this file is the explicit contract. +/// +public class DependencyGraphTests +{ + private static readonly string[] ForbiddenAppAssemblies = + { + "Editor03.PluginInterface", + "Editor02.HmEGAppManager", + "EditorCore", + }; + + private const string HmegAssembly = "HmEG"; + + private static readonly string[] GenericAssemblies = + { + "Recordingtest.Bridge.Abstractions", + "Recordingtest.Recorder", + "Recordingtest.Player", + "Recordingtest.Normalizer", + "Recordingtest.DiffReporter", + "Recordingtest.Runner", + "Recordingtest.SutProber", + }; + + private static readonly string[] HmegAwareAssemblies = + { + "Recordingtest.Hmeg.Bridge", + "Recordingtest.Hmeg.Catalog", + "Recordingtest.Hmeg.Bridge.Client", + }; + + [Theory] + [InlineData("Recordingtest.Bridge.Abstractions")] + [InlineData("Recordingtest.Recorder")] + [InlineData("Recordingtest.Player")] + [InlineData("Recordingtest.Normalizer")] + [InlineData("Recordingtest.DiffReporter")] + [InlineData("Recordingtest.Runner")] + [InlineData("Recordingtest.SutProber")] + public void Generic_Tier_Does_Not_Reference_Hmeg_Or_AppAssemblies(string assemblyName) + { + var refs = LoadReferences(assemblyName); + Assert.DoesNotContain(HmegAssembly, refs); + foreach (var app in ForbiddenAppAssemblies) + { + Assert.DoesNotContain(app, refs); + } + } + + [Theory] + [InlineData("Recordingtest.Hmeg.Bridge")] + [InlineData("Recordingtest.Hmeg.Catalog")] + [InlineData("Recordingtest.Hmeg.Bridge.Client")] + public void HmegAware_Tier_Does_Not_Reference_AppAssemblies(string assemblyName) + { + var refs = LoadReferences(assemblyName); + foreach (var app in ForbiddenAppAssemblies) + { + Assert.DoesNotContain(app, refs); + } + } + + [Fact] + public void Hmeg_Bridge_References_HmEG_Dll() + { + // HmEG-aware tier is expected to reference HmEG.dll. This is the + // positive check that pairs with the App-specific forbidden list. + var refs = LoadReferences("Recordingtest.Hmeg.Bridge"); + Assert.Contains(HmegAssembly, refs); + } + + private static IReadOnlySet LoadReferences(string assemblyName) + { + // Locate the assembly via a type we know belongs to it. Each tier + // member has at least one public type; we use GenericAssemblies/ + // HmegAwareAssemblies as lookups by name. + Assembly? asm = null; + foreach (var loaded in AppDomain.CurrentDomain.GetAssemblies()) + { + if (loaded.GetName().Name == assemblyName) + { + asm = loaded; + break; + } + } + if (asm is null) + { + // Force-load by trying to resolve a type: the test project has a + // ProjectReference to the target, so the binary is next to ours. + var dir = Path.GetDirectoryName(typeof(DependencyGraphTests).Assembly.Location)!; + var path = Path.Combine(dir, assemblyName + ".dll"); + asm = Assembly.LoadFrom(path); + } + return new HashSet( + asm.GetReferencedAssemblies().Select(n => n.Name ?? string.Empty), + StringComparer.Ordinal); + } +} diff --git a/tests/Recordingtest.Architecture.Tests/Recordingtest.Architecture.Tests.csproj b/tests/Recordingtest.Architecture.Tests/Recordingtest.Architecture.Tests.csproj new file mode 100644 index 0000000..e6492ea --- /dev/null +++ b/tests/Recordingtest.Architecture.Tests/Recordingtest.Architecture.Tests.csproj @@ -0,0 +1,32 @@ + + + net8.0-windows + true + enable + enable + true + false + Recordingtest.Architecture.Tests + Recordingtest.Architecture.Tests + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Recordingtest.EgPlugin.Tests/ChainedEngineStateProviderTests.cs b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ChainedEngineStateProviderTests.cs similarity index 97% rename from tests/Recordingtest.EgPlugin.Tests/ChainedEngineStateProviderTests.cs rename to tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ChainedEngineStateProviderTests.cs index 4bd1754..89953a7 100644 --- a/tests/Recordingtest.EgPlugin.Tests/ChainedEngineStateProviderTests.cs +++ b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ChainedEngineStateProviderTests.cs @@ -1,8 +1,8 @@ using Recordingtest.Bridge; -using Recordingtest.EgPlugin; +using Recordingtest.Sut.EgBim.PluginHost; using Xunit; -namespace Recordingtest.EgPlugin.Tests; +namespace Recordingtest.Sut.EgBim.PluginHost.Tests; public class ChainedEngineStateProviderTests { diff --git a/tests/Recordingtest.EgPlugin.Tests/Recordingtest.EgPlugin.Tests.csproj b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/Recordingtest.Sut.EgBim.PluginHost.Tests.csproj similarity index 57% rename from tests/Recordingtest.EgPlugin.Tests/Recordingtest.EgPlugin.Tests.csproj rename to tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/Recordingtest.Sut.EgBim.PluginHost.Tests.csproj index 61777e2..92ece83 100644 --- a/tests/Recordingtest.EgPlugin.Tests/Recordingtest.EgPlugin.Tests.csproj +++ b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/Recordingtest.Sut.EgBim.PluginHost.Tests.csproj @@ -5,7 +5,8 @@ enable true false - Recordingtest.EgPlugin.Tests + Recordingtest.Sut.EgBim.PluginHost.Tests + Recordingtest.Sut.EgBim.PluginHost.Tests @@ -13,6 +14,7 @@ - + + diff --git a/tests/Recordingtest.EgPlugin.Tests/ReflectionEngineStateProviderTests.cs b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ReflectionEngineStateProviderTests.cs similarity index 98% rename from tests/Recordingtest.EgPlugin.Tests/ReflectionEngineStateProviderTests.cs rename to tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ReflectionEngineStateProviderTests.cs index 7e9e487..c3bd12c 100644 --- a/tests/Recordingtest.EgPlugin.Tests/ReflectionEngineStateProviderTests.cs +++ b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/ReflectionEngineStateProviderTests.cs @@ -1,8 +1,8 @@ using Recordingtest.Bridge; -using Recordingtest.EgPlugin; +using Recordingtest.Sut.EgBim.PluginHost; using Xunit; -namespace Recordingtest.EgPlugin.Tests; +namespace Recordingtest.Sut.EgBim.PluginHost.Tests; public class ReflectionEngineStateProviderTests { diff --git a/tests/Recordingtest.EgPlugin.Tests/StateRouterTests.cs b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/StateRouterTests.cs similarity index 95% rename from tests/Recordingtest.EgPlugin.Tests/StateRouterTests.cs rename to tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/StateRouterTests.cs index 121a7a0..6cecef4 100644 --- a/tests/Recordingtest.EgPlugin.Tests/StateRouterTests.cs +++ b/tests/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost.Tests/StateRouterTests.cs @@ -1,9 +1,9 @@ using System.Net; using Recordingtest.Bridge; -using Recordingtest.EgPlugin; +using Recordingtest.Sut.EgBim.PluginHost; using Xunit; -namespace Recordingtest.EgPlugin.Tests; +namespace Recordingtest.Sut.EgBim.PluginHost.Tests; public class StateRouterTests {