Skip to content

Wire new animation engine into scanning managers with per-session renderer and DI integration#274

Open
Copilot wants to merge 5 commits intomasterfrom
copilot/integrate-animation-system
Open

Wire new animation engine into scanning managers with per-session renderer and DI integration#274
Copilot wants to merge 5 commits intomasterfrom
copilot/integrate-animation-system

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

Completes the switch-over to the new animation engine by closing the wiring gap between the adapter infrastructure and the actual call sites. The previous commits added AnimationPlayerAdapter and property injection on both managers, but the engine was never activated because AnimationService was never set at call sites and TryCreate() lacked a renderer.

Changes Made

Context.AppAnimationService

Added a static IAnimationService AppAnimationService property to Context.cs that resolves IAnimationService from the DI container. Returns null when DI is not configured, preserving full backward compatibility.

IAnimationService.CreateSession() — per-session renderer

Added an optional IHighlightRenderer renderer parameter. When supplied it overrides the DI singleton renderer, allowing each panel to supply its own renderer with panel-specific widget-lookup callbacks. Falls back to the singleton; throws InvalidOperationException if neither is available.

AnimationService.CreateSession() — renderer fallback

Implements the per-session override / singleton fallback chain to match the updated interface.

AnimationPlayerAdapter.BuildRenderer()

New factory method that builds a WinFormsHighlightRenderer from the Widget tree using Finder.FindChild() + HighlightOn()/HighlightOff(), with UI-thread marshalling via Control.BeginInvoke. A shared InvokeOnUIThread() helper eliminates the duplicated marshalling pattern. The built renderer is passed to CreateSession(), removing the dependency on a pre-registered singleton.

DialogCommon.initAnimationManager()

Sets _animationManager.AnimationService = Context.AppAnimationService so the new engine is automatically used when DI is configured and falls back to the legacy AnimationPlayer otherwise.

UserControlCommon.initAnimationManager()

Same wiring pattern as DialogCommon.

Testing

  • T21CreateSession() succeeds when a per-session renderer is supplied and the singleton is null
  • T22CreateSession() throws InvalidOperationException when no renderer is available at all
  • T23CreateSession() falls back to the singleton renderer when the per-session parameter is null
  • T24AnimationPlayerAdapter.TryCreate() returns null when IAnimationService is null
  • T25AnimationPlayerAdapter.TryCreate() succeeds with a singleton renderer and a null root widget
  • ✅ ACATCore build: 0 errors
  • ✅ ConfigMigrationTool tests: 25 passed, 0 failed
Original prompt

This section details on the original issue you should resolve

<issue_title>Animation System: Integration, Testing & Documentation</issue_title>
<issue_description># Animation System: Integration, Testing & Documentation

Labels

phase-3, workstream-b, animation, integration, testing

Milestone

Phase 3: Animation System Modernization

Summary

Wire the new animation engine (from Issue #4) into the existing ACAT application, creating adapter layers so the new engine handles scanning while maintaining 100% backward compatibility. Includes comprehensive testing (unit, integration, performance), BCI extension validation, and developer documentation.

This is the higher-risk part of the animation work — it touches production scanning behavior that users with motor disabilities depend on.

Context

After Issue #4, the new engine exists as standalone components. This issue connects them to the real application:

  • PanelAnimationManager delegates internally to IAnimationService.CreateSession()
  • UserControlAnimationManager similarly adapted
  • Legacy AnimationPlayer remains functional for any callers not yet migrated
  • BCI extension (AnimationSharpManagerV2.cs, 2,885 lines) must continue to function

Performance Requirements (from Design Spec §14)

  • Scan interval deviation: ≤5% at 200ms minimum
  • Actuator-to-highlight latency: ≤50ms
  • IEventBus dispatch time: ≤1ms
  • Config load time: ≤20ms (BCI worst case with 25 animations)

XML Configuration Landscape

  • 69 panel XML config files with <Animation> elements
  • Located in src/ACATResources/panelconfigs/ (common/, en/, es/)
  • Highest complexity: NumericUserControlBCI.xml (25 animations), KeyboardABCUserControlBCI2.xml (25 animations)

Implementation Steps

Part 1: Adapter Layer (~3 days)

  1. Create AnimationPlayerAdapter — bridges PanelAnimationManager to new IAnimationService:

    • PanelAnimationManager calls remain unchanged from callers' perspective
    • Internally creates IAnimationSession via IAnimationService.CreateSession()
    • Routes actuator switch events to IAnimationSession.HandleInput()
    • Falls back to legacy AnimationPlayer if new engine session fails
  2. Update PanelAnimationManager.cs:

    • Inject IAnimationService (property injection to avoid constructor breakage)
    • Use adapter when IAnimationService is available
    • Preserve all existing public method signatures
  3. Update UserControlAnimationManager.cs:

    • Same adapter pattern as PanelAnimationManager
    • Ensure UserControl-specific behavior preserved
  4. Update AnimationManager.cs:

    • Route actuator events to new sessions when active
    • Maintain existing event routing for legacy sessions

Part 2: XML-to-JSON Configuration Bridge (~2 days)

  1. Implement XmlAnimationConfigAdapter (started in Issue Restarting the Presage engine #4, complete here):

    • Parse all 69 XML panel configs' <Animation> elements
    • Convert to AnimationConfig JSON model at runtime
    • Handle the 5 schema migration constraints:
      • C1: Iterations as @VarName runtime reference
      • C2: ScanTime/FirstPauseTime as variable names
      • C3: Wildcard widget names (Box1/*, @SelectedWidget)
      • C4: Per-widget OnSelected PCode
      • C5: Per-animation OnEnter/OnEnd PCode
    • Cache converted configs (parse once per panel load)
  2. Validate against high-complexity configs:

    • NumericUserControlBCI.xml (25 animations)
    • KeyboardABCUserControlBCI2.xml (25 animations)
    • KeyboardEditUserControlBCI.xml (17 animations)
    • Verify all animations load and scan correctly

Part 3: BCI Extension Validation (~2 days)

  1. Validate BCI extension compatibility:

    • src/Extensions/BCI/AnimationSharpManagerV2.cs (2,885 lines) has its own animation loop and SharpDX overlay rendering
    • Verify it continues to function unchanged (BCI extension does NOT use the new engine yet — that's a future phase)
    • Ensure no interface changes break BCI compilation
    • Test BCI-specific scan modes (eye-gaze, neural signal actuator)
  2. Document BCI migration path for future work:

    • Identify which parts of AnimationSharpManagerV2.cs could be replaced by the new engine
    • Note ~1,400 lines of duplicated core logic that the new engine could eliminate
    • Create brief migration roadmap (not implementing now)

Part 4: Testing (~3 days)

  1. Integration tests — test real panel lifecycle with new engine:

    • Panel creation → animation session start → widget scanning → user selection → panel close
    • Multi-panel scenarios (main panel + dialog overlay)
    • Actuator pause/resume during scanning
    • Panel transition (close one, open another)
  2. Performance benchmarks:

    • Scan interval accuracy at 200ms, 500ms, 1000ms intervals
    • Actuator-to-highli...

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 25, 2026 20:20
…ger/UserControlAnimationManager, integration tests, and performance benchmarks

Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com>
…n, update INDEX.md

Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com>
Copilot AI changed the title [WIP] Integrate new animation engine into existing ACAT application Wire new animation engine into PanelAnimationManager/UserControlAnimationManager via adapter layer Feb 25, 2026
…anelName}.animation.json from panel XML configs

Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com>
Copilot AI changed the title Wire new animation engine into PanelAnimationManager/UserControlAnimationManager via adapter layer Add file-level animation config converter and wire new animation engine into scanning managers Feb 25, 2026
@michaelbeale-IL michaelbeale-IL marked this pull request as ready for review February 25, 2026 21:52
@michaelbeale-IL
Copy link
Contributor

@copilot Review this PR and determine if there is any more work that needs to be completed.

…n renderer in CreateSession, BuildRenderer in AnimationPlayerAdapter, wiring in DialogCommon/UserControlCommon, tests T21-T25

Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 25, 2026

@copilot Review this PR and determine if there is any more work that needs to be completed.

Reviewed the PR. The previous 4 commits had the adapter infrastructure in place (AnimationPlayerAdapter, property injection on both managers) but the engine was never actually activatedAnimationService was never set on the managers at call sites, and AnimationPlayerAdapter.TryCreate() didn't build a renderer from the root widget, so CreateSession() would throw.

The following gaps were filled in commit 7f6463c:

  1. Context.AppAnimationService — static shortcut that resolves IAnimationService from DI (returns null when DI isn't configured, preserving backward compatibility).

  2. IAnimationService.CreateSession() renderer parameter — added an optional IHighlightRenderer renderer parameter; per-session renderer overrides the DI singleton, with a fallback chain and a clear error when neither is available.

  3. AnimationPlayerAdapter.BuildRenderer() — factory method that constructs a WinFormsHighlightRenderer from the Widget tree using Finder.FindChild() + HighlightOn()/HighlightOff(), with proper UI-thread marshalling via Control.BeginInvoke. Extracted into a shared InvokeOnUIThread() helper to avoid duplication.

  4. DialogCommon.initAnimationManager() — now sets _animationManager.AnimationService = Context.AppAnimationService so the new engine is used whenever DI is configured.

  5. UserControlCommon.initAnimationManager() — same wiring pattern.

  6. Tests T21–T25 — unit tests for the per-session renderer override, null-renderer exception, singleton fallback, TryCreate null-guard, and TryCreate success path.

Copilot AI changed the title Add file-level animation config converter and wire new animation engine into scanning managers Wire new animation engine into scanning managers with per-session renderer and DI integration Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Animation System: Integration, Testing & Documentation

2 participants