» it.Guida ai Plugin Dinamici
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

it.Guida ai Plugin Dinamici

English | French

The original english version of this page is newer and may contain information this translation does not have! Click here to view the english version.

PluginInfo

[PluginInfo(Name = "Template",
            Category = "Value",
            Help = "A Template",
            Tags = "simple, basic",
            Author = "vvvv group",
            AutoEvaluate = false)]
L'attributo PluginInfo, scritto sopra la classe-plugin, viene usato per descrivere un plugin a vvvv.

All'interno delle parentesi curve, (), c'è una lista separata da virgole di coppie Nome=Valore (Name=Value). Solo Name e Category sono obbligatorie: tutte le altrre sono opzionali.

Consultate la lista di tutte le proprietà di PluginInfo, in inglese

Per quanto riguarda l'impostazione AutoEvaluate consultate la sezione Evaluate() più in basso.

Definire i Pin

[Config("My Config Value")]
public ISpread<double> FConfig;
 
[Input("My Input String")]
public ISpread<string> FInput;
 
[Output("My Output Color")]
public ISpread<RGBAColor> FOutput;
Esempi di Attributo
//specificare un valore
//di default per un pin
[Input("Input", DefaultValue = 255.0)]
 
//specificare un pin non spread.
//Il pin ha solo una slice
//e l'utente non può modificare
//questa impostazione. 
[.., IsSingle = true)]
 
//specificare la visibilità di un pin. 
[.., Visibility = PinVisibility.Hidden)]
 
//specificare come il pin debba
//essere del tipo ''filename'' 
//per aprire una finestra di dialogo
//con il click destro.
[.., StringType = StringType.Filename)]
Esempio IDiffSpread
[Input("Write", IsBang=true)]
IDiffSpread<bool> FDoWrite;
...
if (FDoWrite.IsChanged)
...
Esempio di Spread di Spread
//crea uno spread di due dimensioni
//che genera in vvvv un pin dati 
//ed un pin ((it.binsize|BinSize)).
[..]
ISpread<ISpread<double>> FInput;
Esempio di PinGroup
//Crea un PinGroup dinamico, in cui 
//l'utente può specificare
//la quantità dei pin 
//attraverso l'Ispettore (Inspektor). 
[.., IsPinGroup = true)]
ISpread<ISpread<double>> FInput;
Un pin viene definito con due righe di codice:

  • un attributo PinInfo (Config, Input o Output)
  • la dichiarazione di una variabile
L'attributo PinInfo

L'attributo PinInfo viene usato per descrivere un pin a vvvv. L'attributo precede immediatamente la dichiarazione di una variabile di input o output.

All'interno delle parentesi tonde, (), dell'istruzione della variabile, il primo argomento è obbligatorio e specifica il nome del pin. Può seguire, in quanto opzionale, una lista di coppie Name=Value che consente di descrivere un sotto tipo del valore del pin impostando Default-, Min-, MaxValue (ed altro ancora).

Consultate la lista delle proprietà di PinInfo, in inglese.

Dichiarazione di una variabile

Nella maggior parte dei casi vorrete dichiarare i vostri input ed output del tipo generico Ispread<T>, dove per T si intende:

float, double, bool, int, ..
pin value
string
pin stringa
RGBAColor
pin colore

Se volete sapere se un input sia cambiato, usate allora IDiffSpread<T> invece che ISpread<T> nella dichiarazione e richiamate .IsChanged nel vostro codice.

Spread di Spread

Se si dichiara una variabile come ISpread<ISpread<T>>, accanto al pin che contiene i dati si genererà un pin BinSize che vi consentirà di specificare come i dati siano strutturati in bin. Se invece questo pin è un PinGroup, si creerà un pin di configurazione visibile solo nell'Ispettore - vedi esempio a sinistra.

Aggiungere\Rimuovere pin

Ci sono due modi per fare questo in runtime:

  • semplice => usate un PinGroup: funzionerà solo in combinazione con ISpread<Ispread<T>> con qualsiasi T - vedi a sinistra.
  • flessibile: consultate il codice del nodo Template (Value DynamicPins).
Callback delle Connessioni

Nell'improbabile caso che dobbiate sapere quando un pin si connette\disconnette usate Pin<T> invece che ISpread<T> - consultate - Pin(T) Events, in inglese.

Evaluate

public void Evaluate(int SpreadMax)
{ 
  FOutput.SliceCount = SpreadMax;
 
  for (int i = 0; i < SpreadMax; i++)
    FOutput[i] = FInput[i] * 2;
}
Questo è il cuore del vostro plugin. La funzione Evaluate() viene eseguita ogni frame se:

  • qualcosa è collegato a valle

oppure se

  • è stato impostato AutoEvaluate = true (vedi PluginInfo più in alto)

Qui viene effettuato il calcolo principale del vostro plugin. Per inizializzare alcune parti del codice (es. per eseguirle una volta sola), vedere la sezione successiva (Constructor).

Come parametro di input la funzione fornisce lo "SpreadMax", che è lo SliceCount massimo di tutti gli spread collegati a tutti i pin di input del plugin. In genere si usa per impostare lo slicecount del pin di output - vedi a sinistra.

Nota bene: se uno dei pin di input è un ISpread <ISpread <... >>, dovrete valutare calcolare voi stessi SpreadMax, come nell'esempio qui sotto. In questo modo uno spread 2d contribuirà a SpreadMax solo con il "bin count" - che è poi il risultato che si cerca, in genere.

SpreadMax = SpreadUtils.SpreadMax(FInput1, FInput2 /* riportare TUTTI gli input*/);

Constructor: Inizializzare le cose - o le robe.

public MyNodeClassname()
{ 
  //inizializza qui
}
public class MyNodeClassname: 
IPluginEvaluate, 
IPartImportsSatisfiedNotification
{
...
 
public void OnImportsSatisfied()
{
  //accedi qui agli in\output
}
Userete un constructor se alcune parti del vostro codice devono essere eseguite una sola volta. Tenete presente che un constructor è opzionale e perciò la maggior parte dei Template non ne contiene un esempio.

Se vorrete accedere alle variabili che avete definito come in\output dovrete implementare IPartImportsSatisfiedNotification come mostrato nell'esempio a sinistra. Per un esempio consultate il codice di Template (Raw).

Destructor: Disfarsi delle cose - o delle robe

public class MyNodeClassname: 
IPluginEvaluate, 
IDisposable
{
...
//richiamato quando si
//elimina il plugin
public void Dispose()
{
  //unsubscribe eventi
  //richiama dispose per le
  //risorse create dal plugin 
}
Se il plugin usa risorse che devono essere rilasciate quando il plugin viene eliminato, dovete implementare l'interfaccia IDisposable. All'interno del metodo Dispose potrete fare tutte le operazioni necessarie.

Accesso alla struttura interna: HDEHost

[Import()]
public IPluginHost2 FPluginHost;
 
[Import()]
public IHDEHost FHDEHost;
Ci sono due punti d'ingresso alla struttura interna di vvvv:

  • per impostare\ottenere informazioni sul plugin a cui state lavorando, consultate: IPluginHost2, in inglese
  • per accedere a tutto vvvv consultate IHDEHost, in inglese

Project Explorer

Premete CTRL + J per aprire la finestra di Project Explorer: qui potrete aggiungere\rimuovere documenti o riferimenti ai\dai progetti.

Documenti

Anche se è possibile definire più classi del plugin all'interno di un documento, in presenza di un'ampia serie di nodi, potrebbe essebe utile dividerli in più documenti. Fate click destro sul progetto e scegliete Add... per aggiungere un documento nuovo o già esistente.

References

Di norma farete riferimenti a:

  • librerie presenti nel GAC
  • o a librerie di terze parti (per esempio, il driver di un dispositivo)

Usings

using System;
..
using VVVV.PluginInterfaces.V2;
Tutte le entità in .NET possono essere raggiunte da un percorse globale, una combinazione dello spazio dei nomi in cui l'entità è definita ed il nome dell'entità stessa: Per esempio VVVV.PluginInterfaces.V2.ISpread<bool> è il percorso completo per il tipo ISpread<bool> che è definito nello spazio del nome VVVV.PluginInterfaces.V2.

Le istruzioni using esistono per abbreviare il codice potendo scrivere solo ISpread<bool>. Per fare questo è necessario usare lo spazio dei nomi (VVVV.PluginInterfaces.V2) una volta all'inizio del codice.

Debugging

[Import()]
public ILogger Flogger;
...
 
Flogger.Log(LogType.Debug, "foo");
Il modo più semplice per il debug del codice è scrivere messaggi-log che è possibile visualizzare con il nodo  Renderer (TTY). Si importa ILogger e si richiama .Log () - vedi a sinistra.

Breakpoint !!!!
Se si desidera impostare punti di interruzione, breakpoint, e passare al setaccio il codice riga per riga, avrete bisogno di un IDE come SharpDevelop o VisualStudio e fare quanto segue:

  • caricate il .csproj del plugin
  • impostate un punto di interruzione nel codice
  • collegate l'IDE per l'istanza in esecuzione di vvvv.

Ora, quando si incontra un punto di interruzione, l'IDE ferma vvvv e si potrà controllare il codice.

Ulteriori interfacce opzionali da implementare

  • IBackgroundColor consente ad un plugin GUI di specificare il colore di sfondo per la finestra che lo ospita (nella maggior parte dei casi per evitare lo sfarfallio quando la finestra va a pieno schermo).
  • IQueryDelete, in inglese, fornisce ad un plugin la possibilità di proibire la sua eliminazione.
  • IMainLoop, in inglese, consente di sottoscrivere eventi ''mainloop..
  • IDXDeviceService, in inglese, fornisce l'accesso ai dispositivi Direct3D9 creati da vvvv.
  • IStartable, in inglese, consente di eseguire del codice all'avvio.

Personalizzazione

Il file \lib\thirdparty\CSharp-Mode.xshd consente di effettuare alcune personalizzazioni dell'interfaccia dell'editor di codice di vvvv ed altre cosette interessanti.

Fate attenzione a cosa cambiate all'interno del file:
fate una copia del file originale prima di modificarlo.

anonymous user login

Shoutbox

~8d ago

joreg: Postponed: Next vvvv beginner course starting April 29: https://thenodeinstitute.org/courses/vvvv-beginner-class-summer-2024/

~1mth ago

~1mth 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/

~2mth ago

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

~2mth 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/