#nullable enable using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UVC.Core; namespace UVC.UI.Window.PropertyWindow { /// /// 속성 데이터를 관리하고, 데이터 변경 시 이벤트를 발생시키는 컨트롤러 클래스입니다. /// Model과 View 사이의 중재자 역할을 합니다. /// public class PropertyWindow: SingletonScene { [SerializeField] private PropertyView _view; /// /// 현재 컨트롤러가 관리하는 모든 속성 항목의 목록입니다. /// public List Properties { get; private set; } = new List(); /// /// 속성 값이 변경될 때 발생하는 이벤트입니다. /// View는 이 이벤트를 구독하여 UI를 업데이트할 수 있습니다. /// public event EventHandler? PropertyValueChanged; /// /// 새로운 속성 목록을 로드하고 초기화합니다. /// /// 표시할 속성 항목들의 목록 public void LoadProperties(List items) { Properties = items ?? new List(); // 필요하다면 여기서 추가적인 초기화 로직을 수행할 수 있습니다. if(_view != null) _view.Initialize(this); } /// /// 특정 ID를 가진 속성의 값을 업데이트합니다. /// 이 메서드는 주로 View에서 사용자 입력이 발생했을 때 호출됩니다. /// /// 값을 변경할 속성의 고유 ID /// 속성의 타입 /// 새로운 값 public void UpdatePropertyValue(string propertyId, PropertyType propertyType, object newValue) { // ID에 해당하는 속성을 찾습니다. var propertyItem = Properties.FirstOrDefault(p => p.Id == propertyId); if (propertyItem == null) { // 해당 ID의 속성이 없으면 오류를 기록하고 반환합니다. UnityEngine.Debug.LogError($"[PropertyWindow] ID '{propertyId}'에 해당하는 속성을 찾을 수 없습니다."); return; } // 이전 값을 저장합니다. object oldValue = propertyItem.GetValue(); // 새 값과 이전 값이 같은지 확인합니다. (불필요한 이벤트 발생 방지) if (Equals(oldValue, newValue)) { return; } // 속성 객체의 값을 새로운 값으로 설정합니다. propertyItem.SetValue(newValue); // 값이 변경되었음을 알리는 이벤트를 발생시킵니다. OnPropertyValueChanged(propertyId, propertyType, oldValue, newValue); } /// /// PropertyValueChanged 이벤트를 안전하게 발생시키는 보호된 가상 메서드입니다. /// /// 변경된 속성 ID /// 이전 값 /// 새로운 값 protected virtual void OnPropertyValueChanged(string propertyId, PropertyType propertyType, object oldValue, object newValue) { // 이벤트 핸들러가 등록되어 있는지 확인하고 이벤트를 발생시킵니다. PropertyValueChanged?.Invoke(this, new PropertyValueChangedEventArgs(propertyId, propertyType, oldValue, newValue)); } public bool IsVisible() { return gameObject.activeSelf; } public void Show() { gameObject.SetActive(true); } public void Hide() { gameObject.SetActive(false); } } }