public static void RegisterServer(SocketContext socketContext) { socketContext.AddPacketHandler<DownloadFileQuery>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, data.Length); stream.Close(); socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data }); }); socketContext.AddPacketHandler<UploadFilePacket>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write); await stream.WriteAsync(packet.Data, 0, packet.Data.Length); stream.Close(); }); socketContext.AddPacketHandler<FileExistsQuery>( async (packet) => { var fileExists = await VirtualFileSystem.FileExistsAsync(packet.Url); socketContext.Send(new FileExistsAnswer { StreamId = packet.StreamId, FileExists = fileExists }); }); }
public static void RegisterServer(SocketContext socketContext) { socketContext.AddPacketHandler <DownloadFileQuery>( async(packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, data.Length); stream.Close(); socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data }); }); socketContext.AddPacketHandler <UploadFilePacket>( async(packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write); await stream.WriteAsync(packet.Data, 0, packet.Data.Length); stream.Close(); }); socketContext.AddPacketHandler <FileExistsQuery>( async(packet) => { var fileExists = await VirtualFileSystem.FileExistsAsync(packet.Url); socketContext.Send(new FileExistsAnswer { StreamId = packet.StreamId, FileExists = fileExists }); }); }
protected override void Dispose(bool disposing) { socketContext.Send(new UploadFilePacket { Url = url, Data = memoryStream.ToArray() }); base.Dispose(disposing); }
public async Task ProcessLoginResult(string id, string pass, int session) { m_AccountInfo = new AccountInfo(); m_AccountInfo.Characters = new List <Tuple <int, int> >(); m_AccountInfo.StrUserID = id; m_AccountInfo.Password = pass; using (var reader = await Globals.ShardDB.ExecuteReaderAsync("exec _CertifyUser '{0}', '{1}', {2}", id, Utility.MD5Hash(pass, true), session)) { await reader.ReadAsync(); int type = await reader.GetFieldValueAsync <int>(0); if (type == 0) { m_AccountInfo.SID = await reader.GetFieldValueAsync <int>(1); m_AccountInfo.Auth = (AuthType)await reader.GetFieldValueAsync <byte>(2); Packet resp = new Packet(SCommon.Opcode.Agent.Response.CONNECTION); resp.WriteByte(1); m_SocketContext.Send(resp); } else { Disconnect(); } } }
private async void ShaderCompilerRequestHandler(SocketContext clientSocketContext, EffectLogStore recordedEffectCompile, EffectCompiler effectCompiler, ShaderCompilerRequest shaderCompilerRequest) { // Wait for a client to be connected await clientConnectedTCS.Task; // Yield so that this socket can continue its message loop to answer to shader file request. await Task.Yield(); Console.WriteLine("Compiling shader"); // A shader has been requested, compile it (asynchronously)! var precompiledEffectShaderPass = await effectCompiler.Compile(shaderCompilerRequest.MixinTree, null).AwaitResult(); // Record compilation to asset file (only if parent) recordedEffectCompile[new EffectCompileRequest(shaderCompilerRequest.MixinTree.Name, shaderCompilerRequest.MixinTree.UsedParameters)] = true; // Send compiled shader clientSocketContext.Send(new ShaderCompilerAnswer { StreamId = shaderCompilerRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode }); }
public async static Task ProcessClient(EngineContext engineContext, SocketContext socketContext, SocketContext socketContextAsync) { socketContext.AddPacketHandler <DownloadFileQuery>( async(packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, data.Length); stream.Close(); socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data }); }); socketContext.AddPacketHandler <UploadFilePacket>( async(packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write); await stream.WriteAsync(packet.Data, 0, packet.Data.Length); stream.Close(); }); var viewModelGlobalContext = new ViewModelGlobalContext(); selectedEntitiesContext = new ViewModelContext(viewModelGlobalContext); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EntityComponentEnumerator(engineContext)); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginEnumerator()); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); //selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EffectPropertyEnumerator(engineContext)); var renderPassHierarchyContext = new ViewModelContext(viewModelGlobalContext); renderPassHierarchyContext.ChildrenPropertyEnumerators.Add(new RenderPassHierarchyEnumerator()); renderPassHierarchyContext.Root = new ViewModelNode("Root", engineContext.RenderContext.RootRenderPass).GenerateChildren(renderPassHierarchyContext); var renderPassPluginsContext = new ViewModelContext(viewModelGlobalContext); renderPassPluginsContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginsEnumerator { SelectedRenderPassPluginContext = selectedEntitiesContext }); renderPassPluginsContext.Root = new ViewModelNode("Root", new EnumerableViewModelContent <ViewModelReference>( () => engineContext.RenderContext.RenderPassPlugins.Select(x => new ViewModelReference(x, true)))); var entityHierarchyEnumerator = new EntityHierarchyEnumerator(engineContext.EntityManager, selectedEntitiesContext); var entityHierarchyContext = new ViewModelContext(viewModelGlobalContext); entityHierarchyContext.ChildrenPropertyEnumerators.Add(entityHierarchyEnumerator); entityHierarchyContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); entityHierarchyContext.Root = new ViewModelNode("EntityHierarchyRoot", new EnumerableViewModelContent <ViewModelReference>( () => engineContext.EntityManager.Entities .Where(x => { var transformationComponent = x.Transformation; return(transformationComponent == null || transformationComponent.Parent == null); }) .Select(x => new ViewModelReference(x, true)))); entityHierarchyEnumerator.SelectedEntities.CollectionChanged += (sender, args) => { SelectEntity(entityHierarchyEnumerator.SelectedEntities); }; //entityHierarchyContext.Root.Children.Add(new ViewModelNode("SelectedItems", EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ViewModelReference>(new NullViewModelContent(), // (x) => { return new[] { new ViewModelReference(pickingSystem.SelectedEntity) }; }))); /*(value) => * { * var entityModelView = value != null ? entityHierarchyContext.GetModelView(value.Guid) : null; * var entity = entityModelView != null ? (Entity)entityModelView.NodeValue : null; * SelectEntity(entity); * })));*/ entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropEntity", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var movedItem = dropParameters.Data is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Data) : null; var newParent = dropParameters.Parent is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Parent) : null; if (newParent == null || movedItem == null) { return; } var parent = ((Entity)newParent.NodeValue).Transformation; if (dropParameters.TargetIndex > parent.Children.Count) { return; } var transformationComponent = ((Entity)movedItem.NodeValue).Transformation; transformationComponent.Parent = null; parent.Children.Insert(dropParameters.TargetIndex, transformationComponent); })))); entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropAsset", new RootViewModelContent((ExecuteCommand)(async(viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var assetUrl = (string)dropParameters.Data; /*var newParent = entityHierarchyContext.GetModelView((Guid)dropParameters.Parent); * * if (newParent == null || assetUrl == null) * return; * * var parent = ((Entity)newParent.NodeValue).Transformation; * if (dropParameters.ItemIndex > parent.Children.Count) * return;*/ engineContext.Scheduler.Add(async() => { // Load prefab entity var loadedEntityPrefab = await engineContext.AssetManager.LoadAsync <Entity>(assetUrl + "#"); // Build another entity from prefab var loadedEntity = Prefab.Inherit(loadedEntityPrefab); // Add it to scene engineContext.EntityManager.AddEntity(loadedEntity); if (loadedEntity.ContainsKey(AnimationComponent.Key)) { Scheduler.Current.Add(() => AnimScript.AnimateFBXModel(engineContext, loadedEntity)); } }); })))); var scriptEngineContext = new ViewModelContext(viewModelGlobalContext); scriptEngineContext.ChildrenPropertyEnumerators.Add(new ScriptAssemblyEnumerator(engineContext)); scriptEngineContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); scriptEngineContext.Root = new ViewModelNode(new EnumerableViewModelContent <ViewModelReference>( () => engineContext.ScriptManager.ScriptAssemblies.Select(x => new ViewModelReference(x, true)))); scriptEngineContext.Root.Children.Add(new ViewModelNode("RunScript", new RootViewModelContent((ExecuteCommand)(async(viewModel2, parameter) => { var scriptName = (string)parameter; var matchingScript = engineContext.ScriptManager.Scripts.Where(x => x.TypeName + "." + x.MethodName == scriptName); if (matchingScript.Any()) { var scriptEntry = matchingScript.Single(); var microThread = engineContext.ScriptManager.RunScript(scriptEntry, null); } })))); var runningScriptsContext = new ViewModelContext(viewModelGlobalContext); runningScriptsContext.ChildrenPropertyEnumerators.Add(new MicroThreadEnumerator(selectedEntitiesContext)); runningScriptsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); runningScriptsContext.Root = new ViewModelNode("MicroThreads", new EnumerableViewModelContent <ViewModelReference>( () => engineContext.Scheduler.MicroThreads.Select(x => new ViewModelReference(x, true)) )); var effectsContext = new ViewModelContext(viewModelGlobalContext); effectsContext.ChildrenPropertyEnumerators.Add(new EffectEnumerator(selectedEntitiesContext)); effectsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); effectsContext.Root = new ViewModelNode("Effects", new EnumerableViewModelContent <ViewModelReference>( () => engineContext.RenderContext.Effects.Select(x => new ViewModelReference(x, true)) )); //effectsContext.Root.Children.Add(new ViewModelNode("PluginDefinitions", new RootViewModelContent())); var assetBrowserContext = new ViewModelContext(viewModelGlobalContext); assetBrowserContext.ChildrenPropertyEnumerators.Add(new AssetBrowserEnumerator(engineContext)); assetBrowserContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); assetBrowserContext.Root = new ViewModelNode("Root", "Root").GenerateChildren(assetBrowserContext); var editorContext = new ViewModelContext(viewModelGlobalContext); editorContext.Root = new ViewModelNode("Root"); editorContext.Root.Children.Add(new ViewModelNode("SwitchSelectionMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.None; }))); editorContext.Root.Children.Add(new ViewModelNode("SwitchTranslationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Translation; }))); editorContext.Root.Children.Add(new ViewModelNode("SwitchRotationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Rotation; }))); var contexts = new Dictionary <string, Tuple <ViewModelContext, ViewModelState> >(); contexts.Add("Editor", Tuple.Create(editorContext, new ViewModelState())); contexts.Add("RenderPassPlugins", Tuple.Create(renderPassPluginsContext, new ViewModelState())); contexts.Add("RenderPasses", Tuple.Create(renderPassHierarchyContext, new ViewModelState())); contexts.Add("SelectedEntities", Tuple.Create(selectedEntitiesContext, new ViewModelState())); contexts.Add("EntityHierarchy", Tuple.Create(entityHierarchyContext, new ViewModelState())); contexts.Add("ScriptEngine", Tuple.Create(scriptEngineContext, new ViewModelState())); contexts.Add("MicroThreads", Tuple.Create(runningScriptsContext, new ViewModelState())); contexts.Add("AssetBrowser", Tuple.Create(assetBrowserContext, new ViewModelState())); contexts.Add("Effects", Tuple.Create(effectsContext, new ViewModelState())); int lastAckPacket = 0; var entitiesChangePackets = new ConcurrentQueue <EntitiesChangePacket>(); socketContext.AddPacketHandler <EntitiesChangePacket>( (packet) => { entitiesChangePackets.Enqueue(packet); entitiesChangePacketEvent.Set(); }); Action asyncThreadStart = () => { while (true) { Thread.Sleep(100); foreach (var context in contexts) { // Process async data Guid[] path = null; object value = null; lock (context.Value.Item1) { var pendingNode = context.Value.Item1.GetNextPendingAsyncNode(); if (pendingNode != null) { value = pendingNode.Value; path = ViewModelController.BuildPath(pendingNode); } } if (path != null) { // Temporary encoding through our serializer (until our serializer are used for packets) var memoryStream = new MemoryStream(); var writer = new BinarySerializationWriter(memoryStream); writer.SerializeExtended(null, value, ArchiveMode.Serialize); var change = new NetworkChange { Path = path.ToArray(), Type = NetworkChangeType.ValueUpdateAsync, Value = memoryStream.ToArray() }; var packet = new EntitiesChangePacket { GroupKey = context.Key, Changes = new NetworkChange[] { change } }; socketContextAsync.Send(packet); break; } } } }; new Thread(new ThreadStart(asyncThreadStart)).Start(); // TODO: Move some of this code directly inside ViewModelContext/Controller classes while (true) { await TaskEx.WhenAny(TaskEx.Delay(250), entitiesChangePacketEvent.WaitAsync()); EntitiesChangePacket packet; while (entitiesChangePackets.TryDequeue(out packet)) { ViewModelController.NetworkApplyChanges(contexts[packet.GroupKey].Item1, packet.Changes); lastAckPacket = packet.Index; } // Wait a single frame so that network updates get applied properly by all rendering systems for next update await Scheduler.Current.NextFrame(); // If entity disappeared, try to replace it with new one (happen during file reload) // It's little bit cumbersome to test, need some simplification of this specific entity view model root. if (selectedEntitiesContext.Root != null && selectedEntitiesContext.Root.Parent != null && selectedEntitiesContext.Root.Parent.NodeValue is Entity) { var entity = (Entity)selectedEntitiesContext.Root.Parent.NodeValue; if (!engineContext.EntityManager.Entities.Contains(entity)) { entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entity.Guid); if (entity != null) { selectedEntitiesContext.ViewModelByGuid.Clear(); selectedEntitiesContext.Root = selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName == "Components"); } } } var data = new Dictionary <string, byte[]>(); foreach (var context in contexts) { lock (context.Value.Item1) { if (context.Value.Item1.Root != null) { context.Value.Item1.AddModelView(context.Value.Item1.Root); } ViewModelController.UpdateReferences(context.Value.Item1, true); data[context.Key] = ViewModelController.NetworkSerialize(context.Value.Item1, context.Value.Item2); } } viewModelGlobalContext.UpdateObjects(contexts.Select(x => x.Value.Item1)); //Console.WriteLine("DataSize: {0}", data.Sum(x => x.Value.Length)); await Task.Factory.StartNew(() => socketContext.Send(new EntitiesUpdatePacket { AckIndex = lastAckPacket, Data = data })); } }
private async void ShaderCompilerRequestHandler(SocketContext clientSocketContext, EffectLogStore recordedEffectCompile, EffectCompiler effectCompiler, ShaderCompilerRequest shaderCompilerRequest) { // Wait for a client to be connected await clientConnectedTCS.Task; // Yield so that this socket can continue its message loop to answer to shader file request. await Task.Yield(); Console.WriteLine("Compiling shader"); // A shader has been requested, compile it (asynchronously)! var precompiledEffectShaderPass = await effectCompiler.Compile(shaderCompilerRequest.MixinTree, null).AwaitResult(); // Record compilation to asset file (only if parent) recordedEffectCompile[new EffectCompileRequest(shaderCompilerRequest.MixinTree.Name, shaderCompilerRequest.MixinTree.UsedParameters)] = true; // Send compiled shader clientSocketContext.Send(new ShaderCompilerAnswer { StreamId = shaderCompilerRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode }); }
#pragma warning disable 1998, 4014 public async Task ProcessLoginResult(Services._shard_item shard, string id, string password) { using (var reader = await Data.Globals.AccountDB.ExecuteReaderAsync("exec _CertifyTB_User '{0}', '{1}'", id, password)) { await reader.ReadAsync(); Packet resp = new Packet(SCommon.Opcode.Gateway.Response.LOGIN); int type = await reader.GetFieldValueAsync <int>(0); switch (type) { case 0: { int sid = await reader.GetFieldValueAsync <int>(1); byte sec_content = await reader.GetFieldValueAsync <byte>(2); int session_id = -1; lock (shard.m_lock) { if (shard.CurrentUsers < shard.MaxUsers) { session_id = Services.Session.Generate(); } } if (session_id != -1) { Data.Globals.GlobalDB.ExecuteCommandAsync("INSERT INTO _ActiveSessions (UserSID, SessionID, Processed) VALUES ({0}, {1}, 0)", sid, session_id); resp.WriteByte(1); resp.WriteInt32(session_id); resp.WriteAscii(Data.Globals.GetConfigValue <string>("GameServerIPAddress")); resp.WriteUInt16(Data.Globals.GetConfigValue <ushort>("GameServerPort")); } else { resp.WriteByte(2); resp.WriteByte(5); } } break; case 1: { int sid = await reader.GetFieldValueAsync <int>(1); string ban_reason = await reader.GetFieldValueAsync <string>(2); DateTime ban_endTime = await reader.GetFieldValueAsync <DateTime>(3); resp.WriteByte(2); resp.WriteByte(2); resp.WriteByte(1); resp.WriteAscii(ban_reason); resp.WriteUInt16(ban_endTime.Year); resp.WriteUInt16(ban_endTime.Month); resp.WriteUInt16(ban_endTime.Day); resp.WriteUInt16(ban_endTime.Hour); resp.WriteUInt16(ban_endTime.Minute); resp.WriteUInt16(ban_endTime.Second); resp.WriteInt32(ban_endTime.Millisecond); } break; case 2: { resp.WriteByte(2); resp.WriteByte(1); if (Data.Globals.WrongPasswordTries.ContainsKey(id)) { var wrong = Data.Globals.WrongPasswordTries[id]; resp.WriteInt32(++wrong.Tries); wrong.LastTick = Environment.TickCount; Data.Globals.WrongPasswordTries[id] = wrong; } else { var wrong = new Data._wrongpass_item { LastTick = Environment.TickCount, Tries = 1 }; Data.Globals.WrongPasswordTries.Add(id, wrong); resp.WriteInt32(1); } resp.WriteInt32(Data.Globals.MAX_WRONG_PASSWORD); } break; case 3: { //already in game packet } break; } m_SocketContext.Send(resp); Disconnect(); } }
public async static Task ProcessClient(EngineContext engineContext, SocketContext socketContext, SocketContext socketContextAsync) { socketContext.AddPacketHandler<DownloadFileQuery>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, data.Length); stream.Close(); socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data }); }); socketContext.AddPacketHandler<UploadFilePacket>( async (packet) => { var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write); await stream.WriteAsync(packet.Data, 0, packet.Data.Length); stream.Close(); }); var viewModelGlobalContext = new ViewModelGlobalContext(); selectedEntitiesContext = new ViewModelContext(viewModelGlobalContext); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EntityComponentEnumerator(engineContext)); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginEnumerator()); selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); //selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EffectPropertyEnumerator(engineContext)); var renderPassHierarchyContext = new ViewModelContext(viewModelGlobalContext); renderPassHierarchyContext.ChildrenPropertyEnumerators.Add(new RenderPassHierarchyEnumerator()); renderPassHierarchyContext.Root = new ViewModelNode("Root", engineContext.RenderContext.RootRenderPass).GenerateChildren(renderPassHierarchyContext); var renderPassPluginsContext = new ViewModelContext(viewModelGlobalContext); renderPassPluginsContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginsEnumerator { SelectedRenderPassPluginContext = selectedEntitiesContext }); renderPassPluginsContext.Root = new ViewModelNode("Root", new EnumerableViewModelContent<ViewModelReference>( () => engineContext.RenderContext.RenderPassPlugins.Select(x => new ViewModelReference(x, true)))); var entityHierarchyEnumerator = new EntityHierarchyEnumerator(engineContext.EntityManager, selectedEntitiesContext); var entityHierarchyContext = new ViewModelContext(viewModelGlobalContext); entityHierarchyContext.ChildrenPropertyEnumerators.Add(entityHierarchyEnumerator); entityHierarchyContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); entityHierarchyContext.Root = new ViewModelNode("EntityHierarchyRoot", new EnumerableViewModelContent<ViewModelReference>( () => engineContext.EntityManager.Entities .Where(x => { var transformationComponent = x.Transformation; return (transformationComponent == null || transformationComponent.Parent == null); }) .Select(x => new ViewModelReference(x, true)))); entityHierarchyEnumerator.SelectedEntities.CollectionChanged += (sender, args) => { SelectEntity(entityHierarchyEnumerator.SelectedEntities); }; //entityHierarchyContext.Root.Children.Add(new ViewModelNode("SelectedItems", EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ViewModelReference>(new NullViewModelContent(), // (x) => { return new[] { new ViewModelReference(pickingSystem.SelectedEntity) }; }))); /*(value) => { var entityModelView = value != null ? entityHierarchyContext.GetModelView(value.Guid) : null; var entity = entityModelView != null ? (Entity)entityModelView.NodeValue : null; SelectEntity(entity); })));*/ entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropEntity", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var movedItem = dropParameters.Data is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Data) : null; var newParent = dropParameters.Parent is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Parent) : null; if (newParent == null || movedItem == null) return; var parent = ((Entity)newParent.NodeValue).Transformation; if (dropParameters.TargetIndex > parent.Children.Count) return; var transformationComponent = ((Entity)movedItem.NodeValue).Transformation; transformationComponent.Parent = null; parent.Children.Insert(dropParameters.TargetIndex, transformationComponent); })))); entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropAsset", new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) => { var dropParameters = (DropCommandParameters)parameter; var assetUrl = (string)dropParameters.Data; /*var newParent = entityHierarchyContext.GetModelView((Guid)dropParameters.Parent); if (newParent == null || assetUrl == null) return; var parent = ((Entity)newParent.NodeValue).Transformation; if (dropParameters.ItemIndex > parent.Children.Count) return;*/ engineContext.Scheduler.Add(async () => { // Load prefab entity var loadedEntityPrefab = await engineContext.AssetManager.LoadAsync<Entity>(assetUrl + "#"); // Build another entity from prefab var loadedEntity = Prefab.Inherit(loadedEntityPrefab); // Add it to scene engineContext.EntityManager.AddEntity(loadedEntity); if (loadedEntity.ContainsKey(AnimationComponent.Key)) { Scheduler.Current.Add(() => AnimScript.AnimateFBXModel(engineContext, loadedEntity)); } }); })))); var scriptEngineContext = new ViewModelContext(viewModelGlobalContext); scriptEngineContext.ChildrenPropertyEnumerators.Add(new ScriptAssemblyEnumerator(engineContext)); scriptEngineContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); scriptEngineContext.Root = new ViewModelNode(new EnumerableViewModelContent<ViewModelReference>( () => engineContext.ScriptManager.ScriptAssemblies.Select(x => new ViewModelReference(x, true)))); scriptEngineContext.Root.Children.Add(new ViewModelNode("RunScript", new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) => { var scriptName = (string)parameter; var matchingScript = engineContext.ScriptManager.Scripts.Where(x => x.TypeName + "." + x.MethodName == scriptName); if (matchingScript.Any()) { var scriptEntry = matchingScript.Single(); var microThread = engineContext.ScriptManager.RunScript(scriptEntry, null); } })))); var runningScriptsContext = new ViewModelContext(viewModelGlobalContext); runningScriptsContext.ChildrenPropertyEnumerators.Add(new MicroThreadEnumerator(selectedEntitiesContext)); runningScriptsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); runningScriptsContext.Root = new ViewModelNode("MicroThreads", new EnumerableViewModelContent<ViewModelReference>( () => engineContext.Scheduler.MicroThreads.Select(x => new ViewModelReference(x, true)) )); var effectsContext = new ViewModelContext(viewModelGlobalContext); effectsContext.ChildrenPropertyEnumerators.Add(new EffectEnumerator(selectedEntitiesContext)); effectsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); effectsContext.Root = new ViewModelNode("Effects", new EnumerableViewModelContent<ViewModelReference>( () => engineContext.RenderContext.Effects.Select(x => new ViewModelReference(x, true)) )); //effectsContext.Root.Children.Add(new ViewModelNode("PluginDefinitions", new RootViewModelContent())); var assetBrowserContext = new ViewModelContext(viewModelGlobalContext); assetBrowserContext.ChildrenPropertyEnumerators.Add(new AssetBrowserEnumerator(engineContext)); assetBrowserContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator()); assetBrowserContext.Root = new ViewModelNode("Root", "Root").GenerateChildren(assetBrowserContext); var editorContext = new ViewModelContext(viewModelGlobalContext); editorContext.Root = new ViewModelNode("Root"); editorContext.Root.Children.Add(new ViewModelNode("SwitchSelectionMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.None; }))); editorContext.Root.Children.Add(new ViewModelNode("SwitchTranslationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Translation; }))); editorContext.Root.Children.Add(new ViewModelNode("SwitchRotationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Rotation; }))); var contexts = new Dictionary<string, Tuple<ViewModelContext, ViewModelState>>(); contexts.Add("Editor", Tuple.Create(editorContext, new ViewModelState())); contexts.Add("RenderPassPlugins", Tuple.Create(renderPassPluginsContext, new ViewModelState())); contexts.Add("RenderPasses", Tuple.Create(renderPassHierarchyContext, new ViewModelState())); contexts.Add("SelectedEntities", Tuple.Create(selectedEntitiesContext, new ViewModelState())); contexts.Add("EntityHierarchy", Tuple.Create(entityHierarchyContext, new ViewModelState())); contexts.Add("ScriptEngine", Tuple.Create(scriptEngineContext, new ViewModelState())); contexts.Add("MicroThreads", Tuple.Create(runningScriptsContext, new ViewModelState())); contexts.Add("AssetBrowser", Tuple.Create(assetBrowserContext, new ViewModelState())); contexts.Add("Effects", Tuple.Create(effectsContext, new ViewModelState())); int lastAckPacket = 0; var entitiesChangePackets = new ConcurrentQueue<EntitiesChangePacket>(); socketContext.AddPacketHandler<EntitiesChangePacket>( (packet) => { entitiesChangePackets.Enqueue(packet); entitiesChangePacketEvent.Set(); }); Action asyncThreadStart = () => { while (true) { Thread.Sleep(100); foreach (var context in contexts) { // Process async data Guid[] path = null; object value = null; lock (context.Value.Item1) { var pendingNode = context.Value.Item1.GetNextPendingAsyncNode(); if (pendingNode != null) { value = pendingNode.Value; path = ViewModelController.BuildPath(pendingNode); } } if (path != null) { // Temporary encoding through our serializer (until our serializer are used for packets) var memoryStream = new MemoryStream(); var writer = new BinarySerializationWriter(memoryStream); writer.SerializeExtended(null, value, ArchiveMode.Serialize); var change = new NetworkChange { Path = path.ToArray(), Type = NetworkChangeType.ValueUpdateAsync, Value = memoryStream.ToArray() }; var packet = new EntitiesChangePacket { GroupKey = context.Key, Changes = new NetworkChange[] { change } }; socketContextAsync.Send(packet); break; } } } }; new Thread(new ThreadStart(asyncThreadStart)).Start(); // TODO: Move some of this code directly inside ViewModelContext/Controller classes while (true) { await TaskEx.WhenAny(TaskEx.Delay(250), entitiesChangePacketEvent.WaitAsync()); EntitiesChangePacket packet; while (entitiesChangePackets.TryDequeue(out packet)) { ViewModelController.NetworkApplyChanges(contexts[packet.GroupKey].Item1, packet.Changes); lastAckPacket = packet.Index; } // Wait a single frame so that network updates get applied properly by all rendering systems for next update await Scheduler.Current.NextFrame(); // If entity disappeared, try to replace it with new one (happen during file reload) // It's little bit cumbersome to test, need some simplification of this specific entity view model root. if (selectedEntitiesContext.Root != null && selectedEntitiesContext.Root.Parent != null && selectedEntitiesContext.Root.Parent.NodeValue is Entity) { var entity = (Entity)selectedEntitiesContext.Root.Parent.NodeValue; if (!engineContext.EntityManager.Entities.Contains(entity)) { entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entity.Guid); if (entity != null) { selectedEntitiesContext.ViewModelByGuid.Clear(); selectedEntitiesContext.Root = selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName == "Components"); } } } var data = new Dictionary<string, byte[]>(); foreach (var context in contexts) { lock (context.Value.Item1) { if (context.Value.Item1.Root != null) context.Value.Item1.AddModelView(context.Value.Item1.Root); ViewModelController.UpdateReferences(context.Value.Item1, true); data[context.Key] = ViewModelController.NetworkSerialize(context.Value.Item1, context.Value.Item2); } } viewModelGlobalContext.UpdateObjects(contexts.Select(x => x.Value.Item1)); //Console.WriteLine("DataSize: {0}", data.Sum(x => x.Value.Length)); await Task.Factory.StartNew(() => socketContext.Send(new EntitiesUpdatePacket { AckIndex = lastAckPacket, Data = data })); } }