Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
RemoveItemCommand.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 
5 using SiliconStudio.ActionStack;
6 using SiliconStudio.Core.Reflection;
7 using SiliconStudio.Quantum.Attributes;
8 
9 namespace SiliconStudio.Quantum.Commands
10 {
12  {
13  private struct UndoTokenData
14  {
15  private readonly object indexer;
16  private readonly object item;
17  public UndoTokenData(object indexer, object item)
18  {
19  this.indexer = indexer;
20  this.item = item;
21  }
22 
23  public object Indexer { get { return indexer; } }
24 
25  public object Item { get { return item; } }
26  }
27 
28  /// <inheritdoc/>
29  public string Name { get { return "RemoveItem"; } }
30 
31  /// <inheritdoc/>
32  public CombineMode CombineMode { get { return CombineMode.AlwaysCombine; } }
33 
34 
35  /// <inheritdoc/>
36  public bool CanAttach(ITypeDescriptor typeDescriptor, MemberDescriptorBase memberDescriptor)
37  {
38  if (memberDescriptor != null)
39  {
40  var attrib = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute<SealedCollectionAttribute>(memberDescriptor.MemberInfo);
41  if (attrib != null && attrib.CollectionSealed)
42  return false;
43  }
44 
45  var collectionDescriptor = typeDescriptor as CollectionDescriptor;
46  var dictionaryDescriptor = typeDescriptor as DictionaryDescriptor;
47  if (collectionDescriptor != null)
48  {
49  var elementType = collectionDescriptor.ElementType;
50  // We also add the same conditions that for AddNewItem
51  return collectionDescriptor.HasRemoveAt && (!elementType.IsClass || elementType.GetConstructor(Type.EmptyTypes) != null || elementType.IsAbstract || elementType.IsNullable() || elementType == typeof(string));
52  }
53  // TODO: add a HasRemove in the dictionary descriptor and test it!
54  return dictionaryDescriptor != null;
55  }
56 
57  /// <inheritdoc/>
58  public object Invoke(object currentValue, ITypeDescriptor descriptor, object parameter, out UndoToken undoToken)
59  {
60  var collectionDescriptor = descriptor as CollectionDescriptor;
61  var dictionaryDescriptor = descriptor as DictionaryDescriptor;
62  if (collectionDescriptor != null)
63  {
64  var position = (int)parameter;
65  var removedObject = collectionDescriptor.GetValue(currentValue, position);
66  undoToken = new UndoToken(true, new UndoTokenData(parameter, removedObject));
67  collectionDescriptor.RemoveAt(currentValue, position);
68  }
69  else if (dictionaryDescriptor != null)
70  {
71  var removedObject = dictionaryDescriptor.GetValue(currentValue, parameter);
72  undoToken = new UndoToken(true, new UndoTokenData(parameter, removedObject));
73  dictionaryDescriptor.Remove(currentValue, parameter);
74  }
75  else
76  throw new InvalidOperationException("This command cannot be executed on the given object.");
77 
78  return currentValue;
79  }
80 
81  /// <inheritdoc/>
82  public object Undo(object currentValue, ITypeDescriptor descriptor, UndoToken undoToken)
83  {
84  var collectionDescriptor = descriptor as CollectionDescriptor;
85  var dictionaryDescriptor = descriptor as DictionaryDescriptor;
86  var undoData = (UndoTokenData)undoToken.TokenValue;
87  if (collectionDescriptor != null)
88  {
89  var position = (int)undoData.Indexer;
90  if (collectionDescriptor.HasInsert)
91  collectionDescriptor.Insert(currentValue, position, undoData.Item);
92  else
93  collectionDescriptor.Add(currentValue, undoData.Item);
94  }
95  else if (dictionaryDescriptor != null)
96  {
97  if (dictionaryDescriptor.ContainsKey(currentValue, undoData.Indexer))
98  throw new InvalidOperationException("Unable to undo remove: the dictionary contains the key to re-add.");
99  dictionaryDescriptor.SetValue(currentValue, undoData.Indexer, undoData.Item);
100  }
101  return currentValue;
102  }
103  }
104 }
object Undo(object currentValue, ITypeDescriptor descriptor, UndoToken undoToken)
Undoes an invoke of the node command. The current value of the associated object or member...
Provides a descriptor for a System.Collections.ICollection.
Provides a descriptor for a System.Collections.IDictionary.
CombineMode
An enum that describes what to do with a node or a command when combining view models.
Definition: CombineMode.cs:8
bool CanAttach(ITypeDescriptor typeDescriptor, MemberDescriptorBase memberDescriptor)
Indicates whether this command can be attached to an object or a member with the given descriptors...
Base interface for node commands.
Definition: INodeCommand.cs:11
object Invoke(object currentValue, ITypeDescriptor descriptor, object parameter, out UndoToken undoToken)
Invokes the node command. The current value of the associated object or member.The type descriptor of...
Provides access members of a type.
object TokenValue
Gets a user-defined object hosted by the token that should store all information needed to undo a com...
Definition: UndoToken.cs:43
Base class for IMemberDescriptor for a MemberInfo
Represents a token that stores an unique identifier and an object. This token should be generated by ...
Definition: UndoToken.cs:12