Skip to content

Commit

Permalink
feat: Update hook & event impls
Browse files Browse the repository at this point in the history
  • Loading branch information
Pd233 committed Nov 20, 2023
1 parent 4ed4199 commit 76f6928
Show file tree
Hide file tree
Showing 17 changed files with 1,332 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,5 @@ ASALocalRun/
.mfractor/

# Local History for Visual Studio
.localhistory/
.localhistory/
/src/Properties/launchSettings.json
50 changes: 50 additions & 0 deletions src/Events/Implements/Player/DestroyBlockEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Hosihikari.NativeInterop;
using Hosihikari.NativeInterop.Unmanaged;
using System.Runtime.InteropServices;

namespace Hosihikari.Minecraft.Extension.Events.Implements.Player;

public class DestroyBlockEventArgs : CancelableEventArgsBase
{
public required Hosihikari.Minecraft.Player Player { get; init; }
public required BlockPos Position { get; init; }
public int DimensionId { get; init; }
}

public class DestroyBlockEvent : HookEventBase<DestroyBlockEventArgs, DestroyBlockEvent.HookDelegate>
{
[return: MarshalAs(UnmanagedType.U1)]
public unsafe delegate bool HookDelegate(Pointer<Block> @this, Pointer<Hosihikari.Minecraft.Player> player, BlockPos* pos);

Check warning on line 17 in src/Events/Implements/Player/DestroyBlockEvent.cs

View workflow job for this annotation

GitHub Actions / build

This takes the address of, gets the size of, or declares a pointer to a managed type ('BlockPos')

public DestroyBlockEvent()
: base(Block.Original.PlayerWillDestroy) { }

private const int DimensionIdOffset = 352;

public override unsafe HookDelegate HookedFunc =>
(@this, _player, pos) =>
{
var player = _player.Target;
using var actor = player.As<Actor>();
using var dim = actor.Dimension.Target;
var dimid = DAccess<int>(dim.Pointer, DimensionIdOffset);

var e = new DestroyBlockEventArgs
{
Player = player,
DimensionId = dimid,
Position = *pos
};

OnEventBefore(e);

if (e.IsCanceled)
return false;

var ret = Original(@this, _player, pos);

OnEventAfter(e);
return ret;
};

}
111 changes: 111 additions & 0 deletions src/FormUI/CustomForm/CustomForm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Hosihikari.Minecraft;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Hosihikari.FormUI;

public class CustomFormCallbackEventArgs : EventArgs
{
private readonly Dictionary<string, CustomFormElement> elements;
private readonly Player player;

public Dictionary<string, CustomFormElement> Elements => elements;

public Player Player => player;

Check failure on line 14 in src/FormUI/CustomForm/CustomForm.cs

View workflow job for this annotation

GitHub Actions / build

The type or namespace name 'Player' could not be found (are you missing a using directive or an assembly reference?)

public CustomFormCallbackEventArgs(Dictionary<string, CustomFormElement> elements, Player player)
{
this.elements = elements;
this.player = player;
}
}

public class CustomForm : FormBase
{
private FormElementCollection<(string elementName, CustomFormElement element)> elements;

private string title = string.Empty;

public CustomForm()
{
elements = new();
elements.Changed += OnCollectionChanged;
}

[JsonPropertyName("title")]
public string Title
{
get => title;
set
{
title = value;
OnPropertyChanged(nameof(Title));
}
}

[JsonPropertyName("content")]
public List<CustomFormElement> SerializedContents
{
get
{
var contents = new List<CustomFormElement>(elements.Count);
foreach (var (_, element) in elements)
{
contents.Add(element);
}
return contents;
}
set => throw new NotSupportedException();
}

[JsonPropertyName("type")]
public string Type { get; private set; } = "custom_form";


private void OnCollectionChanged(object? sender, EventArgs args) => OnPropertyChanged(nameof(Elements));

[JsonIgnore]
public FormElementCollection<(string elementName, CustomFormElement element)> Elements
{
get => elements;
set
{
elements.Changed -= OnCollectionChanged;
elements = value;
elements.Changed += OnCollectionChanged;
OnPropertyChanged(nameof(Elements));
}
}

public void Append(CustomFormElement element)
=> elements.Add((element.Name, element));

public void Remove(CustomFormElement element)
=> elements.Remove((element.Name, element));

public void Remove(string elementName)
{
foreach (var pair in elements)
{
if (pair.elementName == elementName)
{
elements.Remove(pair);
return;
}
};
}

public void Remove(int index)
=> elements.RemoveAt(index);

protected override string Serialize() => JsonSerializer.Serialize(this);

#nullable enable
public event EventHandler<CustomFormCallbackEventArgs>? Callback;

internal void InvokeCallback(Dictionary<string, CustomFormElement> elements, Player player)
=> Callback?.Invoke(this, new(elements, player));

[JsonIgnore]
internal bool IsNullCallback => Callback is null;
}
63 changes: 63 additions & 0 deletions src/FormUI/CustomForm/CustomFormElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Text.Json.Serialization;

namespace Hosihikari.FormUI;

[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(Dropdown), "dropdown")]
[JsonDerivedType(typeof(Input), "input")]
[JsonDerivedType(typeof(Label), "label")]
[JsonDerivedType(typeof(Slider), "slider")]
[JsonDerivedType(typeof(StepSlider), "step_slider")]
[JsonDerivedType(typeof(Toggle), "toggle")]
public abstract class CustomFormElement : FormElementBase
{
[JsonIgnore]
public string Name { get; set; } = string.Empty;

[JsonIgnore]
public string Value { get; set; } = string.Empty;

[Flags]
public enum ElementType
{
Label,
Input,
Toggle,
Dropdown,
Slider,
StepSlider
}

[JsonIgnore]
public abstract ElementType FormElementType { get; }

public T GetValue<T>() where T : IParsable<T>, new()
{
if (T.TryParse(Value, null, out var result))
{
return result;
}
return new();
}


public CustomFormElement(string name)
{
Name = name;

PropertyChanged += (obj, args) =>
{
switch (args.PropertyName)
{
case "Value": break;
default: IsSerialized = false; break;
}
};
}

#nullable enable
public event EventHandler<EventArgs>? ValueChanged;

internal void InvokeValueChanged()
=> ValueChanged?.Invoke(this, EventArgs.Empty);
}
61 changes: 61 additions & 0 deletions src/FormUI/CustomForm/Dropdown.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Hosihikari.FormUI;

public class Dropdown : CustomFormElement
{
[JsonIgnore]
public override ElementType FormElementType => ElementType.Dropdown;

protected override string Serialize() => JsonSerializer.Serialize(this);

private string title = string.Empty;

private FormElementCollection<string> options;

private int? @default = -1;

public Dropdown(string name) : base(name)
{
options = new();
options.Changed += (_, _) => OnPropertyChanged(nameof(Options));
}

//[JsonPropertyName("type")]
//public string Type { get; private set; } = "dropdown";

[JsonPropertyName("text")]
public string Title
{
get => title;
set
{
title = value;
OnPropertyChanged(nameof(Title));
}
}

[JsonPropertyName("options")]
public FormElementCollection<string> Options
{
get => options;
set
{
options = value;
OnPropertyChanged(nameof(Options));
}
}

[JsonPropertyName("default")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Default
{
get => @default;
set
{
@default = value;
OnPropertyChanged(nameof(Default));
}
}
}
68 changes: 68 additions & 0 deletions src/FormUI/CustomForm/Input.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Hosihikari.FormUI;

public class Input : CustomFormElement
{
[JsonIgnore]
public override ElementType FormElementType => ElementType.Input;

protected override string Serialize()
{
return JsonSerializer.Serialize(this);
}

private string title = string.Empty;

#nullable enable
private string? placeHolder;

private string? @default;
#nullable disable

public Input(string name) : base(name)
{
}

//[JsonPropertyName("type")]
//public string Type { get; private set; } = "input";

[JsonPropertyName("text")]
public string Title
{
get => title;
set
{
title = value;
OnPropertyChanged(nameof(Title));
}
}


#nullable enable
[JsonPropertyName("placeholder")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? PlaceHolder
{
get => placeHolder;
set
{
placeHolder = value;
OnPropertyChanged(nameof(PlaceHolder));
}
}

[JsonPropertyName("default")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Default
{
get => @default;
set
{
@default = value;
OnPropertyChanged(nameof(Default));
}
}
#nullable disable
}
32 changes: 32 additions & 0 deletions src/FormUI/CustomForm/Label.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Hosihikari.FormUI;

public class Label : CustomFormElement
{
[JsonIgnore]
public override ElementType FormElementType => ElementType.Label;

protected override string Serialize() => JsonSerializer.Serialize(this);

private string text = string.Empty;

public Label(string name) : base(name)
{
}

//[JsonPropertyName("type")]
//public string Type { get; private set; } = "label";

[JsonPropertyName("text")]
public string Text
{
get => text;
set
{
text = value;
OnPropertyChanged(nameof(Text));
}
}
}
Loading

0 comments on commit 76f6928

Please sign in to comment.