Skip to content

Commit

Permalink
Merge 88f9878 into 3d07924
Browse files Browse the repository at this point in the history
  • Loading branch information
jonmmease committed Aug 15, 2020
2 parents 3d07924 + 88f9878 commit 33316cb
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
35 changes: 35 additions & 0 deletions holoviews/streams.py
Expand Up @@ -855,6 +855,41 @@ def __del__(self):
self._unregister_input_streams()


class History(Stream):
"""
A Stream that maintains a history of the values of a single input stream
"""
values = param.List(constant=True, doc="""
List containing the historical values of the input stream""")

def __init__(self, input_stream, **params):
super(History, self).__init__(**params)
self.input_stream = input_stream
self._register_input_stream()
# Trigger event on input stream after registering so that current value is
# added to our values list
self.input_stream.event()

def clear_history(self):
self.values.clear()
self.event()

def _register_input_stream(self):
"""
Register callback on input_stream to watch for changes
"""
def perform_update(**kwargs):
self.values.append(kwargs)
self.event()

self.input_stream.add_subscriber(perform_update)

def __del__(self):
self.input_stream.source = None
self.input_stream.clear()
self.values.clear()


class SelectionExpr(Derived):
selection_expr = param.Parameter(default=None, constant=True)

Expand Down
66 changes: 66 additions & 0 deletions holoviews/tests/teststreams.py
Expand Up @@ -974,6 +974,72 @@ def test_exclusive_derived_stream(self):
self.assertEqual(s0.v, -8.0)


class TestHistoryStream(ComparisonTestCase):
def test_initial_history_stream_values(self):
# Check values list is initialized with initial contents of input stream
val = Val(v=1.0)
history = History(val)
self.assertEqual(history.contents, {"values": [val.contents]})

def test_history_stream_values_appended(self):
val = Val(v=1.0)
history = History(val)
# Perform a few updates on val stream
val.event(v=2.0)
val.event(v=3.0)
self.assertEqual(
history.contents,
{"values": [{"v": 1.0}, {"v": 2.0}, {"v": 3.0}]}
)

# clear
history.clear_history()
self.assertEqual(history.contents, {"values": []})

def test_history_stream_trigger_callbacks(self):
# Construct history stream
val = Val(v=1.0)
history = History(val)

# Register callback
callback_input = []
def cb(**kwargs):
callback_input.append(kwargs)
history.add_subscriber(cb)
self.assertEqual(callback_input, [])

# Perform updates on val stream and make sure history callback is triggered
callback_input.clear()
val.event(v=2.0)
self.assertEqual(
callback_input[0],
{"values": [{"v": 1.0}, {"v": 2.0}]}
)

callback_input.clear()
val.event(v=3.0)
self.assertEqual(
callback_input[0],
{"values": [{"v": 1.0}, {"v": 2.0}, {"v": 3.0}]}
)

# clearing history should trigger callback
callback_input.clear()
history.clear_history()
self.assertEqual(
callback_input[0],
{"values": []}
)

# Update after clearing
callback_input.clear()
val.event(v=4.0)
self.assertEqual(
callback_input[0],
{"values": [{"v": 4.0}]}
)


class TestExprSelectionStream(ComparisonTestCase):

def setUp(self):
Expand Down

0 comments on commit 33316cb

Please sign in to comment.