diff --git a/src/CustomJsonConverter.cs b/src/CustomJsonConverter.cs index 5a06889..6d0111b 100644 --- a/src/CustomJsonConverter.cs +++ b/src/CustomJsonConverter.cs @@ -18,11 +18,27 @@ public override bool CanConvert(Type objectType) return objectType == typeof(HOTASButton) || objectType == typeof(HOTASAxis) || objectType == typeof(ButtonAction) || + objectType == typeof(ActionCatalogItem) || objectType == typeof(IHOTASDevice); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { + if (objectType == typeof(ActionCatalogItem)) + { + var item = new ActionCatalogItem(); + try + { + serializer.Populate(reader, item); + } + catch (Exception e) + { + Logging.Log.Error(e, "Failed to deserialize an ActionCatalogItem"); + throw; + } + return item; + } + if (objectType == typeof(IHOTASDevice)) { var device = new HOTASDevice(); @@ -126,7 +142,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s if (button.Type == HOTASButton.ButtonType.Button && string.CompareOrdinal(button.MapName, JoystickOffsetValues.GetName(button.MapId)) != 0 || button.Type == HOTASButton.ButtonType.POV && string.CompareOrdinal(button.MapName, JoystickOffsetValues.GetPOVName(button.MapId)) != 0 || button.ActionCatalogItem?.Actions?.Count > 0 || - button.ShiftModePage >0 || + button.ShiftModePage > 0 || button.IsShift) { SerializeButton(writer, serializer, button); @@ -143,6 +159,12 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s return; } + if (value is ActionCatalogItem item) + { + if (item.Id == Guid.Empty) return; + SerializeCatalogActionItem(writer, serializer, item); + } + if (!(value is Dictionary>)) return; serializer.Serialize(writer, value); @@ -160,7 +182,7 @@ private static void SerializeButton(JsonWriter writer, JsonSerializer serializer if (prop.Name == nameof(button.ShiftModePage) && (int)prop.GetValue(button) == 0) continue; if (prop.Name == nameof(button.IsShift) && (bool)prop.GetValue(button) == false) continue; - + writer.WritePropertyName(prop.Name); serializer.Serialize(writer, value); } @@ -207,6 +229,22 @@ private static void SerializeButtonAction(JsonWriter writer, JsonSerializer seri } writer.WriteEndObject(); } + + private static void SerializeCatalogActionItem(JsonWriter writer, JsonSerializer serializer, ActionCatalogItem item) + { + var propList = typeof(ActionCatalogItem).GetProperties(); + writer.WriteStartObject(); + foreach (var prop in propList) + { + if (prop.GetCustomAttributes(true).Any(x => x is JsonIgnoreAttribute)) continue; + + var value = prop.GetValue(item); + + writer.WritePropertyName(prop.Name); + serializer.Serialize(writer, value); + } + writer.WriteEndObject(); + } } } diff --git a/src/Models/ActionCatalog.cs b/src/Models/ActionCatalog.cs index 5f1f24e..06e6372 100644 --- a/src/Models/ActionCatalog.cs +++ b/src/Models/ActionCatalog.cs @@ -58,8 +58,7 @@ public void Add(ActionCatalogItem item, string buttonName) public ActionCatalogItem Get(string actionName) { - if (!Contains(actionName)) return null; - return Catalog.First(x => x.ActionName == actionName); + return Catalog.FirstOrDefault(x => x.ActionName == actionName); } private void AddEmptyItem() diff --git a/src/Models/ActionCatalogItem.cs b/src/Models/ActionCatalogItem.cs index 3d0c202..0cb4153 100644 --- a/src/Models/ActionCatalogItem.cs +++ b/src/Models/ActionCatalogItem.cs @@ -9,7 +9,7 @@ namespace SierraHOTAS.Models public class ActionCatalogItem : INotifyPropertyChanged { private string _actionName; - private const string NO_ACTION_TEXT = ""; + public const string NO_ACTION_TEXT = ""; public Guid Id { get; set; } diff --git a/src/Models/HOTASAxis.cs b/src/Models/HOTASAxis.cs index 3a67265..50fbf3f 100644 --- a/src/Models/HOTASAxis.cs +++ b/src/Models/HOTASAxis.cs @@ -315,7 +315,7 @@ private void ClearUnassignedActions(ObservableCollection map) { foreach (var b in map) { - if (b.ActionName != "") continue; + if (b.ActionName != ActionCatalogItem.NO_ACTION_TEXT) continue; b.ActionName = string.Empty; b.ActionCatalogItem.Actions.Clear(); } diff --git a/src/Models/HOTASButton.cs b/src/Models/HOTASButton.cs index e2503a5..2af2ee5 100644 --- a/src/Models/HOTASButton.cs +++ b/src/Models/HOTASButton.cs @@ -123,7 +123,7 @@ private void RecordKeypress(Keyboard.KeystrokeEventArgs e) public void ClearUnassignedActions() { - if (ActionName != "") return; + if (ActionName != ActionCatalogItem.NO_ACTION_TEXT) return; ActionName = string.Empty; ActionCatalogItem.Actions.Clear(); } diff --git a/tests/ActionCatalogViewModelTests.cs b/tests/ActionCatalogViewModelTests.cs index 6f6a82a..14f57c0 100644 --- a/tests/ActionCatalogViewModelTests.cs +++ b/tests/ActionCatalogViewModelTests.cs @@ -10,7 +10,7 @@ public class ActionCatalogViewModelTests public void new_catalog_then_noActionItem_exists() { var catalog = new ActionCatalog(); - Assert.True(catalog.Contains("")); + Assert.True(catalog.Contains(ActionCatalogItem.NO_ACTION_TEXT)); } [Fact] diff --git a/tests/DeviceViewModelTests.cs b/tests/DeviceViewModelTests.cs index 5917da7..8b82cd3 100644 --- a/tests/DeviceViewModelTests.cs +++ b/tests/DeviceViewModelTests.cs @@ -280,7 +280,7 @@ public void clear_button_map() Type = HOTASButton.ButtonType.Button, ActionCatalogItem = new ActionCatalogItem() { Actions = new ObservableCollection() { new ButtonAction() } }, - ActionName = "" + ActionName = ActionCatalogItem.NO_ACTION_TEXT }; list.Add(testButton); diff --git a/tests/HOTASAxisMapTests.cs b/tests/HOTASAxisMapTests.cs index 1b40f56..5259a8c 100644 --- a/tests/HOTASAxisMapTests.cs +++ b/tests/HOTASAxisMapTests.cs @@ -434,11 +434,11 @@ public void get_button_from_raw_value_backward_directional_not_multi_action() public void clear_unassigned_actions() { var map = new HOTASAxis(); - map.ButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); + map.ButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = ActionCatalogItem.NO_ACTION_TEXT, Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); map.ButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "item 1", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); map.ButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "item 2", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); - map.ReverseButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); + map.ReverseButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = ActionCatalogItem.NO_ACTION_TEXT, Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); map.ReverseButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "item 1", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); map.ReverseButtonMap.Add(new HOTASButton() { ActionCatalogItem = new ActionCatalogItem() { ActionName = "item 2", Actions = new ObservableCollection() { new ButtonAction(), new ButtonAction() } } }); diff --git a/tests/HOTASCollectionViewModelTests.cs b/tests/HOTASCollectionViewModelTests.cs index ee440dc..78ebcde 100644 --- a/tests/HOTASCollectionViewModelTests.cs +++ b/tests/HOTASCollectionViewModelTests.cs @@ -518,7 +518,7 @@ public void file_open_command_valid_file() //check action catalog is rebuilt with the button loaded from file Assert.Equal(2, hotasVm.ActionCatalog.Catalog.Count); - Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == ""); + Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == ActionCatalogItem.NO_ACTION_TEXT); Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == "Release"); subDeviceList.Received().Stop(); @@ -603,7 +603,7 @@ public void file_open_command_valid_file_existing_device() //check action catalog is rebuilt with the button loaded from file Assert.Equal(2, hotasVm.ActionCatalog.Catalog.Count); - Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == ""); + Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == ActionCatalogItem.NO_ACTION_TEXT); Assert.Contains(hotasVm.ActionCatalog.Catalog, item => item.ActionName == "Release"); subDeviceList.Received().Stop(); @@ -637,7 +637,7 @@ public void file_open_command_null_file() Assert.NotEqual(loadedButtonMapId, hotasVm.Devices[0].ButtonMap[3].ButtonId); Assert.Single(hotasVm.ActionCatalog.Catalog); - Assert.Equal("", hotasVm.ActionCatalog.Catalog[0].ActionName); + Assert.Equal(ActionCatalogItem.NO_ACTION_TEXT, hotasVm.ActionCatalog.Catalog[0].ActionName); subDeviceList.DidNotReceive().Stop(); subFileSystem.Received().FileOpenDialog(); @@ -665,7 +665,7 @@ public void clear_active_profile_set_command() existingDevice.DeviceId = deviceGuid; existingDevice.Name = "existing device"; AddHotasButtonMap(existingDevice.ButtonMap, existingButtonMapId); - AddHotasButtonMap(existingDevice.ButtonMap, 0, HOTASButton.ButtonType.Button, "Button2 - remove my actions", "", 1); + AddHotasButtonMap(existingDevice.ButtonMap, 0, HOTASButton.ButtonType.Button, "Button2 - remove my actions", ActionCatalogItem.NO_ACTION_TEXT, 1); subDeviceList.ModeProfileActivationButtons.Add(1, new ModeActivationItem() { ButtonId = modeActivationButtonId, DeviceId = deviceGuid }); subFileSystem.FileOpenDialog().Returns((HOTASCollection)null); @@ -1169,7 +1169,7 @@ public void load_profile_add_button_list_to_catalog() var hotasVm = CreateHotasCollectionViewModel(out var subFileSystem, out var subQuickProfilePanelVm); Assert.Single(hotasVm.ActionCatalog.Catalog); - Assert.Equal("", hotasVm.ActionCatalog.Catalog[0].ActionName); + Assert.Equal(ActionCatalogItem.NO_ACTION_TEXT, hotasVm.ActionCatalog.Catalog[0].ActionName); var subHotasCollection = CreateHotasCollectionSubstitute(); @@ -1209,7 +1209,7 @@ public void load_profile_add_button_list_to_catalog() hotasVm.Initialize(); Assert.Equal(3, hotasVm.ActionCatalog.Catalog.Count); - Assert.Equal("", hotasVm.ActionCatalog.Catalog[0].ActionName); + Assert.Equal(ActionCatalogItem.NO_ACTION_TEXT, hotasVm.ActionCatalog.Catalog[0].ActionName); Assert.Equal("action1", hotasVm.ActionCatalog.Catalog[1].ActionName); Assert.Equal("action2", hotasVm.ActionCatalog.Catalog[2].ActionName); }