using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace UnityEditor.U2D.Tooling.Analyzer
{
///
/// Abstract base class for analyzer issue reports that provides common functionality
/// for data source management, report display, and object inspection.
///
public abstract class AnalyzerIssueReportBase : IAnalyzerReport
{
///
/// Provider for data sources used by this report.
///
IDataSourceProvider m_DataSourceProvider;
///
/// Array of data source types that this report is interested in monitoring.
///
Type[] m_DataSourceInterestedType;
///
/// List of active data sources that this report is currently monitoring.
///
List m_DataSourceInterested = new();
///
/// Event triggered when an object needs to be inspected.
///
protected event Action m_OnInspectObject;
///
/// UI list item representing this report in the analyzer interface.
///
ReportListItem m_ReportListItem;
///
/// Flag indicating whether the report is currently being filtered.
///
bool m_IsFilteringReport;
///
/// String representation of the current report item count.
///
string m_ReportItemCount = "-";
///
/// Initializes a new instance of the AnalyzerIssueReportBase class.
///
/// Array of data source types this report should monitor.
protected AnalyzerIssueReportBase(Type[] dataSourceInterestedType)
{
m_DataSourceInterestedType = dataSourceInterestedType;
m_ReportListItem = new ReportListItem();
m_ReportListItem.SetName(reportTitle);
m_ReportListItem.SetCount(m_ReportItemCount);
}
///
/// Gets the visual element representing this report in the list view.
///
VisualElement IAnalyzerReport.listItem => m_ReportListItem;
///
/// Gets the main content visual element for this report.
///
public abstract VisualElement reportContent { get; }
///
/// Gets the settings content visual element for this report.
///
public abstract VisualElement settingsContent { get; }
///
/// Gets the title for this report.
///
public abstract string reportTitle { get; }
///
/// Sets the data source provider for this report and initializes data source monitoring.
///
/// The data source provider to use.
void IAnalyzerReport.SetDataSourceProvider(IDataSourceProvider dataSourceProvider)
{
if (m_DataSourceProvider != null)
m_DataSourceProvider.onDataSourceChanged -= OnDataProviderChanged;
m_DataSourceProvider = dataSourceProvider;
m_DataSourceProvider.onDataSourceChanged += OnDataProviderChanged;
InitDataSource();
}
///
/// Sets the display name for this report in the list item.
///
/// The name to display.
public void SetReportListItemName(string name)
{
m_ReportListItem.SetName(name);
}
///
/// Sets the item count display for this report and clears filtering state.
///
/// The count string to display.
public void SetReportListemCount(string count)
{
m_ReportItemCount = count;
m_IsFilteringReport = false;
m_ReportListItem.SetCount(count);
}
///
/// Triggers the object inspection event for the specified Unity object.
///
/// The Unity object to inspect.
protected void InspectObject(Object obj)
{
m_OnInspectObject?.Invoke(this, obj);
}
///
/// Handles data provider change events by reinitializing data sources.
///
void OnDataProviderChanged()
{
InitDataSource();
}
///
/// Initializes and subscribes to data sources based on the interested types.
/// Clears existing subscriptions and creates new ones for available data sources.
///
void InitDataSource()
{
for (int i = 0; i < m_DataSourceInterested.Count; ++i)
{
m_DataSourceInterested[i].onDataSourceChanged -= OnReportDataSourceChanged;
}
m_DataSourceInterested.Clear();
for (int i = 0; i < m_DataSourceInterestedType.Length; ++i)
{
var reportDataSource = m_DataSourceProvider.GetDataSource(m_DataSourceInterestedType[i]);
if (reportDataSource != null)
{
reportDataSource.onDataSourceChanged += OnReportDataSourceChanged;
m_DataSourceInterested.Add(reportDataSource);
OnReportDataSourceChanged(reportDataSource);
}
}
}
///
/// Request capture of data from all interested data sources.
///
/// The paths to folder or asset to capture.
protected void RequestCapture(string[] path)
{
for(int i = 0; i < m_DataSourceInterested.Count; ++i)
{
m_DataSourceInterested[i].Capture(path);
}
}
///
/// Abstract method called when a monitored data source changes.
/// Derived classes must implement this to handle data source updates.
///
/// The data source that changed.
protected abstract void OnReportDataSourceChanged(IReportDataSource reportDataSource);
///
/// Performs cleanup by unsubscribing from events and clearing data sources.
///
public virtual void Dispose()
{
for (int i = 0; i < m_DataSourceInterested.Count; ++i)
{
m_DataSourceInterested[i].onDataSourceChanged -= OnReportDataSourceChanged;
}
m_DataSourceInterested.Clear();
m_OnInspectObject = null;
}
///
/// Event that is raised when an object should be inspected.
///
event Action IAnalyzerReport.onInspectObject
{
add => m_OnInspectObject += value;
remove => m_OnInspectObject -= value;
}
///
/// Gets the report instance for the specified type.
///
/// The type to get the report for.
/// This report instance if the type matches, otherwise null.
IAnalyzerReport IAnalyzerReport.GetReportForType(Type type)
{
if (type == GetType())
{
return this;
}
return null;
}
///
/// Gets or sets a value indicating whether the report is currently being filtered.
/// When set to true, shows a loading state in the UI. When set to false, shows the current item count.
///
public bool isFilteringReport
{
get => m_IsFilteringReport;
protected set
{
if (m_IsFilteringReport != value)
{
m_IsFilteringReport = value;
if (m_IsFilteringReport)
{
if (m_ReportListItem != null)
m_ReportListItem.SetLoading();
}
else
{
m_ReportListItem.SetCount(m_ReportItemCount);
}
}
}
}
}
}