gflow-simple-source.vala 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /********************************************************************
  2. # Copyright 2014-2022 Daniel 'grindhold' Brendle, 2015 Daniel Espinosa <esodan@gmail.com>
  3. #
  4. # This file is part of libgtkflow.
  5. #
  6. # libgtkflow is free software: you can redistribute it and/or
  7. # modify it under the terms of the GNU Lesser General Public License
  8. # as published by the Free Software Foundation, either
  9. # version 3 of the License, or (at your option) any later
  10. # version.
  11. #
  12. # libgtkflow is distributed in the hope that it will be
  13. # useful, but WITHOUT ANY WARRANTY; without even the implied
  14. # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. # PURPOSE. See the GNU Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with libgtkflow.
  19. # If not, see http://www.gnu.org/licenses/.
  20. *********************************************************************/
  21. namespace GFlow {
  22. /**
  23. * A simple implementation of {@link GFlow.Source}.
  24. */
  25. public class SimpleSource : Object, Dock, Source {
  26. // Dock interface
  27. protected GLib.Type _type;
  28. protected bool _valid = false;
  29. private GLib.Value? last_value = null;
  30. private string? _name = null;
  31. /**
  32. * This SimpleSource's displayname
  33. */
  34. public string? name {
  35. get { return this._name; }
  36. set { this._name = value; }
  37. }
  38. /**
  39. * This SimpleSource's typestring
  40. */
  41. public string? _typename = null;
  42. public string? typename {
  43. get { return this._typename; }
  44. set { this._typename = value; }
  45. }
  46. /**
  47. * Indicates whether this Source should be rendered highlighted
  48. */
  49. public bool highlight { get; set; }
  50. /**
  51. * Indicates whether this Source should be rendered active
  52. */
  53. public bool active {get; set; default=false;}
  54. /**
  55. * A reference to the {@link Node} that this SimpleSource resides in
  56. */
  57. public weak Node? node { get; set; }
  58. /**
  59. * Creates a new SimpleSource. Supply an arbitrary {@link GLib.Value}. This
  60. * initial value's type will determine this SimpleSource's type.
  61. */
  62. public SimpleSource(GLib.Value value) {
  63. _type = value.type ();
  64. last_value = value;
  65. }
  66. /**
  67. * Creates a new SimpleSource with given type {@link GLib.Type}
  68. */
  69. public SimpleSource.with_type(GLib.Type type) {
  70. _type = type;
  71. }
  72. /**
  73. * The value that this SimpleSource was initialized with
  74. */
  75. public GLib.Type value_type { get { return _type; } }
  76. // Source interface
  77. private List<Sink> _sinks = new List<Sink> ();
  78. /**
  79. * The {@link Sink}s that this SimpleSource is connected to
  80. */
  81. public List<Sink> sinks { get { return _sinks; } }
  82. /**
  83. * Connects this SimpleSource to the given {@link Sink}. This will
  84. * only succeed if both {@link Dock}s are of the same type. If this
  85. * is not the case, an exception will be thrown
  86. */
  87. protected void add_sink (Sink s) throws Error
  88. {
  89. if (this.value_type != s.value_type) {
  90. throw new NodeError.INCOMPATIBLE_SINKTYPE(
  91. "Can't connect. Sink has type %s while Source has type %s".printf(
  92. s.value_type.name(), this.value_type.name()
  93. )
  94. );
  95. }
  96. this._sinks.append (s);
  97. }
  98. /**
  99. * Destroys the connection between this SimpleSource and the given {@link Sink}
  100. */
  101. protected void remove_sink (Sink s) throws GLib.Error
  102. {
  103. if (this._sinks.index(s) != -1)
  104. this._sinks.remove(s);
  105. if (s.is_linked_to(this)) {
  106. s.unlink (this);
  107. this.unlinked(s, this._sinks.length () == 0);
  108. }
  109. }
  110. /**
  111. * Returns true if this Source is connected to the given Sink
  112. */
  113. public bool is_linked_to (Dock dock) {
  114. if (!(dock is Sink)) return false;
  115. return this._sinks.index((Sink) dock) != -1;
  116. }
  117. /**
  118. * Returns true if this Source is connected to one or more Sinks
  119. */
  120. public bool is_linked () {
  121. return this.sinks.length () > 0;
  122. }
  123. /**
  124. * Disconnect from the given {@link Dock}
  125. */
  126. public new void unlink (Dock dock) throws GLib.Error
  127. {
  128. if (!this.is_linked_to (dock)) return;
  129. if (dock is Sink) {
  130. remove_sink ((Sink) dock);
  131. }
  132. }
  133. /**
  134. * Connect to the given {@link Dock}
  135. */
  136. public new void link (Dock dock) throws GLib.Error
  137. {
  138. if (!this.before_linking(this, dock)) return;
  139. if (dock is Sink) {
  140. if (this.is_linked_to (dock)) return;
  141. add_sink ((Sink) dock);
  142. dock.link (this);
  143. linked (dock);
  144. }
  145. }
  146. /**
  147. * Disconnect from any {@link Dock} that this SimplesSource is connected to
  148. */
  149. public new void unlink_all () throws GLib.Error {
  150. foreach (Sink s in this._sinks.copy())
  151. if (s != null)
  152. this.unlink(s);
  153. }
  154. /**
  155. * Set the value of this SimpleSource
  156. */
  157. public void set_value (GLib.Value? v, string? flow_id = null) throws GLib.Error
  158. {
  159. if (v != null && this.value_type != v.type())
  160. throw new NodeError.INCOMPATIBLE_VALUE(
  161. "Cannot set a %s value to this %s Source".printf(
  162. v.type().name(), this.value_type.name())
  163. );
  164. this.last_value = v;
  165. this.changed(v, flow_id);
  166. }
  167. /**
  168. * {@inheritDoc}
  169. */
  170. public new GLib.Value? get_last_value() {
  171. return this.last_value;
  172. }
  173. }
  174. }