using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using UnityEngine; using UVC.Core; using UVC.Data; using UVC.Data.Core; using UVC.Factory; using UVC.Factory.Alarm; using UVC.Factory.Component; using UVC.Factory.Modal; using UVC.Factory.Modal.Settings; using UVC.Factory.Playback; using UVC.Log; using UVC.UI.Commands; using UVC.UI.Loading; using UVC.UI.Menu; using UVC.UI.Modal; using UVC.UI.Tooltip; using UVC.UI.Window.PropertyWindow; namespace SampleProject { [DefaultExecutionOrder(90)] public class SceneMain : SingletonScene { [SerializeField] private TopMenuController topMenu; [SerializeField] private TopMenuController sideMenu; public Action Initialized; /// /// 초기 화 메서드입니다. /// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다. /// protected override void Init() { if (!TooltipManager.Instance.IsInitialized) TooltipManager.Instance.Initialize(); AppMain.Instance.Initialized += OnAppInitialized; } private async void OnAppInitialized() { // AGVManager 생성 시 이벤트 처리 AGVManager.Instance.OnCreated += OnAGVCreated; PlaybackService.Instance.OnStartPlayback += OnStartPlayback; PlaybackService.Instance.OnExitPlayback += OnExitPlayback; PlaybackService.Instance.OnChangedTime += OnChangedTimePlayback; await requestDataAsync(); SetupTopMenu(); SetupSideMenu(); SetupPropertyWindow(); if (Initialized != null) { Initialized.Invoke(); } } /// /// AGV 관리자가 생성될 때 발생하는 이벤트를 처리합니다. /// /// 이 메서드는 AGV 관리자 생성과 관련된 필요한 초기화 또는 설정 작업을 수행하기 위한 것입니다. /// 내부적으로 호출되며 외부 코드에서 직접 사용하도록 의도된 것이 아닙니다. /// internal void OnAGVCreated() { AlarmManager.Instance.Run(); UILoading.Hide(); FactoryCameraController.Instance.Enable = true; } private async UniTask requestDataAsync() { Debug.Log("requestDataAsync"); UILoading.Show(); //Debug.Log("Requesting BaseInfo data..."); var httpFetcher = DataRepository.Instance.HttpFetcher; //var splitRequest = new HttpRequestConfig(URLList.Get("baseinfo")) // .SetSplitResponseByKey(true) // 응답을 키별로 분할 // .AddSplitConfig("AGV", DataMapperValidator.Get("AGV")) // "AGV" 키에 대한 매퍼, Validator 설정 // .AddSplitConfig("ALARM", DataMapperValidator.Get("ALARM")); // "ALARM" 키에 대한 매퍼, Validator 설정 //httpFetcher.AddChild("baseInfo", splitRequest); //await httpFetcher.Excute("baseInfo"); //Debug.Log("BaseInfo data request completed."); //UILoading.Hide(); //MqttReceiver 시작 //DataRepository.Instance.MqttReceiver.Start(); if (AGVManager.Instance.Created) { await UniTask.Delay(1000); UILoading.Hide(); } } private void OnStartPlayback() { FactoryObjectSelectionManager.Instance.DeselectAll(); InfoWindow.Instance.Hide(); } private async void OnExitPlayback() { FactoryObjectSelectionManager.Instance.DeselectAll(); InfoWindow.Instance.Hide(); await requestDataAsync(); } private void OnChangedTimePlayback() { } private void SetupTopMenu() { if (topMenu == null) { Debug.LogWarning("TopMenuController is not assigned in SceneMain."); return; } topMenu.AddMenuItem(new MenuItemData("file", "menu_file", subMenuItems: new List { new MenuItemData("file_new", "menu_file_new", subMenuItems: new List { new MenuItemData("file_new_project", "menu_file_new_project", new DebugLogCommand("새 프로젝트 선택됨 (Command 실행)")), new MenuItemData("file_new_file", "menu_file_new_file", new ActionCommand(() => Debug.Log("[SampleProject] 새 파일 선택됨"))) }), new MenuItemData("file_open", "menu_file_open", new ActionCommand((path) => Debug.Log($"[SampleProject] 파일 열기 선택됨: {path}"), "sample.txt"), commandParameter: "another_sample.txt", // 이 파라미터가 HandleMenuItemClicked에서 사용됨 isEnabled: false), // "파일 열기"는 비활성화 상태로 시작 MenuItemData.CreateSeparator("file_sep1"), // 구분선 추가 new MenuItemData("file_save", "menu_file_save", command: new DebugLogCommand("저장 선택됨 (Command 실행)") , subMenuItems: new List { new MenuItemData("file_save_as", "menu_file_save_as", new DebugLogCommand("다른 이름으로 저장 선택됨 (Command 실행)")) }), MenuItemData.CreateSeparator("file_sep2"), // 또 다른 구분선 추가 new MenuItemData("file_exit", "menu_file_exit", new QuitApplicationCommand()) // 애플리케이션 종료 명령 연결 })); topMenu.AddMenuItem(new MenuItemData("Playback", "Playback", new PlaybackCommand())); // pool 로그 topMenu.AddMenuItem(new MenuItemData("log", "Log", subMenuItems: new List { new MenuItemData("dataArray", "DataArray", new ActionCommand(() => Debug.Log($"DataArrayPool stats: {DataArrayPool.GetStats()}"))), new MenuItemData("dataObject", "DataObjet", new ActionCommand(() => Debug.Log($"DataObjectPool stats: {DataObjectPool.GetStats()}"))), new MenuItemData("agv", "Pool", new ActionCommand(() => Debug.Log($"Pool stats: {AGVManager.Instance.Pool.GetStats()}"))), })); topMenu.AddMenuItem(new MenuItemData("modal", "모달", subMenuItems: new List { new MenuItemData("alert", "Alert", new ActionCommand(async () => { await Alert.Show("알림", "이것은 간단한 알림 메시지입니다."); await Alert.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다"); await Alert.Show("error", "error_network_not", "button_retry"); })), new MenuItemData("confirm", "Confirm", new ActionCommand(async () => { bool result = await Confirm.Show("확인", "이것은 간단한 알림 메시지입니다."); Debug.Log($"사용자가 확인 버튼을 눌렀나요? {result}"); result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다~~~~", "아니요"); Debug.Log($"사용자가 알림을 확인했나요? {result}"); result = await Confirm.Show("error", "error_network_not", "button_retry", "button_cancel"); Debug.Log($"사용자가 네트워크 오류 알림을 확인했나요? {result}"); })) })); topMenu.AddMenuItem(new MenuItemData("Settings", "Settings", new SettingOpenCommand())); topMenu.AddMenuItem(new MenuItemData("PropertyWindow", "PropertyWindow", new ActionCommand(async () => { PropertyWindow.Instance.Show(); }))); topMenu.Initialize(); } private void SetupSideMenu() { if (sideMenu == null) { Debug.LogError("SideMenuController is not assigned in SceneMain."); return; } sideMenu.AddMenuItem(new MenuItemData("menu", "menu", new DebugLogCommand("[SampleProject] 프로젝트 설정 선택됨"), subMenuItems: new List { new MenuItemData("file", "menu_file", subMenuItems: new List { new MenuItemData("file_new_file", "menu_file_new_file", new DebugLogCommand("[SampleProject] 새 파일 선택됨")), // "파일 열기" 메뉴 아이템 생성 시 isEnabled: false로 설정하여 비활성화 상태로 초기화합니다. // 부모 TopMenuController의 HandleMenuItemClicked에서 이 상태를 확인하여 클릭을 무시합니다. new MenuItemData("file_open", "menu_file_open", new DebugLogCommand("[SampleProject] 파일 열기 선택됨"), isEnabled: false), MenuItemData.CreateSeparator("file_sep_sample1"), new MenuItemData("project_settings", "project_settings", new DebugLogCommand("[SampleProject] 프로젝트 설정 선택됨")), // 프로젝트별 메뉴 아이템 MenuItemData.CreateSeparator("file_sep_sample2"), new MenuItemData("file_exit", "menu_file_exit", new QuitApplicationCommand()) }), new MenuItemData("Playback", "Playback", new PlaybackCommand()), new MenuItemData("modal", "모달", subMenuItems: new List { new MenuItemData("alert", "Alert", new ActionCommand(async () => { await Alert.Show("알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림알림", "이것은 간단한 알림 메시지입니다."); await Alert.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다"); await Alert.Show("error", "error_network_not", "button_retry"); })), new MenuItemData("confirm", "Confirm", new ActionCommand(async () => { bool result = await Confirm.Show("확인", "이것은 간단한 알림 메시지입니다."); ULog.Debug($"사용자가 확인 버튼을 눌렀나요? {result}"); result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다", "아니요"); ULog.Debug($"사용자가 알림을 확인했나요? {result}"); result = await Confirm.Show("error", "error_network_not", "button_retry", "button_cancel"); ULog.Debug($"사용자가 네트워크 오류 알림을 확인했나요? {result}"); })) }), new MenuItemData("Settings", "Settings", subMenuItems: new List { new MenuItemData("info", "info", new DisplayDataOrderCommand()), }) })); sideMenu.Initialize(); } private void SetupPropertyWindow() { PropertyWindow.Instance.LoadProperties(new List { new StringProperty("prop1", "String Property", "Initial Value") { Description = "This is a sample string property.", Tooltip = "Enter a string value here.", IsReadOnly = false }, new IntProperty("prop2", "Int Property", 42, true) { Description = "This is a sample integer property.", Tooltip = "Enter an integer value here.", IsReadOnly = false }, new IntRangeProperty("prop2_range", "Int Range Property", new Tuple(0, 100)) { Description = "This is a sample integer range property.", Tooltip = "Select an integer value within the range here.", IsReadOnly = false }, new FloatRangeProperty("prop3_range", "Float Range Property", new Tuple(0.0f, 1.0f)) { Description = "This is a sample float range property.", Tooltip = "Select a float value within the range here.", IsReadOnly = false }, new FloatProperty("prop3", "Float Property", 0.5f, true) { Description = "This is a sample float property.", Tooltip = "Enter an float value here.", IsReadOnly = false }, new BoolProperty("prop4", "Boolean Property", true) { Description = "This is a sample boolean property.", Tooltip = "Toggle the boolean value here.", IsReadOnly = false }, new ColorProperty("prop5", "Color Property", Color.red) { Description = "This is a sample color property.", Tooltip = "Select a color here.", IsReadOnly = false }, new Vector2Property("prop6_vec2", "Vector2 Property", new Vector2(1, 2)) { Description = "This is a sample Vector2 property.", Tooltip = "Enter a Vector2 value here.", IsReadOnly = false }, new Vector3Property("prop6_vec3", "Vector3 Property", new Vector3(1, 2, 3)) { Description = "This is a sample Vector3 property.", Tooltip = "Enter a Vector3 value here.", IsReadOnly = false }, new DateProperty("prop6_date", "Date Property", System.DateTime.Now) { //Description = "This is a sample date property.", Tooltip = "Select a date here.", IsReadOnly = false }, new DateTimeProperty("prop6_datetime", "DateTime Property", System.DateTime.Now) { Description = "This is a sample date-time property.", Tooltip = "Select a date and time here.", IsReadOnly = false }, new DateRangeProperty("prop6_daterange", "Date Range Property", new Tuple(DateTime.Now.AddDays(-7), DateTime.Now)) { Description = "This is a sample date range property.", Tooltip = "Select a date range here.", IsReadOnly = false }, new DateTimeRangeProperty("prop6_datetimerange", "DateTime Range Property", new Tuple(DateTime.Now.AddHours(-1), DateTime.Now)) { Description = "This is a sample date-time range property.", Tooltip = "Select a date-time range here.", IsReadOnly = false }, new EnumProperty("prop6", "Enum Property", SampleEnum.Option1) { Description = "This is a sample enum property.", Tooltip = "Select an option here.", IsReadOnly = false }, new ListProperty("prop7", "List Property", new List { "Item1", "Item2", "Item3" }, "Item1") { Description = "This is a sample list property.", Tooltip = "Manage the list items here.", IsReadOnly = false }, new RadioGroupProperty("prop8", "Radio Group Property", new List { "Option1", "Option2", "Option3" }, "Option1") { Description = "This is a sample radio group property.", Tooltip = "Select one option here.", IsReadOnly = false } }); PropertyWindow.Instance.PropertyValueChanged += (sender, e) => { Debug.Log($"Property Id:{e.PropertyId}, type:{e.PropertyType}, newValue: {e.NewValue}"); }; } enum SampleEnum { Option1, Option2, Option3 } } }