/* * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright (C) 2025 Sergej Görzen * This file is part of OmiLAXR. */ using System.Collections.Generic; using OmiLAXR.Composers; using OmiLAXR.Endpoints; using OmiLAXR.Hooks; using UnityEngine; namespace OmiLAXR { /// /// Generic extension system for DataProvider components that allows modular enhancement /// of data provider functionality without modifying the core implementation. /// Automatically discovers and registers child components (Composers, Hooks, Endpoints) /// with the target DataProvider during initialization. /// /// Type of DataProvider this extension targets [DefaultExecutionOrder(-1)] // Execute early to ensure extensions are applied before other components public abstract class DataProviderExtension : PipelineComponent, IDataProviderExtension where T : DataProvider { /// /// Collection of Composer components found in child objects. /// Composers handle data formatting and transformation for analytics output. /// public readonly List Composers = new List(); /// /// Collection of Hook components found in child objects. /// Hooks provide event interception and custom processing capabilities. /// public readonly List Hooks = new List(); /// /// Collection of Endpoint components found in child objects. /// Endpoints define where and how analytics data should be sent. /// public readonly List Endpoints = new List(); /// /// Reference to the specific DataProvider instance this extension is attached to. /// Strongly typed to the generic parameter for type-safe access. /// public T DataProvider { get; protected set; } /// /// Gets the DataProvider as the base DataProvider type for interface compliance. /// Required by IDataProviderExtension interface. /// /// The DataProvider instance cast to base type public DataProvider GetDataProvider() => DataProvider; /// /// Unity Awake callback that automatically discovers and extends the target DataProvider. /// Searches for the DataProvider and initiates the extension process. /// private void Awake() { // Find the target DataProvider instance in the scene var pipeline = FindObject(); Extend(pipeline); } /// /// Extends the specified DataProvider with components found in this extension's hierarchy. /// Automatically discovers and registers all child Composers, Hooks, and Endpoints. /// /// The DataProvider instance to extend public void Extend(DataProvider dataProvider) { // Cache the strongly-typed reference DataProvider = (T)dataProvider; // Discover all extension components in child objects var composers = gameObject.GetComponentsInChildren(); var hooks = gameObject.GetComponentsInChildren(); var endpoints = gameObject.GetComponentsInChildren(); // Store references locally for management Composers.AddRange(composers); Hooks.AddRange(hooks); Endpoints.AddRange(endpoints); // Register components with the target DataProvider DataProvider.Composers.AddRange(composers); DataProvider.Hooks.AddRange(hooks); DataProvider.Endpoints.AddRange(endpoints); DataProvider.Extensions.Add(this); // Log successful extension for debugging DebugLog.OmiLAXR.Print("Extended data provider " + typeof(T)); } } }