InvokeOnMainThread: Avoid big lambda functions

This commit is contained in:
ORelio 2021-05-16 11:48:52 +02:00
parent ecb69bbdfd
commit 6fe6116831

View file

@ -703,7 +703,7 @@ namespace MinecraftClient
/// <typeparam name="T">Type of the return value</typeparam> /// <typeparam name="T">Type of the return value</typeparam>
public T InvokeOnMainThread<T>(Func<T> task) public T InvokeOnMainThread<T>(Func<T> task)
{ {
if (!InvokeRequired()) if (!InvokeRequired)
{ {
return task(); return task();
} }
@ -731,10 +731,12 @@ namespace MinecraftClient
} }
/// <summary> /// <summary>
/// Check if calling thread is main thread or other thread /// Check if running on a different thread and InvokeOnMainThread is required
/// </summary> /// </summary>
/// <returns>True if calling thread is other thread</returns> /// <returns>True if calling thread is not the main thread</returns>
public bool InvokeRequired() public bool InvokeRequired
{
get
{ {
int callingThreadId = Thread.CurrentThread.ManagedThreadId; int callingThreadId = Thread.CurrentThread.ManagedThreadId;
if (handler != null) if (handler != null)
@ -747,6 +749,7 @@ namespace MinecraftClient
return false; return false;
} }
} }
}
/// <summary> /// <summary>
/// Get a list of disallowed characters in chat /// Get a list of disallowed characters in chat
@ -764,8 +767,12 @@ namespace MinecraftClient
/// </summary> /// </summary>
public void BotLoad(ChatBot b, bool init = true) public void BotLoad(ChatBot b, bool init = true)
{ {
InvokeOnMainThread(() => if (InvokeRequired)
{ {
InvokeOnMainThread(() => BotLoad(b, init));
return;
}
b.SetHandler(this); b.SetHandler(this);
bots.Add(b); bots.Add(b);
if (init) if (init)
@ -773,7 +780,6 @@ namespace MinecraftClient
if (this.handler != null) if (this.handler != null)
DispatchBotEvent(bot => bot.AfterGameJoined(), new ChatBot[] { b }); DispatchBotEvent(bot => bot.AfterGameJoined(), new ChatBot[] { b });
Settings.SingleCommand = ""; Settings.SingleCommand = "";
});
} }
/// <summary> /// <summary>
@ -781,8 +787,12 @@ namespace MinecraftClient
/// </summary> /// </summary>
public void BotUnLoad(ChatBot b) public void BotUnLoad(ChatBot b)
{ {
InvokeOnMainThread(() => if (InvokeRequired)
{ {
InvokeOnMainThread(() => BotUnLoad(b));
return;
}
bots.RemoveAll(item => object.ReferenceEquals(item, b)); bots.RemoveAll(item => object.ReferenceEquals(item, b));
// ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon. // ToList is needed to avoid an InvalidOperationException from modfiying the list while it's being iterated upon.
@ -791,7 +801,6 @@ namespace MinecraftClient
{ {
UnregisterPluginChannel(entry.Key, b); UnregisterPluginChannel(entry.Key, b);
} }
});
} }
/// <summary> /// <summary>
@ -836,8 +845,9 @@ namespace MinecraftClient
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns> /// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetTerrainEnabled(bool enabled) public bool SetTerrainEnabled(bool enabled)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => SetTerrainEnabled(enabled));
if (enabled) if (enabled)
{ {
if (!terrainAndMovementsEnabled) if (!terrainAndMovementsEnabled)
@ -854,7 +864,6 @@ namespace MinecraftClient
world.Clear(); world.Clear();
} }
return true; return true;
});
} }
/// <summary> /// <summary>
@ -865,8 +874,9 @@ namespace MinecraftClient
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns> /// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetInventoryEnabled(bool enabled) public bool SetInventoryEnabled(bool enabled)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => SetInventoryEnabled(enabled));
if (enabled) if (enabled)
{ {
if (!inventoryHandlingEnabled) if (!inventoryHandlingEnabled)
@ -882,7 +892,6 @@ namespace MinecraftClient
inventories.Clear(); inventories.Clear();
} }
return true; return true;
});
} }
/// <summary> /// <summary>
@ -893,8 +902,9 @@ namespace MinecraftClient
/// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns> /// <returns>TRUE if the setting was applied immediately, FALSE if delayed.</returns>
public bool SetEntityHandlingEnabled(bool enabled) public bool SetEntityHandlingEnabled(bool enabled)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => SetEntityHandlingEnabled(enabled));
if (!enabled) if (!enabled)
{ {
if (entityHandlingEnabled) if (entityHandlingEnabled)
@ -912,7 +922,6 @@ namespace MinecraftClient
// Entity Handling cannot be enabled in runtime (or after joining server) // Entity Handling cannot be enabled in runtime (or after joining server)
return false; return false;
} }
});
} }
/// <summary> /// <summary>
@ -924,7 +933,13 @@ namespace MinecraftClient
/// <param name="enabled"></param> /// <param name="enabled"></param>
public void SetNetworkPacketCaptureEnabled(bool enabled) public void SetNetworkPacketCaptureEnabled(bool enabled)
{ {
InvokeOnMainThread(() => { networkPacketCaptureEnabled = enabled; }); if (InvokeRequired)
{
InvokeOnMainThread(() => SetNetworkPacketCaptureEnabled(enabled));
return;
}
networkPacketCaptureEnabled = enabled;
} }
#endregion #endregion
@ -974,12 +989,12 @@ namespace MinecraftClient
/// <returns> Item Dictionary indexed by Slot ID (Check wiki.vg for slot ID)</returns> /// <returns> Item Dictionary indexed by Slot ID (Check wiki.vg for slot ID)</returns>
public Container GetInventory(int inventoryID) public Container GetInventory(int inventoryID)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => GetInventory(inventoryID));
if (inventories.ContainsKey(inventoryID)) if (inventories.ContainsKey(inventoryID))
return inventories[inventoryID]; return inventories[inventoryID];
return null; return null;
});
} }
/// <summary> /// <summary>
@ -1093,7 +1108,10 @@ namespace MinecraftClient
/// <returns>True if packet successfully sent</returns> /// <returns>True if packet successfully sent</returns>
public bool SendRespawnPacket() public bool SendRespawnPacket()
{ {
return InvokeOnMainThread<bool>(handler.SendRespawnPacket); if (InvokeRequired)
return InvokeOnMainThread<bool>(SendRespawnPacket);
return handler.SendRespawnPacket();
} }
/// <summary> /// <summary>
@ -1103,8 +1121,12 @@ namespace MinecraftClient
/// <param name="bot">The bot to register the channel for.</param> /// <param name="bot">The bot to register the channel for.</param>
public void RegisterPluginChannel(string channel, ChatBot bot) public void RegisterPluginChannel(string channel, ChatBot bot)
{ {
InvokeOnMainThread(() => if (InvokeRequired)
{ {
InvokeOnMainThread(() => RegisterPluginChannel(channel, bot));
return;
}
if (registeredBotPluginChannels.ContainsKey(channel)) if (registeredBotPluginChannels.ContainsKey(channel))
{ {
registeredBotPluginChannels[channel].Add(bot); registeredBotPluginChannels[channel].Add(bot);
@ -1116,7 +1138,6 @@ namespace MinecraftClient
registeredBotPluginChannels[channel] = bots; registeredBotPluginChannels[channel] = bots;
SendPluginChannelMessage("REGISTER", Encoding.UTF8.GetBytes(channel), true); SendPluginChannelMessage("REGISTER", Encoding.UTF8.GetBytes(channel), true);
} }
});
} }
/// <summary> /// <summary>
@ -1126,8 +1147,12 @@ namespace MinecraftClient
/// <param name="bot">The bot to unregister the channel for.</param> /// <param name="bot">The bot to unregister the channel for.</param>
public void UnregisterPluginChannel(string channel, ChatBot bot) public void UnregisterPluginChannel(string channel, ChatBot bot)
{ {
InvokeOnMainThread(() => if (InvokeRequired)
{ {
InvokeOnMainThread(() => UnregisterPluginChannel(channel, bot));
return;
}
if (registeredBotPluginChannels.ContainsKey(channel)) if (registeredBotPluginChannels.ContainsKey(channel))
{ {
List<ChatBot> registeredBots = registeredBotPluginChannels[channel]; List<ChatBot> registeredBots = registeredBotPluginChannels[channel];
@ -1138,7 +1163,6 @@ namespace MinecraftClient
SendPluginChannelMessage("UNREGISTER", Encoding.UTF8.GetBytes(channel), true); SendPluginChannelMessage("UNREGISTER", Encoding.UTF8.GetBytes(channel), true);
} }
} }
});
} }
/// <summary> /// <summary>
@ -1151,8 +1175,9 @@ namespace MinecraftClient
/// <returns>Whether the packet was sent: true if it was sent, false if there was a connection error or it wasn't registered.</returns> /// <returns>Whether the packet was sent: true if it was sent, false if there was a connection error or it wasn't registered.</returns>
public bool SendPluginChannelMessage(string channel, byte[] data, bool sendEvenIfNotRegistered = false) public bool SendPluginChannelMessage(string channel, byte[] data, bool sendEvenIfNotRegistered = false)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => SendPluginChannelMessage(channel, data, sendEvenIfNotRegistered));
if (!sendEvenIfNotRegistered) if (!sendEvenIfNotRegistered)
{ {
if (!registeredBotPluginChannels.ContainsKey(channel)) if (!registeredBotPluginChannels.ContainsKey(channel))
@ -1165,7 +1190,6 @@ namespace MinecraftClient
} }
} }
return handler.SendPluginChannelPacket(channel, data); return handler.SendPluginChannelPacket(channel, data);
});
} }
/// <summary> /// <summary>
@ -1192,8 +1216,9 @@ namespace MinecraftClient
/// <returns>TRUE if the slot was successfully clicked</returns> /// <returns>TRUE if the slot was successfully clicked</returns>
public bool DoWindowAction(int windowId, int slotId, WindowActionType action) public bool DoWindowAction(int windowId, int slotId, WindowActionType action)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => DoWindowAction(windowId, slotId, action));
Item item = null; Item item = null;
if (inventories.ContainsKey(windowId) && inventories[windowId].Items.ContainsKey(slotId)) if (inventories.ContainsKey(windowId) && inventories[windowId].Items.ContainsKey(slotId))
item = inventories[windowId].Items[slotId]; item = inventories[windowId].Items[slotId];
@ -1475,7 +1500,6 @@ namespace MinecraftClient
} }
return result; return result;
});
} }
/// <summary> /// <summary>
@ -1510,8 +1534,9 @@ namespace MinecraftClient
/// <remarks>Sending close window for inventory 0 can cause server to update our inventory if there are any item in the crafting area</remarks> /// <remarks>Sending close window for inventory 0 can cause server to update our inventory if there are any item in the crafting area</remarks>
public bool CloseInventory(int windowId) public bool CloseInventory(int windowId)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => CloseInventory(windowId));
if (inventories.ContainsKey(windowId)) if (inventories.ContainsKey(windowId))
{ {
if (windowId != 0) if (windowId != 0)
@ -1519,7 +1544,6 @@ namespace MinecraftClient
return handler.SendCloseWindow(windowId); return handler.SendCloseWindow(windowId);
} }
return false; return false;
});
} }
/// <summary> /// <summary>
@ -1530,12 +1554,13 @@ namespace MinecraftClient
{ {
if (!inventoryHandlingEnabled) if (!inventoryHandlingEnabled)
return false; return false;
return InvokeOnMainThread(() =>
{ if (InvokeRequired)
return InvokeOnMainThread<bool>(ClearInventories);
inventories.Clear(); inventories.Clear();
inventories[0] = new Container(0, ContainerType.PlayerInventory, "Player Inventory"); inventories[0] = new Container(0, ContainerType.PlayerInventory, "Player Inventory");
return true; return true;
});
} }
/// <summary> /// <summary>
@ -1545,23 +1570,23 @@ namespace MinecraftClient
/// <param name="type">0: interact, 1: attack, 2: interact at</param> /// <param name="type">0: interact, 1: attack, 2: interact at</param>
/// <param name="hand">Hand.MainHand or Hand.OffHand</param> /// <param name="hand">Hand.MainHand or Hand.OffHand</param>
/// <returns>TRUE if interaction succeeded</returns> /// <returns>TRUE if interaction succeeded</returns>
public bool InteractEntity(int EntityID, int type, Hand hand = Hand.MainHand) public bool InteractEntity(int entityID, int type, Hand hand = Hand.MainHand)
{ {
return InvokeOnMainThread(() => if (InvokeRequired)
{ return InvokeOnMainThread(() => InteractEntity(entityID, type, hand));
if (entities.ContainsKey(EntityID))
if (entities.ContainsKey(entityID))
{ {
if (type == 0) if (type == 0)
{ {
return handler.SendInteractEntity(EntityID, type, (int)hand); return handler.SendInteractEntity(entityID, type, (int)hand);
} }
else else
{ {
return handler.SendInteractEntity(EntityID, type); return handler.SendInteractEntity(entityID, type);
} }
} }
else return false; else return false;
});
} }
/// <summary> /// <summary>
@ -1585,8 +1610,10 @@ namespace MinecraftClient
{ {
if (!GetTerrainEnabled()) if (!GetTerrainEnabled())
return false; return false;
return InvokeOnMainThread(() =>
{ if (InvokeRequired)
return InvokeOnMainThread(() => DigBlock(location, swingArms, lookAtBlock));
// TODO select best face from current player location // TODO select best face from current player location
Direction blockFace = Direction.Down; Direction blockFace = Direction.Down;
@ -1599,7 +1626,6 @@ namespace MinecraftClient
return handler.SendPlayerDigging(0, location, blockFace) return handler.SendPlayerDigging(0, location, blockFace)
&& (!swingArms || DoAnimation((int)Hand.MainHand)) && (!swingArms || DoAnimation((int)Hand.MainHand))
&& handler.SendPlayerDigging(2, location, blockFace); && handler.SendPlayerDigging(2, location, blockFace);
});
} }
/// <summary> /// <summary>
@ -1609,15 +1635,14 @@ namespace MinecraftClient
/// <returns>TRUE if the slot was changed</returns> /// <returns>TRUE if the slot was changed</returns>
public bool ChangeSlot(short slot) public bool ChangeSlot(short slot)
{ {
if (slot >= 0 && slot <= 8) if (slot < 0 || slot > 8)
{ return false;
return InvokeOnMainThread(() =>
{ if (InvokeRequired)
return InvokeOnMainThread(() => ChangeSlot(slot));
CurrentSlot = Convert.ToByte(slot); CurrentSlot = Convert.ToByte(slot);
return handler.SendHeldItemChange(slot); return handler.SendHeldItemChange(slot);
});
}
else return false;
} }
/// <summary> /// <summary>