Map VP_CALLBACK_OBJECT_CHANGE

This commit is contained in:
Oliver Booth 2022-12-05 15:15:32 +00:00
parent d82a4d2e5e
commit 33d2ffa306
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
3 changed files with 43 additions and 2 deletions

View File

@ -1,3 +1,4 @@
using VpSharp.Exceptions;
using VpSharp.Internal;
using VpSharp.Internal.NativeAttributes;
using static VpSharp.Internal.NativeMethods;
@ -53,6 +54,7 @@ public class VirtualParadiseModelObject : VirtualParadiseObject
{
ArgumentNullException.ThrowIfNull(action);
var taskCompletionSource = new TaskCompletionSource<ReasonCode>();
var builder = new VirtualParadiseModelObjectBuilder(Client, this, ObjectBuilderMode.Modify);
await Task.Run(() => action(builder)).ConfigureAwait(false);
@ -60,9 +62,25 @@ public class VirtualParadiseModelObject : VirtualParadiseObject
{
nint handle = Client.NativeInstanceHandle;
_ = vp_int_set(handle, IntegerAttribute.ObjectId, Id);
_ = vp_int_set(handle, IntegerAttribute.ReferenceNumber, Id);
builder.ApplyChanges();
_ = vp_object_change(handle);
Client.AddObjectUpdateCompletionSource(Id, taskCompletionSource);
var reason = (ReasonCode)vp_object_change(handle);
if (reason != ReasonCode.Success)
{
Client.RemoveObjectUpdateCompletionSource(Id);
throw new VirtualParadiseException(reason);
}
}
ReasonCode result = await taskCompletionSource.Task.ConfigureAwait(false);
Client.RemoveObjectUpdateCompletionSource(Id);
if (result != ReasonCode.Success)
{
throw new VirtualParadiseException(result);
}
}

View File

@ -12,7 +12,7 @@ public sealed partial class VirtualParadiseClient
private void SetNativeCallbacks()
{
// SetNativeCallback(NativeCallback.ObjectAdd, OnObjectAddNativeCallback);
// SetNativeCallback(NativeCallback.ObjectChange, OnObjectChangeNativeCallback);
SetNativeCallback(NativeCallback.ObjectChange, OnObjectChangeNativeCallback);
// SetNativeCallback(NativeCallback.ObjectDelete, OnObjectDeleteNativeCallback);
// SetNativeCallback(NativeCallback.GetFriends, OnGetFriendsNativeCallback);
// SetNativeCallback(NativeCallback.FriendAdd, OnFriendAddNativeCallback);
@ -49,6 +49,16 @@ public sealed partial class VirtualParadiseClient
taskCompletionSource.SetResult((reason, virtualParadiseObject));
}
private void OnObjectChangeNativeCallback(nint sender, ReasonCode reason, int reference)
{
if (!_objectUpdates.TryGetValue(reference, out TaskCompletionSource<ReasonCode>? taskCompletionSource))
{
return;
}
taskCompletionSource.SetResult(reason);
}
private void OnLoginNativeCallback(nint sender, ReasonCode reason, int reference)
{
_loginCompletionSource?.SetResult(reason);

View File

@ -14,6 +14,8 @@ public sealed partial class VirtualParadiseClient
private readonly ConcurrentDictionary<int, TaskCompletionSource<(ReasonCode, VirtualParadiseObject?)>>
_objectCompletionSources = new();
private readonly ConcurrentDictionary<int, VirtualParadiseObject> _objects = new();
private readonly ConcurrentDictionary<int, TaskCompletionSource<ReasonCode>> _objectUpdates = new();
/// <summary>
/// Enumerates all objects within a specified cell.
@ -151,6 +153,17 @@ public sealed partial class VirtualParadiseClient
};
}
internal void AddObjectUpdateCompletionSource(int id, TaskCompletionSource<ReasonCode> taskCompletionSource)
{
_objectUpdates.AddOrUpdate(id, _ => taskCompletionSource, (_, _) => taskCompletionSource);
}
internal void RemoveObjectUpdateCompletionSource(int id)
{
_objectUpdates.TryRemove(id, out _);
}
private VirtualParadiseObject AddOrUpdateObject(VirtualParadiseObject obj)
{
ArgumentNullException.ThrowIfNull(obj);