mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-11-07 17:36:07 +00:00
Improve InvokeOnMainThread mechanism
Add documentation to make the invoke mechanism easier to understand Make it clear in documentation that code is invoked synchronously Use Action and Func<T> for minimizing the amount of code to write Use type parameter T to automatically adjust return value type Throw exceptions on the calling thread, not the main thread
This commit is contained in:
parent
9e5364a4ff
commit
c1cfaf520d
6 changed files with 164 additions and 59 deletions
|
|
@ -423,10 +423,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
int compressedDataSize = dataTypes.ReadNextInt(packetData);
|
||||
byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData);
|
||||
byte[] decompressed = ZlibUtils.Decompress(compressed);
|
||||
new Task(new Action(() =>
|
||||
{
|
||||
new Thread(() => {
|
||||
pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, addBitmap, currentDimension == 0, chunksContinuous, currentDimension, new Queue<byte>(decompressed));
|
||||
})).Start();
|
||||
}).Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -450,10 +449,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
else dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above
|
||||
}
|
||||
int dataSize = dataTypes.ReadNextVarInt(packetData);
|
||||
new Task(new Action(() =>
|
||||
{
|
||||
new Thread(() => {
|
||||
pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, 0, false, chunksContinuous, currentDimension, packetData);
|
||||
})).Start();
|
||||
}).Start();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -162,12 +162,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
}
|
||||
|
||||
//We have our chunk, save the chunk into the world
|
||||
handler.ScheduleTask(new Action(() =>
|
||||
handler.InvokeOnMainThread(() =>
|
||||
{
|
||||
if (handler.GetWorld()[chunkX, chunkZ] == null)
|
||||
handler.GetWorld()[chunkX, chunkZ] = new ChunkColumn();
|
||||
handler.GetWorld()[chunkX, chunkZ][chunkY] = chunk;
|
||||
}));
|
||||
});
|
||||
|
||||
//Pre-1.14 Lighting data
|
||||
if (protocolversion < Protocol18Handler.MC114Version)
|
||||
|
|
@ -192,10 +192,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (chunksContinuous && chunkMask == 0)
|
||||
{
|
||||
//Unload the entire chunk column
|
||||
handler.ScheduleTask(new Action(() =>
|
||||
handler.InvokeOnMainThread(() =>
|
||||
{
|
||||
handler.GetWorld()[chunkX, chunkZ] = null;
|
||||
}));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -214,12 +214,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
chunk[blockX, blockY, blockZ] = new Block(queue.Dequeue());
|
||||
|
||||
//We have our chunk, save the chunk into the world
|
||||
handler.ScheduleTask(new Action(() =>
|
||||
handler.InvokeOnMainThread(() =>
|
||||
{
|
||||
if (handler.GetWorld()[chunkX, chunkZ] == null)
|
||||
handler.GetWorld()[chunkX, chunkZ] = new ChunkColumn();
|
||||
handler.GetWorld()[chunkX, chunkZ][chunkY] = chunk;
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,10 +248,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (chunksContinuous && chunkMask == 0)
|
||||
{
|
||||
//Unload the entire chunk column
|
||||
handler.ScheduleTask(new Action(() =>
|
||||
handler.InvokeOnMainThread(() =>
|
||||
{
|
||||
handler.GetWorld()[chunkX, chunkZ] = null;
|
||||
}));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -297,12 +297,12 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
for (int blockX = 0; blockX < Chunk.SizeX; blockX++)
|
||||
chunk[blockX, blockY, blockZ] = new Block(blockTypes.Dequeue(), blockMeta.Dequeue());
|
||||
|
||||
handler.ScheduleTask(new Action(() =>
|
||||
handler.InvokeOnMainThread(() =>
|
||||
{
|
||||
if (handler.GetWorld()[chunkX, chunkZ] == null)
|
||||
handler.GetWorld()[chunkX, chunkZ] = new ChunkColumn();
|
||||
handler.GetWorld()[chunkX, chunkZ][chunkY] = chunk;
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,24 @@ namespace MinecraftClient.Protocol
|
|||
ILogger GetLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a task to run on the main thread
|
||||
/// Invoke a task on the main thread, wait for completion and retrieve return value.
|
||||
/// </summary>
|
||||
/// <param name="task">Task to run</param>
|
||||
/// <returns>Any result returned from delegate</returns>
|
||||
object ScheduleTask(Delegate task);
|
||||
/// <param name="task">Task to run with any type or return value</param>
|
||||
/// <returns>Any result returned from task, result type is inferred from the task</returns>
|
||||
/// <example>bool result = InvokeOnMainThread(methodThatReturnsAbool);</example>
|
||||
/// <example>bool result = InvokeOnMainThread(() => methodThatReturnsAbool(argument));</example>
|
||||
/// <example>int result = InvokeOnMainThread(() => { yourCode(); return 42; });</example>
|
||||
/// <typeparam name="T">Type of the return value</typeparam>
|
||||
T InvokeOnMainThread<T>(Func<T> task);
|
||||
|
||||
/// <summary>
|
||||
/// Invoke a task on the main thread and wait for completion
|
||||
/// </summary>
|
||||
/// <param name="task">Task to run without return value</param>
|
||||
/// <example>InvokeOnMainThread(methodThatReturnsNothing);</example>
|
||||
/// <example>InvokeOnMainThread(() => methodThatReturnsNothing(argument));</example>
|
||||
/// <example>InvokeOnMainThread(() => { yourCode(); });</example>
|
||||
void InvokeOnMainThread(Action task);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a network packet received or sent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue