» ISynchronizable and IFlushable
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

ISynchronizable and IFlushable

ever wanted to write a sample and hold node as a plugin? well you couldn't, until now :)

the ISpread interface now implements two new interfaces, ISynchronizable and IFlushable.
ISynchronizable exposes the method Sync and IFlushable exposes the method Flush. what they do is simple:
calling the method Sync on a spread triggers the evaluation of the upstream pin and copies the raw pin data to the spread.
calling the method Flush on a spread will copy the data of the spread back to the pin.

by default those two methods will be called automatically by the plugin hosting code: Sync will be called before the Evaluate method of the plugin and Flush will be called after the call to Evaluate.
now the interesting part is that you can disable the implicit call to Sync and call it manually in your Evaluate method. this means that as long as you don't call Sync on your input spread all the nodes connected upstream of the corresponding pin are not evaluated. that's exactly the behaviour how the well known sample and hold node works.

you can disable the implicit call to Sync by setting the new property AutoValidate to false on your input attribute.

here's an example code how a sample and hold could look like:

[Input("Input", AutoValidate = false)]
ISpread<T> FInput;
[Input("Set")]
ISpread<bool> FSetIn;
[Output("Output")]
ISpread<T> FOutput;
...
public void Evaluate(int spreadMax) {
  if (FSetIn[0]) {
    FInput.Sync();
    FOutput.AssignFrom(FInput);
  }
}

the implicit call to Flush cannot be disabled. if someone comes up with a good use case it shouldn't be that hard to implement though.

ISynchronizable and IFlushable are implemented by all pin data accessor interfaces (spread, stream etc.) except for the raw V1 IPluginIO interfaces which expose a new method Validate which gets called by the Sync methods of the higher level accessor interfaces.
Elias, Wednesday, Jul 25th 2012 Digg | Tweet | Delicious 5 comments  
zeos 27/07/2012 - 03:11

That's great! Does it make sense, to also allow to overwrite the flush method, when there is a parallel task started inside the node (this nice .net 4 task/continueWith,...) and when the task is finished, loads the result into the output pin(should be locked in that moment or with continueWith you and up in the parent thread, so.. Or?) hm or there is better way (IStream...?)

Cheers

Elias 27/07/2012 - 12:20

calling Sync or Flush can lead to calls on COM interfaces, which will immediately throw an exception if called from another thread than the vvvv main thread.
as i explained in the blog post, Sync will definitely lead to a COM call, as it calls the Validate method on the underlying IPluginIO interface. so this is a no go.
on the other hand calling Flush from another thread could work depending on the used datatype, as for example the int/float/double/bool/vector/matrix stream implementations work directly on the unmanaged data pointer.
but in those cases the Flush is either a no op, if you work with IOutStream directly or when working with an IIOStream or an ISpread it leads to a very fast mem copy for the above mentioned data types, so i doubt that it would make much of a difference.

zeos 27/07/2012 - 17:36

Hi Elias!

Many thanks for your answer and for all this vvvvunderfull new stuff!!!

How do you recommend to use the new .net4 parallels library (http://msdn.microsoft.com/en-us/library/dd537609.aspx) inside vvvv dynamic plugin?

Let's say we have one node (plugin) that has an enable pin. When enabled is set to [1] it starts a TASK to read and process data from elsewhere, when the TASK is done it "load" the result into a FOutput pin via IOutStream? And the re-start the TASK from the beginning.

I want to use the new TASK library to do some things parallel and increase performance, also to make a "Task Template" that uses .NET4 Tasks and shared it, when I figure it out ;) I do not know the v4 internals and some directions will help a lot ;)

Many, many thanks!

Elias 28/07/2012 - 13:13

i guess you do not want to block the main thread as long as the task is running?
in that case use a ConcurrentQueue where you enqueue your results from your tasks and try to dequeue them from the main thread.

something like this should work...

private readonly ConcurrentQueue<T> FResultQueue = new ConcurrentQueue<T>();
...
public void Evaluate(int spreadMax) {
  if (FEnabled[0]) {
    Parallel.Invoke(() => FResultQueue.Enqueue(default(T));
  }
  T result;
  if (FResultQueue.TryDequeue(out result)) {
    FOutput[0] = result;
  }
}
zeos 01/08/2012 - 05:02

Thanks!!! I will experiment and report.

  • 1

anonymous user login

Shoutbox

~14d ago

~17d ago

joreg: The Winter Season of vvvv workshops is now over but all recordings are still available for purchase: https://thenodeinstitute.org/ws23-vvvv-intermediates/

~23d ago

schlonzo: Love the new drag and drop functionality for links in latest previews!

~1mth ago

joreg: Workshop on 29 02: Create Sequencers and Precise Clock Based Tools. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-08-create-sequencers-and-precise-clock-based-tools-in-vvvv-gamma/

~1mth ago

joreg: Workshop on 22 02: Unlocking Shader Artistry: A Journey through ‘The Book of Shaders’ with FUSE. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-12-book-of-shaders/

~2mth ago

joreg: Talk and Workshop on February 15 & 16 in Frankfurt: https://visualprogramming.net/blog/vvvv-at-node-code-frankfurt/

~2mth ago

woei: @Joanie_AntiVJ: think so, looks doable