@@ -6,32 +6,82 @@ import reactify.standard.StandardReactions
66import scala .annotation .tailrec
77import scala .concurrent .{Future , Promise }
88
9+ /**
10+ * Reactive is the core trait for Reactify. The basic premise is that a Reactive represents an instance that can attach
11+ * Reactions and fire instances of `T` that are received by those Reactions.
12+ *
13+ * @tparam T the type of value this Reactive receives
14+ */
915trait Reactive [T ] {
16+ /**
17+ * An optional name associated. This is primarily used for distinguishing between instances as well as logging.
18+ */
1019 def name : Option [String ]
20+
1121 private lazy val _status = new ThreadLocal [Option [ReactionStatus ]]
1222
23+ /**
24+ * If the current thread is reacting to a value currently, status represents the status of the reaction. This can be
25+ * set to ReactionStatus.Stop in order to stop propagation. This can also be achieved via stopPropagation().
26+ */
1327 def status : Option [ReactionStatus ] = _status.get()
1428 def status_= (status : ReactionStatus ): Unit = {
1529 assert(_status.get().nonEmpty, " Cannot set the status without an active reaction on this thread" )
1630 _status.set(Some (status))
1731 }
1832
33+ /**
34+ * Shortcut functionality to call `status = ReactionStatus.Stop`
35+ */
1936 def stopPropagation (): Unit = status = ReactionStatus .Stop
2037
38+ /**
39+ * Reactions currently associated with this Reactive
40+ */
2141 lazy val reactions : Reactions [T ] = new StandardReactions [T ]
2242
43+ /**
44+ * Convenience method to create a Reaction to attach to this Reactive
45+ *
46+ * @param f the function reaction
47+ * @param priority the priority in comparison to other reactions (Defaults to Priority.Normal)
48+ * @return created Reaction[T]
49+ */
2350 def attach (f : T => Unit , priority : Double = Priority .Normal ): Reaction [T ] = {
2451 reactions += Reaction [T ](f, priority)
2552 }
2653
54+ /**
55+ * Convenience method to create a Reaction to monitor changes to this Reactive
56+ *
57+ * @param f the function reaction to receive changes
58+ * @param priority the priority in comparison to other reactions (Defaults to Priority.Normal)
59+ * @return created Reaction[T]
60+ */
2761 def changes (f : (T , T ) => Unit , priority : Double = Priority .Normal ): Reaction [T ] = {
2862 reactions += Reaction .changes[T ](f, priority)
2963 }
3064
65+ /**
66+ * Convenience method to create a Reaction to monitor changes to this Reactive when you don't care about the actual
67+ * value.
68+ *
69+ * @param f the function reaction to invoke in reaction to a value received
70+ * @param priority the priority in comparison to other reactions (Defaults to Priority.Normal)
71+ * @return created Reaction[T]
72+ */
3173 def on (f : => Unit , priority : Double = Priority .Normal ): Reaction [T ] = {
3274 attach(_ => f, priority)
3375 }
3476
77+ /**
78+ * Convenience method to create a Reaction to monitor a single reaction based on an optional condition.
79+ *
80+ * @param f the function reaction
81+ * @param condition optional condition that must be true for this to fire (Defaults to accept anything)
82+ * @param priority the priority in comparison to other reactions (Defaults to Priority.Normal)
83+ * @return created Reaction[T]
84+ */
3585 def once (f : T => Unit , condition : T => Boolean = _ => true , priority : Double = Priority .Normal ): Reaction [T ] = {
3686 var reaction : Reaction [T ] = null
3787 val function = (t : T ) => if (condition(t)) {
@@ -43,12 +93,22 @@ trait Reactive[T] {
4393 reaction
4494 }
4595
96+ /**
97+ * Convenience method to create a `Future[T]` that will complete upon the next reaction that meets to supplied
98+ * condition.
99+ *
100+ * @param condition optional condition that must be true for this to fire (Defaults to accept anything)
101+ * @return Future[T]
102+ */
46103 def future (condition : T => Boolean = _ => true ): Future [T ] = {
47104 val promise = Promise [T ]
48105 once(promise.success, condition)
49106 promise.future
50107 }
51108
109+ /**
110+ * Fires the value to the Reactions
111+ */
52112 protected def fire (value : T , previous : Option [T ], reactions : List [Reaction [T ]] = this .reactions()): ReactionStatus = {
53113 _status.set(Some (ReactionStatus .Continue ))
54114 try {
@@ -77,7 +137,7 @@ trait Reactive[T] {
77137}
78138
79139object Reactive {
80- def fire [T ](reactive : Reactive [T ], value : T , previous : Option [T ]): Unit = {
140+ private [reactify] def fire [T ](reactive : Reactive [T ], value : T , previous : Option [T ]): Unit = {
81141 reactive.fire(value, previous, reactive.reactions())
82142 }
83143}
0 commit comments