/** * The function for the message queue monitoring thread used for * calling the callback from the remote Agent */ static void MessageThreadProc(Object ThreadParameters) { MessageThreadData ThreadData = (MessageThreadData)ThreadParameters; IAgentInterfaceWrapper Connection = ThreadData.Connection; try { // Because the way we use the GetMessage call is blocking, if we ever break out, quit AgentMessage ManagedMessage = null; while (Connection.GetMessage(ThreadData.ConnectionHandle, out ManagedMessage, -1) >= 0) { // TODO: As we add additional versions, convert to a switch rather than if-else. // For now, just use a simple if since we only have one version and a switch is // overkill. if (ManagedMessage.Version == ESwarmVersionValue.VER_1_0) { IntPtr NativeMessage = IntPtr.Zero; String PinnedStringData = null; switch (ManagedMessage.Type) { case EMessageType.JOB_STATE: { AgentJobState JobStateMessage = (AgentJobState)ManagedMessage; FGuid JobGuid = new FGuid(JobStateMessage.JobGuid.A, JobStateMessage.JobGuid.B, JobStateMessage.JobGuid.C, JobStateMessage.JobGuid.D); FJobState NativeJobStateMessage = new FJobState(JobGuid, (EJobTaskState)JobStateMessage.JobState); NativeJobStateMessage.JobExitCode = JobStateMessage.JobExitCode; NativeJobStateMessage.JobRunningTime = JobStateMessage.JobRunningTime; // If there is a message, be sure to pin and pass it on if (JobStateMessage.JobMessage != null) { Char[] RawJobMessageData = JobStateMessage.JobMessage.ToCharArray(); if (RawJobMessageData.Length > 0) { // Pin the string data for the message PinnedStringData = new String(RawJobMessageData); NativeJobStateMessage.JobMessage = FStringMarshaler.MarshalManagedToNative(PinnedStringData); } } NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FJobState))); Marshal.StructureToPtr(NativeJobStateMessage, NativeMessage, false); } break; case EMessageType.TASK_REQUEST: // Swallow this message, since it should not be sent along to a local connection // since all Job and Task information is contained within the Agent itself break; case EMessageType.TASK_REQUEST_RESPONSE: { AgentTaskRequestResponse TaskRequestResponseMessage = (AgentTaskRequestResponse)ManagedMessage; // Switch again on the response type ETaskRequestResponseType ResponseType = (ETaskRequestResponseType)TaskRequestResponseMessage.ResponseType; switch (ResponseType) { case ETaskRequestResponseType.RELEASE: case ETaskRequestResponseType.RESERVATION: { NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FTaskRequestResponse))); Marshal.StructureToPtr(new FTaskRequestResponse((ETaskRequestResponseType)ResponseType), NativeMessage, false); } break; case ETaskRequestResponseType.SPECIFICATION: { AgentTaskSpecification TaskSpecificationMessage = (AgentTaskSpecification)TaskRequestResponseMessage; FGuid TaskGuid = new FGuid(TaskSpecificationMessage.TaskGuid.A, TaskSpecificationMessage.TaskGuid.B, TaskSpecificationMessage.TaskGuid.C, TaskSpecificationMessage.TaskGuid.D); EJobTaskFlags TaskFlags = (EJobTaskFlags)TaskSpecificationMessage.TaskFlags; Char[] RawParametersData = TaskSpecificationMessage.Parameters.ToCharArray(); if (RawParametersData.Length > 0) { // Pin the string data for the message PinnedStringData = new String(RawParametersData); } FTaskSpecificationMarshalHelper MarshalHelper = new FTaskSpecificationMarshalHelper(); MarshalHelper.TaskGuid = TaskGuid; MarshalHelper.Parameters = FStringMarshaler.MarshalManagedToNative(PinnedStringData); MarshalHelper.Flags = TaskFlags; MarshalHelper.Cost = 0; MarshalHelper.DependencyCount = 0; MarshalHelper.Dependencies = IntPtr.Zero; NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FTaskSpecificationMarshalHelper))); Marshal.StructureToPtr(MarshalHelper, NativeMessage, false); } break; } } break; case EMessageType.TASK_STATE: { AgentTaskState TaskStateMessage = (AgentTaskState)ManagedMessage; // TODO: Assert that we have a valid Job GUID, since this must be the Instigator // TODO: Assert that the Job GUID of the message matches the ConnectionConfiguration.AgentJobGuid FGuid TaskGuid = new FGuid(TaskStateMessage.TaskGuid.A, TaskStateMessage.TaskGuid.B, TaskStateMessage.TaskGuid.C, TaskStateMessage.TaskGuid.D); FTaskState NativeTaskStateMessage = new FTaskState(TaskGuid, (EJobTaskState)TaskStateMessage.TaskState); // If there is a message, be sure to pin and pass it if (TaskStateMessage.TaskMessage != null) { Char[] RawTaskMessageData = TaskStateMessage.TaskMessage.ToCharArray(); if (RawTaskMessageData.Length > 0) { // Pin the string data for the message PinnedStringData = new String(RawTaskMessageData); NativeTaskStateMessage.TaskMessage = FStringMarshaler.MarshalManagedToNative(PinnedStringData); } } NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FTaskState))); Marshal.StructureToPtr(NativeTaskStateMessage, NativeMessage, false); } break; case EMessageType.INFO: { // Create the managed version of the info message AgentInfoMessage ManagedInfoMessage = (AgentInfoMessage)ManagedMessage; FInfoMessage NativeInfoMessage = new FInfoMessage(""); if (ManagedInfoMessage.TextMessage != null) { Char[] RawTaskMessageData = ManagedInfoMessage.TextMessage.ToCharArray(); if (RawTaskMessageData.Length > 0) { // Pin the string data for the message PinnedStringData = new String(RawTaskMessageData); NativeInfoMessage.TextMessage = FStringMarshaler.MarshalManagedToNative(PinnedStringData); } } NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FInfoMessage))); Marshal.StructureToPtr(NativeInfoMessage, NativeMessage, false); } break; case EMessageType.ALERT: { // Create the managed version of the info message AgentAlertMessage ManagedAlertMessage = (AgentAlertMessage)ManagedMessage; FGuid JobGuid = new FGuid(ManagedAlertMessage.JobGuid.A, ManagedAlertMessage.JobGuid.B, ManagedAlertMessage.JobGuid.C, ManagedAlertMessage.JobGuid.D); FGuid ObjectGuid = new FGuid(ManagedAlertMessage.ObjectGuid.A, ManagedAlertMessage.ObjectGuid.B, ManagedAlertMessage.ObjectGuid.C, ManagedAlertMessage.ObjectGuid.D); FAlertMessage NativeAlertMessage = new FAlertMessage( JobGuid, ManagedAlertMessage.AlertLevel, ObjectGuid, ManagedAlertMessage.TypeId); if (ManagedAlertMessage.TextMessage != null) { Char[] RawTaskMessageData = ManagedAlertMessage.TextMessage.ToCharArray(); if (RawTaskMessageData.Length > 0) { // Pin the string data for the message PinnedStringData = new String(RawTaskMessageData); NativeAlertMessage.TextMessage = FStringMarshaler.MarshalManagedToNative(PinnedStringData); } } NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FAlertMessage))); Marshal.StructureToPtr(NativeAlertMessage, NativeMessage, false); } break; default: // By default, just pass the message version and type through, but // any additional payload of a specialized type will be lost NativeMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FMessage))); Marshal.StructureToPtr(new FMessage(ESwarmVersionValue.VER_1_0, (EMessageType)ManagedMessage.Type), NativeMessage, false); break; } // If a message was created to pass on to the user's callback, send it on if (NativeMessage != IntPtr.Zero) { // Call the user's callback function ThreadData.ConnectionCallback(NativeMessage, ThreadData.ConnectionCallbackData); // All finished with the message, free and set to null NativeMessage = IntPtr.Zero; } if (ManagedMessage.Type == EMessageType.QUIT) { // Return from this function, which will exit this message processing thread DebugLog.Write("Message queue thread shutting down from a QUIT message"); return; } } // Reset the message handle ManagedMessage = null; } } catch (ThreadAbortException) { // An expected exception when closing the connection DebugLog.Write("Message queue thread shutting down normally after being closed by CloseConnection"); } catch (Exception Ex) { DebugLog.Write("Error: Exception in the message queue thread: " + Ex.Message); // If the connection has thrown us an exception, close the connection DebugLog.Write("MessageThreadProc calling CleanupClosedConnection"); ThreadData.Owner.CleanupClosedConnection(); } // Only write out in debug DebugLog.Write("Message queue thread shutting down normally"); }
/** * Opens a Job session, which allows a Job to be specified, Tasks added, Job * channels opened and used, etc. When the Job is complete and no more Job * related data is needed from the Swarm, call CloseJob. * * @param JobGuid A GUID that uniquely identifies this Job, generated by the caller * * @return Int32 Error code (< 0 is an error) */ public virtual Int32 OpenJob(FGuid JobGuid) { StartTiming("OpenJob-Managed", true); Int32 ReturnValue = Constants.INVALID; if (Connection != null) { StartTiming("OpenJob-Remote", false); try { AgentGuid ManagedJobGuid = new AgentGuid(JobGuid.A, JobGuid.B, JobGuid.C, JobGuid.D); ReturnValue = Connection.OpenJob(ConnectionHandle, ManagedJobGuid); if (ReturnValue >= 0) { // If the call was successful, assign the Job Guid as the active one ConnectionConfiguration.AgentJobGuid = ManagedJobGuid; // Allocate a new list to collect tasks until the specification is complete PendingTasks = new List<AgentTaskSpecification>(); } } catch (Exception Ex) { Log(EVerbosityLevel.Critical, ELogColour.Red, "[Interface:OpenJob] Error: " + Ex.Message); ReturnValue = Constants.ERROR_CONNECTION_DISCONNECTED; CleanupClosedConnection(); } StopTiming(); } else { ReturnValue = Constants.ERROR_CONNECTION_NOT_FOUND; } StopTiming(); return ReturnValue; }
public FStaticParameterBase(FStructFallback fallback) { ParameterInfo = fallback.GetOrDefault <FMaterialParameterInfo>(nameof(ParameterInfo)); bOverride = fallback.GetOrDefault <bool>(nameof(bOverride)); ExpressionGuid = fallback.GetOrDefault <FGuid>(nameof(ExpressionGuid)); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); bStaticLightingBuiltGUID = Ar.Read <FGuid>(); }
private FPakInfo(FArchive Ar, OffsetsToTry offsetToTry) { // New FPakInfo fields. EncryptionKeyGuid = Ar.Read <FGuid>(); // PakFile_Version_EncryptionKeyGuid EncryptedIndex = Ar.Read <byte>() != 0; // Do not replace by ReadFlag // Old FPakInfo fields Magic = Ar.Read <uint>(); if (Magic != PAK_FILE_MAGIC) { // Stop immediately when magic is wrong return; } Version = Ar.Read <EPakFileVersion>(); SubVersion = Ar.Read <short>(); IsSubVersion = Version == EPakFileVersion.PakFile_Version_FNameBasedCompressionMethod && offsetToTry == OffsetsToTry.Size8a; IndexOffset = Ar.Read <long>(); IndexSize = Ar.Read <long>(); IndexHash = new FSHAHash(Ar); if (Version == EPakFileVersion.PakFile_Version_FrozenIndex) { var bIndexIsFrozen = Ar.ReadFlag(); // used just for 4.25, so don't do any support unless it's really needed if (bIndexIsFrozen) { throw new ParserException(Ar, "Pak index is frozen"); } } if (Version < EPakFileVersion.PakFile_Version_FNameBasedCompressionMethod) { CompressionMethods = new List <CompressionMethod> { CompressionMethod.None, CompressionMethod.Zlib, CompressionMethod.Gzip, CompressionMethod.Oodle, CompressionMethod.LZ4 }; } else { var maxNumCompressionMethods = offsetToTry switch { OffsetsToTry.Size8a => 5, OffsetsToTry.Size8 => 4, OffsetsToTry.Size8_1 => 1, OffsetsToTry.Size8_2 => 2, OffsetsToTry.Size8_3 => 3, _ => 4 }; unsafe { var bufferSize = COMPRESSION_METHOD_NAME_LEN * maxNumCompressionMethods; var buffer = stackalloc byte[bufferSize]; Ar.Serialize(buffer, bufferSize); CompressionMethods = new List <CompressionMethod>(maxNumCompressionMethods + 1) { CompressionMethod.None }; for (var i = 0; i < maxNumCompressionMethods; i++) { var name = new string((sbyte *)buffer + i * COMPRESSION_METHOD_NAME_LEN, 0, COMPRESSION_METHOD_NAME_LEN).TrimEnd('\0'); if (string.IsNullOrEmpty(name)) { continue; } if (!Enum.TryParse(name, out CompressionMethod method)) { Log.Warning($"Unknown compression method '{name}' in {Ar.Name}"); method = CompressionMethod.Unknown; } CompressionMethods.Add(method); } } } // Reset new fields to their default states when seralizing older pak format. if (Version < EPakFileVersion.PakFile_Version_IndexEncryption) { EncryptedIndex = default; } if (Version < EPakFileVersion.PakFile_Version_EncryptionKeyGuid) { EncryptionKeyGuid = default; } }
public void DeserializePropertyTagValue(IAssetConverter converter) { this.Value = new FGuid(converter.GetExportStream()); }