Skip to content

Commit

Permalink
[UnmanagedRemoteObject] Implement Casting
Browse files Browse the repository at this point in the history
  • Loading branch information
RemoteNet committed Oct 24, 2024
1 parent 7d6593f commit 4fb02ea
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/RemoteNET.Common/RemoteObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public abstract class RemoteObject
public abstract dynamic Dynamify();

public abstract ObjectOrRemoteAddress GetItem(ObjectOrRemoteAddress key);
public abstract RemoteObject Cast(Type t);

public abstract Type GetRemoteType();
public new Type GetType() => GetRemoteType();
Expand Down
36 changes: 18 additions & 18 deletions src/RemoteNET/Internal/RemoteObjectRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,23 @@ internal class RemoteObjectRef
{
private bool _isReleased;
private readonly TypeDump _typeInfo;
private ObjectDump _remoteObjectInfo;
private readonly DiverCommunicator _creatingCommunicator;
public ObjectDump RemoteObjectInfo { get; private set; }
public DiverCommunicator CreatingCommunicator { get; private set; }

// TODO: I think addresses as token should be reworked
public ulong Token => _remoteObjectInfo.PinnedAddress;
public DiverCommunicator Communicator => _creatingCommunicator;
public ulong Token => RemoteObjectInfo.PinnedAddress;
public DiverCommunicator Communicator => CreatingCommunicator;


public RemoteObjectRef(ObjectDump remoteObjectInfo, TypeDump typeInfo, DiverCommunicator creatingCommunicator)
{
if (typeInfo == null)
{
throw new ArgumentNullException(nameof(typeInfo));
}

_remoteObjectInfo = remoteObjectInfo;
RemoteObjectInfo = remoteObjectInfo;
_typeInfo = typeInfo;
_creatingCommunicator = creatingCommunicator;
CreatingCommunicator = creatingCommunicator;
_isReleased = false;
}

Expand All @@ -46,10 +45,10 @@ public MemberDump GetFieldDump(string name, bool refresh = false)
ThrowIfReleased();
if (refresh)
{
_remoteObjectInfo = _creatingCommunicator.DumpObject(_remoteObjectInfo.PinnedAddress, _remoteObjectInfo.Type);
RemoteObjectInfo = CreatingCommunicator.DumpObject(RemoteObjectInfo.PinnedAddress, RemoteObjectInfo.Type);
}

var field = _remoteObjectInfo.Fields.Single(fld => fld.Name == name);
var field = RemoteObjectInfo.Fields.Single(fld => fld.Name == name);
if (!string.IsNullOrEmpty(field.RetrivalError))
throw new Exception(
$"Field of the remote object could not be retrieved. Error: {field.RetrivalError}");
Expand All @@ -70,7 +69,7 @@ public MemberDump GetProperty(string name, bool refresh = false)
throw new NotImplementedException("Refreshing property values not supported yet");
}

var property = _remoteObjectInfo.Properties.Single(prop => prop.Name == name);
var property = RemoteObjectInfo.Properties.Single(prop => prop.Name == name);
if (!string.IsNullOrEmpty(property.RetrivalError))
{
throw new Exception(
Expand All @@ -92,51 +91,52 @@ private void ThrowIfReleased()
public InvocationResults InvokeMethod(string methodName, string[] genericArgsFullTypeNames, ObjectOrRemoteAddress[] args)
{
ThrowIfReleased();
return _creatingCommunicator.InvokeMethod(_remoteObjectInfo.PinnedAddress, _remoteObjectInfo.Type, methodName, genericArgsFullTypeNames, args);
string typeFullName = $"{_typeInfo.Assembly}!{_typeInfo.Type}";
return CreatingCommunicator.InvokeMethod(RemoteObjectInfo.PinnedAddress, typeFullName, methodName, genericArgsFullTypeNames, args);
}

public InvocationResults SetField(string fieldName, ObjectOrRemoteAddress newValue)
{
ThrowIfReleased();
return _creatingCommunicator.SetField(_remoteObjectInfo.PinnedAddress, _remoteObjectInfo.Type, fieldName, newValue);
return CreatingCommunicator.SetField(RemoteObjectInfo.PinnedAddress, RemoteObjectInfo.Type, fieldName, newValue);
}
public InvocationResults GetField(string fieldName)
{
ThrowIfReleased();
return _creatingCommunicator.GetField(_remoteObjectInfo.PinnedAddress, _remoteObjectInfo.Type, fieldName);
return CreatingCommunicator.GetField(RemoteObjectInfo.PinnedAddress, RemoteObjectInfo.Type, fieldName);
}

public void EventSubscribe(string eventName, DiverCommunicator.LocalEventCallback callbackProxy)
{
ThrowIfReleased();

_creatingCommunicator.EventSubscribe(_remoteObjectInfo.PinnedAddress, eventName, callbackProxy);
CreatingCommunicator.EventSubscribe(RemoteObjectInfo.PinnedAddress, eventName, callbackProxy);
}

public void EventUnsubscribe(string eventName, DiverCommunicator.LocalEventCallback callbackProxy)
{
ThrowIfReleased();

_creatingCommunicator.EventUnsubscribe(callbackProxy);
CreatingCommunicator.EventUnsubscribe(callbackProxy);
}

/// <summary>
/// Releases hold of the remote object in the remote process and the local proxy.
/// </summary>
public void RemoteRelease()
{
_creatingCommunicator.UnpinObject(_remoteObjectInfo.PinnedAddress);
CreatingCommunicator.UnpinObject(RemoteObjectInfo.PinnedAddress);
_isReleased = true;
}

public override string ToString()
{
return $"RemoteObjectRef. Address: {_remoteObjectInfo.PinnedAddress}, TypeFullName: {_typeInfo.Type}";
return $"RemoteObjectRef. Address: {RemoteObjectInfo.PinnedAddress}, TypeFullName: {_typeInfo.Type}";
}

internal ObjectOrRemoteAddress GetItem(ObjectOrRemoteAddress key)
{
return _creatingCommunicator.GetItem(this.Token, key);
return CreatingCommunicator.GetItem(this.Token, key);
}
}
}
5 changes: 5 additions & 0 deletions src/RemoteNET/ManagedRemoteObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,10 @@ public override ObjectOrRemoteAddress GetItem(ObjectOrRemoteAddress key)
{
return _ref.GetItem(key);
}

public override RemoteObject Cast(Type t)
{
throw new NotImplementedException("Not implemented in Managed context");
}
}
}
5 changes: 5 additions & 0 deletions src/RemoteNET/RemoteCharStar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ public override Type GetRemoteType()
{
return typeof(ScubaDiver.API.CharStar);
}

public override RemoteObject Cast(Type t)
{
throw new NotImplementedException("Not implemented for char* remote objects");
}
}
8 changes: 8 additions & 0 deletions src/RemoteNET/UnmanagedRemoteObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ public override string ToString()
{
return $"{nameof(UnmanagedRemoteObject)}. Type: {_type?.FullName ?? "UNK"} Reference: [{_ref}]";
}

public override RemoteObject Cast(Type t)
{
TypeDump dumpType = _app.Communicator.DumpType(t.FullName, t.Assembly.GetName().Name);

RemoteObjectRef ror = new RemoteObjectRef(_ref.RemoteObjectInfo, dumpType, _ref.CreatingCommunicator);
return new UnmanagedRemoteObject(ror, _app);
}
}

0 comments on commit 4fb02ea

Please sign in to comment.