Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ScriptSync.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Reflection;
6 using System.Runtime.CompilerServices;
7 
8 using Paradox;
9 using Paradox.Diffs;
10 using Paradox.Effects;
11 using Paradox.Engine;
12 using Paradox.EntityModel;
13 using Paradox.Framework;
14 using Paradox.Framework.Graphics;
15 using Paradox.Framework.Mathematics;
16 using Paradox.Framework.MicroThreading;
17 using Paradox.Framework.PropertyModel;
18 using Paradox.Framework.Serialization;
19 using Paradox.Framework.Serialization.Contents;
20 
21 using NGit;
22 using NGit.Api;
23 using NGit.Dircache;
24 using NGit.Merge;
25 using NGit.Revwalk;
26 using NGit.Revwalk.Filter;
27 using NGit.Storage.File;
28 using NGit.Treewalk;
29 using NGit.Treewalk.Filter;
30 
31 using Sharpen;
32 
34 
35 namespace ScriptTest
36 {
37  // Various scrips to test scene saving/loading and git merging.
38  [ParadoxScript]
39  public static class ScriptSync
40  {
41  private static MemoryStream memoryStream = new MemoryStream();
42  private static Serializer Serializer;
43 
44  static ScriptSync()
45  {
46  Serializer = Serializer.Default;
47  }
48 
49  public static List<EntityDefinition> LoadEntities(Stream stream)
50  {
51  List<EntityDefinition> entities = null;
52  var rw = new BinarySerializationReader(stream);
53  rw.Context.Serializer = Serializer;
54  rw.SerializeClass(null, ref entities, ArchiveMode.Deserialize);
55  return entities;
56  }
57 
58  [ParadoxScript]
59  public static void SaveAssets(EngineContext engineContext)
60  {
61  var entities = new List<EntityDefinition>();
62 
63  foreach (var entity in engineContext.EntityManager.Entities.OrderBy(x => x.Guid).Where(x => x.Name == "him"))
64  {
65  var entityDefinition = new EntityDefinition(entity.Guid);
66  entities.Add(entityDefinition);
67 
68  foreach (var entityComponent in entity.Properties.Where(x => x.Value is EntityComponent).OrderBy(x => x.Key.Name))
69  {
70  var componentDefinition = new EntityComponentDefinition { Name = entityComponent.Key.Name, Properties = new List<EntityComponentProperty>() };
71  entityDefinition.Components.Add(componentDefinition);
72 
73  var entityComponentValue = entityComponent.Value as EntityComponent;
74 
75  foreach (var field in entityComponentValue.GetType().GetFields())
76  {
77  if (field.GetCustomAttributes(typeof(VersionableAttribute), true).Length == 0)
78  continue;
79 
80  componentDefinition.Properties.Add(new EntityComponentProperty(EntityComponentPropertyType.Field, field.Name, Encode(field.GetValue(entityComponentValue))));
81  }
82 
83  foreach (var property in entityComponentValue.GetType().GetProperties())
84  {
85  if (property.GetCustomAttributes(typeof(VersionableAttribute), true).Length == 0)
86  continue;
87 
88  componentDefinition.Properties.Add(new EntityComponentProperty(EntityComponentPropertyType.Property, property.Name, Encode(property.GetValue(entityComponentValue, null))));
89  }
90 
91  componentDefinition.Properties = componentDefinition.Properties.OrderBy(x => x.Name).ToList();
92  }
93  }
94 
95  var fileStream = new FileStream(@"C:\DEV\hotei_scene\scene.hotei", FileMode.Create, FileAccess.Write);
96  var stream = new BinarySerializationWriter(fileStream);
97  stream.Context.Serializer = Serializer;
98  stream.SerializeClass(null, ref entities, ArchiveMode.Serialize);
99  fileStream.Close();
100  }
101 
102  class ParameterUrl
103  {
104  public string Url { get; set; }
105  }
106 
107  [ParadoxScript]
108  public static void MergeTest(EngineContext engineContext)
109  {
110  // TODO: Currently hardcoded
111  var db = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT));
112  var git = new Git(db);
113  var tree1Ref = db.GetRef("test");
114  var tree2Ref = db.GetRef(Constants.HEAD);
115  var tree1CommitId = tree1Ref.GetObjectId();
116  var tree2CommitId = tree2Ref.GetObjectId();
117 
118  // Merge tree1 into current tree
119  var mergeResult = git.Merge().Include(tree1CommitId).Call();
120 
121  if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING)
122  {
123  foreach (var conflict in mergeResult.GetConflicts())
124  {
125  if (conflict.Key.EndsWith(".hotei"))
126  {
127  // Search base tree (common ancestor), if any
128  var walk = new RevWalk(db);
129  walk.SetRevFilter(RevFilter.MERGE_BASE);
130  walk.MarkStart(walk.ParseCommit(tree1CommitId));
131  walk.MarkStart(walk.ParseCommit(tree2CommitId));
132  var baseTree = walk.Next();
133 
134  var tw = new NameConflictTreeWalk(db);
135  tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId());
136  tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId());
137  if (baseTree != null)
138  tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId());
139  tw.Filter = PathFilter.Create(conflict.Key);
140 
141  // Should be only one iteration
142  while (tw.Next())
143  {
144  var tree0 = baseTree != null ? tw.GetTree<AbstractTreeIterator>(2) : null;
145  var tree1 = tw.GetTree<AbstractTreeIterator>(0);
146  var tree2 = tw.GetTree<AbstractTreeIterator>(1);
147 
148  // Get contents of every versions for the 3-way merge
149  var data0 = baseTree != null ? LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null;
150  var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes()));
151  var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes()));
152 
153  // Perform 3-way merge
154  var entities = new List<EntityDefinition>();
155  ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts);
156 
157  // Save new merged file
158  var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write);
159  var stream = new BinarySerializationWriter(fileStream);
160  stream.Context.Serializer = Serializer;
161  stream.SerializeClass(null, ref entities, ArchiveMode.Serialize);
162  fileStream.Close();
163 
164  // TODO: Check if all conflicts are really resolved
165  // Add resolved file for merge commit
166  git.Add().AddFilepattern(conflict.Key).Call();
167  }
168  }
169  }
170  }
171  }
172 
173  // Resolve conflicts for an entity
174  public static void ResolveEntityConflicts(ThreeWayConflictType conflictType, IList<EntityDefinition>[] lists, int[] indices, IList<EntityDefinition> result)
175  {
176  switch (conflictType)
177  {
178  case ThreeWayConflictType.Modified1And2:
179  var entityDefinition = new EntityDefinition(lists[0][indices[0]].Guid);
180  ThreeWayMergeOrdered.Merge(entityDefinition.Components, lists[0][indices[0]].Components, lists[1][indices[1]].Components, lists[2][indices[2]].Components, x => x.Name, (x, y) => x == y, ResolveComponentConflicts);
181  result.Add(entityDefinition);
182  break;
183  default:
184  throw new NotImplementedException();
185  }
186  }
187 
188  // Resolve conflicts for a component
189  public static void ResolveComponentConflicts(ThreeWayConflictType conflictType, IList<EntityComponentDefinition>[] lists, int[] indices, IList<EntityComponentDefinition> result)
190  {
191  switch (conflictType)
192  {
193  case ThreeWayConflictType.Modified1And2:
194  var componentDefinition = new EntityComponentDefinition { Name = lists[0][indices[0]].Name, Properties = new List<EntityComponentProperty>() };
195  ThreeWayMergeOrdered.Merge(componentDefinition.Properties, lists[0][indices[0]].Properties, lists[1][indices[1]].Properties, lists[2][indices[2]].Properties, x => x.Name, (x, y) => x == y, ResolvePropertyConflicts);
196  result.Add(componentDefinition);
197  break;
198  default:
199  throw new NotImplementedException();
200  }
201  }
202 
203  // Resolve conflicts for a property
204  public static void ResolvePropertyConflicts(ThreeWayConflictType conflictType, IList<EntityComponentProperty>[] lists, int[] indices, IList<EntityComponentProperty> result)
205  {
206  switch (conflictType)
207  {
208  case ThreeWayConflictType.Modified1And2:
209  result.Add(lists[1][indices[1]]);
210  break;
211  default:
212  throw new NotImplementedException();
213  }
214  }
215  [ParadoxScript]
216  public static void LoadAssets(EngineContext engineContext)
217  {
218  var fileStream = new FileStream(@"C:\DEV\hotei_scene\scene.hotei", FileMode.Open, FileAccess.Read);
219  var entities = LoadEntities(fileStream);
220  fileStream.Close();
221 
222  foreach (var entityDefinition in entities)
223  {
224  var entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entityDefinition.Guid);
225  if (entity == null)
226  {
227  entity = new Entity(entityDefinition.Guid);
228  engineContext.EntityManager.AddEntity(entity);
229  }
230 
231  foreach (var componentDefinition in entityDefinition.Components)
232  {
233  EntityComponent component = null;
234  if (componentDefinition.Name == "TransformationComponent")
235  {
236  component = entity.Get(TransformationComponent.Key);
237  if (component == null)
238  {
239  component = new TransformationTRSComponent();
240  entity.Set(TransformationComponent.Key, (TransformationComponent)component);
241  }
242  }
243  else
244  {
245  continue;
246  }
247 
248  foreach (var componentProperty in componentDefinition.Properties)
249  {
250  switch (componentProperty.Type)
251  {
252  case EntityComponentPropertyType.Field:
253  var field = component.GetType().GetField(componentProperty.Name);
254  field.SetValue(component, Decode(componentProperty.Data));
255  break;
256  case EntityComponentPropertyType.Property:
257  var property = component.GetType().GetProperty(componentProperty.Name);
258  property.SetValue(component, Decode(componentProperty.Data), null);
259  break;
260  default:
261  throw new NotImplementedException();
262  }
263  }
264  }
265  }
266  }
267 
268  private static object LoadAssetFromUrl(ContentManager contentManager, string url)
269  {
270  throw new NotImplementedException();
271  }
272 
273  private static byte[] Encode(object obj, Serializer serializer = null)
274  {
275  var result = new MemoryStream();
276  var stream = new BinarySerializationWriter(result);
277  if (serializer != null)
278  stream.Context.Serializer = serializer;
279  stream.SerializeExtended(null, ref obj, ArchiveMode.Serialize);
280 
281  return result.ToArray();
282  }
283 
284  private static object Decode(byte[] data, Serializer serializer = null)
285  {
286  object result = null;
287  var stream = new BinarySerializationReader(new MemoryStream(data));
288  if (serializer != null)
289  stream.Context.Serializer = serializer;
290  stream.SerializeExtended(null, ref result, ArchiveMode.Deserialize);
291 
292  return result;
293  }
294  }
295 }
static void ResolvePropertyConflicts(ThreeWayConflictType conflictType, IList< EntityComponentProperty >[] lists, int[] indices, IList< EntityComponentProperty > result)
Definition: ScriptSync.cs:204
static void ResolveEntityConflicts(ThreeWayConflictType conflictType, IList< EntityDefinition >[] lists, int[] indices, IList< EntityDefinition > result)
Definition: ScriptSync.cs:174
System.IO.FileMode FileMode
Definition: ScriptSync.cs:33
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
Definition: DirectXTexP.h:191
global::MonoTouch.Constants Constants
Definition: TouchRunner.cs:42
System.IO.File File
static void LoadAssets(EngineContext engineContext)
Definition: ScriptSync.cs:216
static void ResolveComponentConflicts(ThreeWayConflictType conflictType, IList< EntityComponentDefinition >[] lists, int[] indices, IList< EntityComponentDefinition > result)
Definition: ScriptSync.cs:189
static void SaveAssets(EngineContext engineContext)
Definition: ScriptSync.cs:59
static void MergeTest(EngineContext engineContext)
Definition: ScriptSync.cs:108
static List< EntityDefinition > LoadEntities(Stream stream)
Definition: ScriptSync.cs:49