1
0
mirror of https://github.com/oliverbooth/VpSharp synced 2024-11-10 05:15:42 +00:00

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;
using VpSharp.Internal.NativeAttributes; using VpSharp.Internal.NativeAttributes;
using static VpSharp.Internal.NativeMethods; using static VpSharp.Internal.NativeMethods;
@ -53,6 +54,7 @@ public class VirtualParadiseModelObject : VirtualParadiseObject
{ {
ArgumentNullException.ThrowIfNull(action); ArgumentNullException.ThrowIfNull(action);
var taskCompletionSource = new TaskCompletionSource<ReasonCode>();
var builder = new VirtualParadiseModelObjectBuilder(Client, this, ObjectBuilderMode.Modify); var builder = new VirtualParadiseModelObjectBuilder(Client, this, ObjectBuilderMode.Modify);
await Task.Run(() => action(builder)).ConfigureAwait(false); await Task.Run(() => action(builder)).ConfigureAwait(false);
@ -60,9 +62,25 @@ public class VirtualParadiseModelObject : VirtualParadiseObject
{ {
nint handle = Client.NativeInstanceHandle; nint handle = Client.NativeInstanceHandle;
_ = vp_int_set(handle, IntegerAttribute.ObjectId, Id); _ = vp_int_set(handle, IntegerAttribute.ObjectId, Id);
_ = vp_int_set(handle, IntegerAttribute.ReferenceNumber, Id);
builder.ApplyChanges(); 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() private void SetNativeCallbacks()
{ {
// SetNativeCallback(NativeCallback.ObjectAdd, OnObjectAddNativeCallback); // SetNativeCallback(NativeCallback.ObjectAdd, OnObjectAddNativeCallback);
// SetNativeCallback(NativeCallback.ObjectChange, OnObjectChangeNativeCallback); SetNativeCallback(NativeCallback.ObjectChange, OnObjectChangeNativeCallback);
// SetNativeCallback(NativeCallback.ObjectDelete, OnObjectDeleteNativeCallback); // SetNativeCallback(NativeCallback.ObjectDelete, OnObjectDeleteNativeCallback);
// SetNativeCallback(NativeCallback.GetFriends, OnGetFriendsNativeCallback); // SetNativeCallback(NativeCallback.GetFriends, OnGetFriendsNativeCallback);
// SetNativeCallback(NativeCallback.FriendAdd, OnFriendAddNativeCallback); // SetNativeCallback(NativeCallback.FriendAdd, OnFriendAddNativeCallback);
@ -49,6 +49,16 @@ public sealed partial class VirtualParadiseClient
taskCompletionSource.SetResult((reason, virtualParadiseObject)); 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) private void OnLoginNativeCallback(nint sender, ReasonCode reason, int reference)
{ {
_loginCompletionSource?.SetResult(reason); _loginCompletionSource?.SetResult(reason);

View File

@ -14,6 +14,8 @@ public sealed partial class VirtualParadiseClient
private readonly ConcurrentDictionary<int, TaskCompletionSource<(ReasonCode, VirtualParadiseObject?)>> private readonly ConcurrentDictionary<int, TaskCompletionSource<(ReasonCode, VirtualParadiseObject?)>>
_objectCompletionSources = new(); _objectCompletionSources = new();
private readonly ConcurrentDictionary<int, VirtualParadiseObject> _objects = new(); private readonly ConcurrentDictionary<int, VirtualParadiseObject> _objects = new();
private readonly ConcurrentDictionary<int, TaskCompletionSource<ReasonCode>> _objectUpdates = new();
/// <summary> /// <summary>
/// Enumerates all objects within a specified cell. /// 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) private VirtualParadiseObject AddOrUpdateObject(VirtualParadiseObject obj)
{ {
ArgumentNullException.ThrowIfNull(obj); ArgumentNullException.ThrowIfNull(obj);