/common/src/core/Core/Model/IDItem.cs

https://github.com/woeishi/vvvv-sdk
C# | 248 lines | 197 code | 41 blank | 10 comment | 36 complexity | d8ba870d1ca948102ccccfca62d3776e MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using VVVV.Utils;
  6. namespace VVVV.Core.Model
  7. {
  8. public class IDItem : IIDItem, IDisposable
  9. {
  10. public IDItem(string name, bool isRooted = false)
  11. {
  12. FName = name;
  13. IsRooted = isRooted;
  14. Changed = true;
  15. }
  16. #region IIDItem Members
  17. public bool Changed { get; private set; }
  18. public virtual void MarkChanged()
  19. {
  20. if (!Changed)
  21. {
  22. Changed = true;
  23. if (Owner != null)
  24. Owner.MarkChanged();
  25. }
  26. }
  27. public virtual void AcknowledgeChanges()
  28. {
  29. Changed = false;
  30. }
  31. public ModelMapper Mapper
  32. {
  33. get;
  34. protected set;
  35. }
  36. private IIDContainer FOwner;
  37. public virtual IIDContainer Owner
  38. {
  39. get
  40. {
  41. return FOwner;
  42. }
  43. set
  44. {
  45. if (FOwner != null)
  46. {
  47. if (value != null)
  48. {
  49. throw new Exception(string.Format("ID item {0} ('{1}') has parent already.", this, Name));
  50. }
  51. // Unsubscribe from old owner
  52. FOwner.RootingChanged -= FOwner_RootingChanged;
  53. CheckIfRootingChanged(new RootingChangedEventArgs(RootingAction.ToBeUnrooted));
  54. }
  55. FOwner = value;
  56. if (FOwner != null)
  57. {
  58. // Subscribe to new owner
  59. FOwner.RootingChanged += FOwner_RootingChanged;
  60. CheckIfRootingChanged(new RootingChangedEventArgs(RootingAction.Rooted));
  61. }
  62. }
  63. }
  64. public bool IsRooted
  65. {
  66. get;
  67. private set;
  68. }
  69. public event RenamedHandler Renamed;
  70. public event RootingChangedEventHandler RootingChanged;
  71. public virtual void Dispatch(IVisitor visitor)
  72. {
  73. visitor.Visit(this);
  74. }
  75. private void CheckIfRootingChanged(RootingChangedEventArgs args)
  76. {
  77. switch (args.Rooting)
  78. {
  79. case RootingAction.Rooted:
  80. if (FOwner.IsRooted && !IsRooted)
  81. {
  82. IsRooted = true;
  83. OnRootingChanged(args);
  84. }
  85. break;
  86. case RootingAction.ToBeUnrooted:
  87. if (FOwner.IsRooted && IsRooted)
  88. {
  89. OnRootingChanged(args);
  90. IsRooted = false;
  91. }
  92. break;
  93. }
  94. }
  95. private void OnRootingChanged(RootingChangedEventArgs args)
  96. {
  97. if (args.Rooting == RootingAction.Rooted)
  98. {
  99. Mapper = FOwner.Mapper.CreateChildMapper(this);
  100. OnRootingChanged(RootingAction.Rooted);
  101. }
  102. if (RootingChanged != null)
  103. {
  104. RootingChanged(this, args);
  105. }
  106. if (args.Rooting == RootingAction.ToBeUnrooted)
  107. {
  108. OnRootingChanged(RootingAction.ToBeUnrooted);
  109. Mapper.Dispose();
  110. Mapper = null;
  111. }
  112. }
  113. protected virtual void OnRootingChanged(RootingAction rooting)
  114. {
  115. }
  116. void FOwner_RootingChanged(object sender, RootingChangedEventArgs args)
  117. {
  118. // Propagate the event down further in the object graph
  119. CheckIfRootingChanged(args);
  120. }
  121. #endregion
  122. #region INamed Members
  123. protected virtual void OnRenamed(string newName)
  124. {
  125. if (Renamed != null)
  126. Renamed(this, newName);
  127. }
  128. protected string FName;
  129. public virtual string Name
  130. {
  131. get
  132. {
  133. return FName;
  134. }
  135. set
  136. {
  137. if (value != FName) //(CanRenameTo(value) && (value != FName))
  138. {
  139. OnRenamed(value);
  140. FName = value;
  141. }
  142. }
  143. }
  144. protected virtual bool IsRenameable()
  145. {
  146. return this is IRenameable;
  147. }
  148. #endregion
  149. #region IRenameable Members
  150. public virtual bool CanRenameTo(string value)
  151. {
  152. // let's return false if not IsRenamable (even if new name == old name)
  153. // the action itself is forbidden for not IsRenamble
  154. return (IsRenameable() && ((value == Name) || (Owner == null) || (Owner[value] == null)));
  155. }
  156. #endregion
  157. #region IDisposable
  158. // Use C# destructor syntax for finalization code.
  159. ~IDItem()
  160. {
  161. // Simply call Dispose(false).
  162. Dispose(false);
  163. }
  164. public bool IsDisposed
  165. {
  166. get;
  167. private set;
  168. }
  169. public void Dispose()
  170. {
  171. Dispose(true);
  172. GC.SuppressFinalize(this);
  173. }
  174. protected void Dispose(bool disposing)
  175. {
  176. if (!IsDisposed)
  177. {
  178. if (disposing)
  179. {
  180. // Free other state (managed objects).
  181. DisposeManaged();
  182. }
  183. // Free your own state (unmanaged objects).
  184. // Set large fields to null.
  185. DisposeUnmanaged();
  186. }
  187. IsDisposed = true;
  188. }
  189. protected virtual void DisposeManaged()
  190. {
  191. if (Mapper != null)
  192. Mapper.Dispose();
  193. if (FOwner != null)
  194. {
  195. FOwner.RootingChanged -= FOwner_RootingChanged;
  196. }
  197. }
  198. protected virtual void DisposeUnmanaged()
  199. {
  200. }
  201. #endregion
  202. public override string ToString()
  203. {
  204. return string.Format("{0}: {1}", Name, this.GetType().Name);
  205. }
  206. }
  207. }