/// <summary> /// Executes Immediate commands and enqueues unsafe commands. /// </summary> /// <param name="session">session that sent the command</param> /// <param name="requestInfo">request that tells us which command to execute</param> /// <seealso cref="Whisper.Daemon.Shard.Net.ShardServer.ExecuteQueuedCommand"/> protected override void ExecuteCommand(ShardSession session, ShardRequest requestInfo) { IWhisperCommand <ShardSession, ShardRequest> command; if (RegisteredCommands.TryGetValue(requestInfo.Key, out command)) { // best to assume the worst, right? CommandThreadSafety safety = CommandThreadSafety.NotThreadSafe; if (command is IThreadAwareCommand) { safety = (command as IThreadAwareCommand).ThreadSafety; } if (safety == CommandThreadSafety.Immediate) { // execute Immediate commands immediately base.ExecuteCommand(session, requestInfo); } else { // split remaining commands by thread safety. thread-safe commands are executed on a thread owned by the session that received them; thread-unsafe commands are executed on the server update thread CommandClosure closure = () => base.ExecuteCommand(session, requestInfo); if (safety == CommandThreadSafety.ThreadSafe) { session.EnqueueCommand(closure); } else { EnqueueCommand(closure); } } } // no need to log the 'else' case here. unknown packet notifications are handled by the Composer }
/// <summary> /// Enqueues a command to be executed on the next update tick. /// </summary> /// <param name="command">command to execute</param> public void EnqueueCommand(CommandClosure command) { commandQueue.Enqueue(command); }
/// <summary> /// Executes a command from the command queue. /// </summary> /// <param name="command">closure for the command to execute</param> protected virtual void ExecuteQueuedCommand(CommandClosure command) { command(); }