2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.Collections.Specialized;
7 using System.Threading;
8 using System.Threading.Tasks;
9 using System.Xml.Serialization;
10 using SiliconStudio.Paradox;
11 using SiliconStudio.Paradox.Engine.Network;
12 using SiliconStudio.Paradox.Effects;
13 using SiliconStudio.Paradox.Engine;
14 using SiliconStudio.Paradox.EntityModel;
15 using SiliconStudio.Paradox.Configuration;
16 using SiliconStudio.Core.Extensions;
17 using SiliconStudio.Paradox.Games.IO;
18 using SiliconStudio.Paradox.Games.MicroThreading;
19 using SiliconStudio.Paradox.Games.ViewModel;
20 using SiliconStudio.Paradox.Games.Serialization;
21 using SiliconStudio.Paradox.Prefabs;
30 [Framework.Serialization.SerializableExtended]
41 public Dictionary<string, byte[]>
Data {
get; set; }
44 [Framework.Serialization.SerializableExtended]
52 public NetworkChange[]
Changes {
get; set; }
58 private static ViewModelContext selectedEntitiesContext;
59 private static AsyncSignal entitiesChangePacketEvent =
new AsyncSignal();
70 [XmlAttribute(
"debugmanager")]
73 [XmlAttribute(
"port")]
74 public int Port {
get; set; }
87 var configDebug = AppConfig.GetConfiguration<
Config>(
"ScriptDebug");
88 return (configDebug.DebugManager);
100 if (selectedEntitiesContext != null)
102 selectedEntitiesContext.ViewModelByGuid.Clear();
103 var viewModels = entities
104 .Where(entity => entity != null)
105 .Select(entity => selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName ==
"Components"))
108 if (viewModels.Count() > 1)
109 selectedEntitiesContext.Root = ViewModelController.Combine(selectedEntitiesContext, viewModels);
111 selectedEntitiesContext.Root = viewModels.FirstOrDefault();
116 var entitiesArray = entities.ToArray();
120 entitiesChangePacketEvent.Set();
125 var config = AppConfig.GetConfiguration<
Config>(
"ScriptDebug");
128 engineContext.RenderContext.PrepareEffectPlugins += (effectBuilder, plugins) =>
130 if (effectBuilder.PickingPassMainPlugin != null)
133 if (engineContext.DataContext.RenderPassPlugins.TryGetValue(effectBuilder.Name ==
"Gizmo" ?
"MouseOverPickingPlugin" :
"PickingPlugin", out pickingPlugin))
134 plugins.Add(
new PickingShaderPlugin { RenderPassPlugin = (PickingPlugin)pickingPlugin, MainPlugin = effectBuilder.PickingPassMainPlugin });
136 if (effectBuilder.SupportWireframe)
139 if (engineContext.DataContext.RenderPassPlugins.TryGetValue(
"WireframePlugin", out wireframePlugin))
140 plugins.Add(
new WireframeShaderPlugin { RenderPassPlugin = wireframePlugin, MainTargetPlugin = renderingSetup.MainTargetPlugin });
145 pickingSystem.PropertyChanged += pickingSystem_PropertyChanged;
151 var currentScheduler = Scheduler.Current;
155 socketContext.Connected = (clientSocketContext) =>
159 pendingClient.MainSocket = clientSocketContext;
160 if (pendingClient.AsyncSocket != null)
161 currentScheduler.Add(() =>
ProcessClient(engineContext, pendingClient.MainSocket, pendingClient.AsyncSocket));
164 socketContextAsync.Connected = (clientSocketContext) =>
168 pendingClient.AsyncSocket = clientSocketContext;
169 if (pendingClient.MainSocket != null)
170 currentScheduler.Add(() =>
ProcessClient(engineContext, pendingClient.MainSocket, pendingClient.AsyncSocket));
174 socketContext.StartServer(config.Port);
175 socketContextAsync.StartServer(config.Port + 1);
178 static void pickingSystem_PropertyChanged(
object sender, System.ComponentModel.PropertyChangedEventArgs e)
180 if (e.PropertyName ==
"SelectedEntity")
191 var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read);
192 var data =
new byte[stream.Length];
193 await stream.ReadAsync(data, 0, data.Length);
195 socketContext.Send(
new DownloadFileAnswer { StreamId = packet.StreamId, Data = data });
201 var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write);
202 await stream.WriteAsync(packet.Data, 0, packet.Data.Length);
206 var viewModelGlobalContext =
new ViewModelGlobalContext();
208 selectedEntitiesContext =
new ViewModelContext(viewModelGlobalContext);
211 selectedEntitiesContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
214 var renderPassHierarchyContext =
new ViewModelContext(viewModelGlobalContext);
216 renderPassHierarchyContext.Root =
new ViewModelNode(
"Root", engineContext.RenderContext.RootRenderPass).GenerateChildren(renderPassHierarchyContext);
218 var renderPassPluginsContext =
new ViewModelContext(viewModelGlobalContext);
219 renderPassPluginsContext.ChildrenPropertyEnumerators.Add(
new RenderPassPluginsEnumerator { SelectedRenderPassPluginContext = selectedEntitiesContext });
220 renderPassPluginsContext.Root =
new ViewModelNode(
"Root",
new EnumerableViewModelContent<ViewModelReference>(
221 () => engineContext.RenderContext.RenderPassPlugins.Select(x =>
new ViewModelReference(x,
true))));
225 var entityHierarchyContext =
new ViewModelContext(viewModelGlobalContext);
226 entityHierarchyContext.ChildrenPropertyEnumerators.Add(entityHierarchyEnumerator);
227 entityHierarchyContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
228 entityHierarchyContext.Root =
new ViewModelNode(
"EntityHierarchyRoot",
new EnumerableViewModelContent<ViewModelReference>(
229 () => engineContext.EntityManager.Entities
232 var transformationComponent = x.Transformation;
233 return (transformationComponent == null || transformationComponent.Parent == null);
235 .Select(x =>
new ViewModelReference(x,
true))));
237 entityHierarchyEnumerator.SelectedEntities.CollectionChanged += (sender, args) =>
239 SelectEntity(entityHierarchyEnumerator.SelectedEntities);
249 entityHierarchyContext.Root.Children.Add(
new ViewModelNode(
"DropEntity",
new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) =>
251 var dropParameters = (DropCommandParameters)parameter;
253 var movedItem = dropParameters.Data is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Data) : null;
254 var newParent = dropParameters.Parent is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Parent) : null;
256 if (newParent == null || movedItem == null)
259 var parent = ((
Entity)newParent.NodeValue).Transformation;
260 if (dropParameters.TargetIndex > parent.Children.Count)
263 var transformationComponent = ((
Entity)movedItem.NodeValue).Transformation;
264 transformationComponent.Parent = null;
265 parent.Children.Insert(dropParameters.TargetIndex, transformationComponent);
268 entityHierarchyContext.Root.Children.Add(
new ViewModelNode(
"DropAsset",
new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) =>
270 var dropParameters = (DropCommandParameters)parameter;
272 var assetUrl = (string)dropParameters.Data;
282 engineContext.Scheduler.Add(async () =>
285 var loadedEntityPrefab = await engineContext.AssetManager.LoadAsync<
Entity>(assetUrl +
"#");
288 var loadedEntity = Prefab.Inherit(loadedEntityPrefab);
291 engineContext.EntityManager.AddEntity(loadedEntity);
300 var scriptEngineContext =
new ViewModelContext(viewModelGlobalContext);
302 scriptEngineContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
303 scriptEngineContext.Root =
new ViewModelNode(
new EnumerableViewModelContent<ViewModelReference>(
304 () => engineContext.ScriptManager.ScriptAssemblies.Select(x =>
new ViewModelReference(x,
true))));
305 scriptEngineContext.Root.Children.Add(
new ViewModelNode(
"RunScript",
new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) =>
307 var scriptName = (string)parameter;
308 var matchingScript = engineContext.ScriptManager.Scripts.Where(x => x.TypeName +
"." + x.MethodName == scriptName);
309 if (matchingScript.Any())
311 var scriptEntry = matchingScript.Single();
312 var microThread = engineContext.ScriptManager.RunScript(scriptEntry, null);
316 var runningScriptsContext =
new ViewModelContext(viewModelGlobalContext);
317 runningScriptsContext.ChildrenPropertyEnumerators.Add(
new MicroThreadEnumerator(selectedEntitiesContext));
318 runningScriptsContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
319 runningScriptsContext.Root =
new ViewModelNode(
"MicroThreads",
new EnumerableViewModelContent<ViewModelReference>(
320 () => engineContext.Scheduler.MicroThreads.Select(x =>
new ViewModelReference(x,
true))
323 var effectsContext =
new ViewModelContext(viewModelGlobalContext);
324 effectsContext.ChildrenPropertyEnumerators.Add(
new EffectEnumerator(selectedEntitiesContext));
325 effectsContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
326 effectsContext.Root =
new ViewModelNode(
"Effects",
new EnumerableViewModelContent<ViewModelReference>(
327 () => engineContext.RenderContext.Effects.Select(x =>
new ViewModelReference(x,
true))
331 var assetBrowserContext =
new ViewModelContext(viewModelGlobalContext);
333 assetBrowserContext.ChildrenPropertyEnumerators.Add(
new ChildrenPropertyInfoEnumerator());
334 assetBrowserContext.Root =
new ViewModelNode(
"Root",
"Root").GenerateChildren(assetBrowserContext);
336 var editorContext =
new ViewModelContext(viewModelGlobalContext);
337 editorContext.Root =
new ViewModelNode(
"Root");
338 editorContext.Root.Children.Add(
new ViewModelNode(
"SwitchSelectionMode",
new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.None; })));
339 editorContext.Root.Children.Add(
new ViewModelNode(
"SwitchTranslationMode",
new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Translation; })));
340 editorContext.Root.Children.Add(
new ViewModelNode(
"SwitchRotationMode",
new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Rotation; })));
342 var contexts =
new Dictionary<string, Tuple<ViewModelContext, ViewModelState>>();
343 contexts.Add(
"Editor", Tuple.Create(editorContext,
new ViewModelState()));
344 contexts.Add(
"RenderPassPlugins", Tuple.Create(renderPassPluginsContext,
new ViewModelState()));
345 contexts.Add(
"RenderPasses", Tuple.Create(renderPassHierarchyContext,
new ViewModelState()));
346 contexts.Add(
"SelectedEntities", Tuple.Create(selectedEntitiesContext,
new ViewModelState()));
347 contexts.Add(
"EntityHierarchy", Tuple.Create(entityHierarchyContext,
new ViewModelState()));
348 contexts.Add(
"ScriptEngine", Tuple.Create(scriptEngineContext,
new ViewModelState()));
349 contexts.Add(
"MicroThreads", Tuple.Create(runningScriptsContext,
new ViewModelState()));
350 contexts.Add(
"AssetBrowser", Tuple.Create(assetBrowserContext,
new ViewModelState()));
351 contexts.Add(
"Effects", Tuple.Create(effectsContext,
new ViewModelState()));
353 int lastAckPacket = 0;
355 var entitiesChangePackets =
new ConcurrentQueue<EntitiesChangePacket>();
359 entitiesChangePackets.Enqueue(packet);
360 entitiesChangePacketEvent.Set();
363 Action asyncThreadStart = () =>
368 foreach (var context
in contexts)
373 lock (context.Value.Item1)
375 var pendingNode = context.Value.Item1.GetNextPendingAsyncNode();
376 if (pendingNode != null)
378 value = pendingNode.Value;
379 path = ViewModelController.BuildPath(pendingNode);
385 var memoryStream =
new MemoryStream();
386 var writer =
new BinarySerializationWriter(memoryStream);
387 writer.SerializeExtended(null, value, ArchiveMode.Serialize);
389 var change =
new NetworkChange { Path = path.ToArray(), Type = NetworkChangeType.ValueUpdateAsync, Value = memoryStream.ToArray() };
390 var packet =
new EntitiesChangePacket { GroupKey = context.Key, Changes =
new NetworkChange[] { change } };
391 socketContextAsync.Send(packet);
398 new Thread(
new ThreadStart(asyncThreadStart)).Start();
403 await TaskEx.WhenAny(TaskEx.Delay(250), entitiesChangePacketEvent.WaitAsync());
406 while (entitiesChangePackets.TryDequeue(out packet))
408 ViewModelController.NetworkApplyChanges(contexts[packet.GroupKey].Item1, packet.Changes);
409 lastAckPacket = packet.Index;
413 await Scheduler.Current.NextFrame();
417 if (selectedEntitiesContext.Root != null
418 && selectedEntitiesContext.Root.Parent != null
419 && selectedEntitiesContext.Root.Parent.NodeValue is
Entity)
421 var entity = (Entity)selectedEntitiesContext.Root.Parent.NodeValue;
422 if (!engineContext.EntityManager.Entities.Contains(entity))
424 entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entity.Guid);
427 selectedEntitiesContext.ViewModelByGuid.Clear();
428 selectedEntitiesContext.Root = selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName ==
"Components");
433 var data =
new Dictionary<string, byte[]>();
434 foreach (var context
in contexts)
436 lock (context.Value.Item1)
438 if (context.Value.Item1.Root != null)
439 context.Value.Item1.AddModelView(context.Value.Item1.Root);
440 ViewModelController.UpdateReferences(context.Value.Item1,
true);
441 data[context.Key] = ViewModelController.NetworkSerialize(context.Value.Item1, context.Value.Item2);
445 viewModelGlobalContext.UpdateObjects(contexts.Select(x => x.Value.Item1));
448 await Task.Factory.StartNew(() => socketContext.
Send(
new EntitiesUpdatePacket { AckIndex = lastAckPacket, Data = data }));
static void SelectEntity(params Entity[] entities)
Entity[] SelectedEntities
Gets or sets currently selected entity.
Game entity. It usually aggregates multiple EntityComponent
SocketContext AsyncSocket
static async Task AnimateFBXModel(EngineContext engineContext, Entity characterEntity, float endAnimTime=0.0f, float loopTime=0.0f)
static bool IsDebugManager
static async Task ProcessClient(EngineContext engineContext, SocketContext socketContext, SocketContext socketContextAsync)
System.Threading.Tasks.Task Task
Add animation capabilities to an Entity. It will usually apply to ModelComponent.ModelViewHierarchy ...
static readonly RenderingSetup Singleton
int AckIndex
Gets or sets the index of the last acknowledged packet. This is useful for client-side prediction...
int Index
Gets or sets the index of this update packet.
static async Task RunDebug(EngineContext engineContext)
Dictionary< string, byte[]> Data
static PropertyKey< AnimationComponent > Key
async Task ProcessGizmoAndPicking(EngineContext engineContext)
static void SelectEntity(IEnumerable< Entity > entities)