Implement worker AddItem commands
This commit is contained in:
@@ -5,4 +5,17 @@ public interface IMxAccessServer
|
||||
int Register(string clientName);
|
||||
|
||||
void Unregister(int serverHandle);
|
||||
|
||||
int AddItem(
|
||||
int serverHandle,
|
||||
string itemDefinition);
|
||||
|
||||
int AddItem2(
|
||||
int serverHandle,
|
||||
string itemDefinition,
|
||||
string itemContext);
|
||||
|
||||
void RemoveItem(
|
||||
int serverHandle,
|
||||
int itemHandle);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,44 @@ public sealed class MxAccessComServer : IMxAccessServer
|
||||
Invoke(nameof(Unregister), serverHandle);
|
||||
}
|
||||
|
||||
public int AddItem(
|
||||
int serverHandle,
|
||||
string itemDefinition)
|
||||
{
|
||||
if (mxAccessComObject is ILMXProxyServer mxAccessServer)
|
||||
{
|
||||
return mxAccessServer.AddItem(serverHandle, itemDefinition);
|
||||
}
|
||||
|
||||
return (int)Invoke(nameof(AddItem), serverHandle, itemDefinition);
|
||||
}
|
||||
|
||||
public int AddItem2(
|
||||
int serverHandle,
|
||||
string itemDefinition,
|
||||
string itemContext)
|
||||
{
|
||||
if (mxAccessComObject is ILMXProxyServer3 mxAccessServer)
|
||||
{
|
||||
return mxAccessServer.AddItem2(serverHandle, itemDefinition, itemContext);
|
||||
}
|
||||
|
||||
return (int)Invoke(nameof(AddItem2), serverHandle, itemDefinition, itemContext);
|
||||
}
|
||||
|
||||
public void RemoveItem(
|
||||
int serverHandle,
|
||||
int itemHandle)
|
||||
{
|
||||
if (mxAccessComObject is ILMXProxyServer mxAccessServer)
|
||||
{
|
||||
mxAccessServer.RemoveItem(serverHandle, itemHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
Invoke(nameof(RemoveItem), serverHandle, itemHandle);
|
||||
}
|
||||
|
||||
private object Invoke(
|
||||
string methodName,
|
||||
params object[] arguments)
|
||||
|
||||
@@ -34,6 +34,9 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
|
||||
{
|
||||
MxCommandKind.Register => ExecuteRegister(command),
|
||||
MxCommandKind.Unregister => ExecuteUnregister(command),
|
||||
MxCommandKind.AddItem => ExecuteAddItem(command),
|
||||
MxCommandKind.AddItem2 => ExecuteAddItem2(command),
|
||||
MxCommandKind.RemoveItem => ExecuteRemoveItem(command),
|
||||
_ => CreateInvalidRequestReply(command, $"Unsupported MXAccess command kind {command.Kind}."),
|
||||
};
|
||||
}
|
||||
@@ -67,6 +70,66 @@ public sealed class MxAccessCommandExecutor : IStaCommandExecutor
|
||||
return CreateOkReply(command);
|
||||
}
|
||||
|
||||
private MxCommandReply ExecuteAddItem(StaCommand command)
|
||||
{
|
||||
if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.AddItem)
|
||||
{
|
||||
return CreateInvalidRequestReply(command, "AddItem command payload is required.");
|
||||
}
|
||||
|
||||
AddItemCommand addItemCommand = command.Command.AddItem;
|
||||
int itemHandle = session.AddItem(
|
||||
addItemCommand.ServerHandle,
|
||||
addItemCommand.ItemDefinition);
|
||||
|
||||
MxCommandReply reply = CreateOkReply(command);
|
||||
reply.ReturnValue = variantConverter.Convert(itemHandle);
|
||||
reply.AddItem = new AddItemReply
|
||||
{
|
||||
ItemHandle = itemHandle,
|
||||
};
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
private MxCommandReply ExecuteAddItem2(StaCommand command)
|
||||
{
|
||||
if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.AddItem2)
|
||||
{
|
||||
return CreateInvalidRequestReply(command, "AddItem2 command payload is required.");
|
||||
}
|
||||
|
||||
AddItem2Command addItem2Command = command.Command.AddItem2;
|
||||
int itemHandle = session.AddItem2(
|
||||
addItem2Command.ServerHandle,
|
||||
addItem2Command.ItemDefinition,
|
||||
addItem2Command.ItemContext);
|
||||
|
||||
MxCommandReply reply = CreateOkReply(command);
|
||||
reply.ReturnValue = variantConverter.Convert(itemHandle);
|
||||
reply.AddItem2 = new AddItem2Reply
|
||||
{
|
||||
ItemHandle = itemHandle,
|
||||
};
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
private MxCommandReply ExecuteRemoveItem(StaCommand command)
|
||||
{
|
||||
if (command.Command.PayloadCase != MxCommand.PayloadOneofCase.RemoveItem)
|
||||
{
|
||||
return CreateInvalidRequestReply(command, "RemoveItem command payload is required.");
|
||||
}
|
||||
|
||||
RemoveItemCommand removeItemCommand = command.Command.RemoveItem;
|
||||
session.RemoveItem(
|
||||
removeItemCommand.ServerHandle,
|
||||
removeItemCommand.ItemHandle);
|
||||
|
||||
return CreateOkReply(command);
|
||||
}
|
||||
|
||||
private static MxCommandReply CreateOkReply(StaCommand command)
|
||||
{
|
||||
return new MxCommandReply
|
||||
|
||||
@@ -6,12 +6,19 @@ namespace MxGateway.Worker.MxAccess;
|
||||
public sealed class MxAccessHandleRegistry
|
||||
{
|
||||
private readonly Dictionary<int, RegisteredServerHandle> serverHandles = new();
|
||||
private readonly Dictionary<long, RegisteredItemHandle> itemHandles = new();
|
||||
|
||||
public IReadOnlyList<RegisteredServerHandle> ServerHandles => serverHandles
|
||||
.Values
|
||||
.OrderBy(handle => handle.ServerHandle)
|
||||
.ToArray();
|
||||
|
||||
public IReadOnlyList<RegisteredItemHandle> ItemHandles => itemHandles
|
||||
.Values
|
||||
.OrderBy(handle => handle.ServerHandle)
|
||||
.ThenBy(handle => handle.ItemHandle)
|
||||
.ToArray();
|
||||
|
||||
public void RegisterServerHandle(
|
||||
int serverHandle,
|
||||
string clientName)
|
||||
@@ -22,10 +29,54 @@ public sealed class MxAccessHandleRegistry
|
||||
public void UnregisterServerHandle(int serverHandle)
|
||||
{
|
||||
serverHandles.Remove(serverHandle);
|
||||
|
||||
foreach (long key in itemHandles
|
||||
.Where(pair => pair.Value.ServerHandle == serverHandle)
|
||||
.Select(pair => pair.Key)
|
||||
.ToArray())
|
||||
{
|
||||
itemHandles.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsServerHandle(int serverHandle)
|
||||
{
|
||||
return serverHandles.ContainsKey(serverHandle);
|
||||
}
|
||||
|
||||
public void RegisterItemHandle(
|
||||
int serverHandle,
|
||||
int itemHandle,
|
||||
string itemDefinition,
|
||||
string itemContext,
|
||||
bool hasItemContext)
|
||||
{
|
||||
itemHandles[CreateItemKey(serverHandle, itemHandle)] = new RegisteredItemHandle(
|
||||
serverHandle,
|
||||
itemHandle,
|
||||
itemDefinition,
|
||||
itemContext,
|
||||
hasItemContext);
|
||||
}
|
||||
|
||||
public void RemoveItemHandle(
|
||||
int serverHandle,
|
||||
int itemHandle)
|
||||
{
|
||||
itemHandles.Remove(CreateItemKey(serverHandle, itemHandle));
|
||||
}
|
||||
|
||||
public bool ContainsItemHandle(
|
||||
int serverHandle,
|
||||
int itemHandle)
|
||||
{
|
||||
return itemHandles.ContainsKey(CreateItemKey(serverHandle, itemHandle));
|
||||
}
|
||||
|
||||
private static long CreateItemKey(
|
||||
int serverHandle,
|
||||
int itemHandle)
|
||||
{
|
||||
return ((long)serverHandle << 32) | (uint)itemHandle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,51 @@ public sealed class MxAccessSession : IDisposable
|
||||
handleRegistry.UnregisterServerHandle(serverHandle);
|
||||
}
|
||||
|
||||
public int AddItem(
|
||||
int serverHandle,
|
||||
string itemDefinition)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
int itemHandle = mxAccessServer.AddItem(serverHandle, itemDefinition);
|
||||
handleRegistry.RegisterItemHandle(
|
||||
serverHandle,
|
||||
itemHandle,
|
||||
itemDefinition,
|
||||
string.Empty,
|
||||
hasItemContext: false);
|
||||
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
public int AddItem2(
|
||||
int serverHandle,
|
||||
string itemDefinition,
|
||||
string itemContext)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
int itemHandle = mxAccessServer.AddItem2(serverHandle, itemDefinition, itemContext);
|
||||
handleRegistry.RegisterItemHandle(
|
||||
serverHandle,
|
||||
itemHandle,
|
||||
itemDefinition,
|
||||
itemContext,
|
||||
hasItemContext: true);
|
||||
|
||||
return itemHandle;
|
||||
}
|
||||
|
||||
public void RemoveItem(
|
||||
int serverHandle,
|
||||
int itemHandle)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
mxAccessServer.RemoveItem(serverHandle, itemHandle);
|
||||
handleRegistry.RemoveItemHandle(serverHandle, itemHandle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
|
||||
@@ -81,6 +81,19 @@ public sealed class MxAccessStaSession : IDisposable
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<RegisteredItemHandle>> GetRegisteredItemHandlesAsync(
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (session is null)
|
||||
{
|
||||
throw new InvalidOperationException("MXAccess COM session has not been started.");
|
||||
}
|
||||
|
||||
return staRuntime.InvokeAsync(
|
||||
() => session.HandleRegistry.ItemHandles,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace MxGateway.Worker.MxAccess;
|
||||
|
||||
public sealed class RegisteredItemHandle
|
||||
{
|
||||
public RegisteredItemHandle(
|
||||
int serverHandle,
|
||||
int itemHandle,
|
||||
string itemDefinition,
|
||||
string itemContext,
|
||||
bool hasItemContext)
|
||||
{
|
||||
ServerHandle = serverHandle;
|
||||
ItemHandle = itemHandle;
|
||||
ItemDefinition = itemDefinition;
|
||||
ItemContext = itemContext;
|
||||
HasItemContext = hasItemContext;
|
||||
}
|
||||
|
||||
public int ServerHandle { get; }
|
||||
|
||||
public int ItemHandle { get; }
|
||||
|
||||
public string ItemDefinition { get; }
|
||||
|
||||
public string ItemContext { get; }
|
||||
|
||||
public bool HasItemContext { get; }
|
||||
}
|
||||
Reference in New Issue
Block a user