using LibPDBinding.Managed.Data;
using LibPDBinding.Managed.Events;
using LibPDBinding.Managed.Utils;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace LibPDBinding.Managed
{
///
/// Messaging in Pd.
///
public sealed class Messaging : IDisposable
{
readonly Pd _pd;
internal Messaging (Pd pd)
{
_pd = pd;
SetupHooks ();
}
~Messaging ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
void Dispose (bool disposing)
{
_pd.Activate ();
foreach (IntPtr pointer in _bindings.Values) {
Native.Messaging.unbind (pointer);
}
Print = null;
Bang = null;
Float = null;
Symbol = null;
List = null;
Message = null;
}
readonly Dictionary _bindings = new Dictionary ();
///
/// Send a general message to the specified receiver with a range of atoms.
///
/// Receiver.
/// Message.
/// Atoms.
[MethodImpl (MethodImplOptions.Synchronized)]
public void Send (string receiver, string message, params IAtom[] atoms)
{
_pd.Activate ();
MessageInvocation.SendMessage (receiver, message, atoms);
}
///
/// Send a message to the specified receiver with a range of atoms.
///
/// Receiver.
/// Atoms.
[MethodImpl (MethodImplOptions.Synchronized)]
public void Send (string receiver, params IAtom[] atoms)
{
_pd.Activate ();
if (atoms.Length == 1) {
MessageInvocation.Send (receiver, atoms [0]);
return;
}
MessageInvocation.SendList (receiver, atoms);
}
///
/// Send a bang message to the specified receiver with a range of atoms.
///
/// Receiver.
/// Bang.
[MethodImpl (MethodImplOptions.Synchronized)]
public void Send (string receiver, Bang bang)
{
_pd.Activate ();
MessageInvocation.SendBang (receiver);
}
///
/// Binds to get messages from the specified receiver.
///
/// Receiver.
[MethodImpl (MethodImplOptions.Synchronized)]
public void Bind (string receiver)
{
_pd.Activate ();
if (_bindings.ContainsKey (receiver)) {
return;
}
IntPtr pointer = Native.Messaging.bind (receiver);
_bindings.Add (receiver, pointer);
}
///
/// Unbinds from the specified receiver.
///
/// Receiver.
[MethodImpl (MethodImplOptions.Synchronized)]
public void Unbind (string receiver)
{
_pd.Activate ();
IntPtr pointer;
if (!_bindings.TryGetValue (receiver, out pointer)) {
return;
}
Native.Messaging.unbind (pointer);
_bindings.Remove (receiver);
}
void RaisePrintEvent (string text)
{
if (Print != null) {
Print (this, new PrintEventArgs (text));
}
}
void RaiseBangEvent (string recv)
{
if (Bang != null) {
Bang (this, new BangEventArgs (recv));
}
}
void RaiseFloatEvent (string recv, float x)
{
if (Float != null) {
Float (this, new FloatEventArgs (recv, x));
}
}
void RaiseSymbolEvent (string recv, string sym)
{
if (Symbol != null) {
Symbol (this, new SymbolEventArgs (recv, sym));
}
}
void RaiseListEvent (string recv, int argc, IntPtr argv)
{
if (List != null) {
List (this, new ListEventArgs (recv, argc, argv));
}
}
void RaiseMessageEvent (string recv, string msg, int argc, IntPtr argv)
{
if (Message != null) {
Message (this, new MessageEventArgs (recv, msg, argc, argv));
}
}
///
/// Occurs when print is called in Pd.
///
public event EventHandler Print;
///
/// Occurs when a Bang message is received on a subscribed receiver.
///
public event EventHandler Bang;
///
/// Occurs when a Float message is received on a subscribed receiver.
///
public event EventHandler Float;
///
/// Occurs when a Symbol message is received on a subscribed receiver.
///
public event EventHandler Symbol;
///
/// Occurs when a List message is received on a subscribed receiver.
///
public event EventHandler List;
///
/// Occurs when a general message is received on a subscribed receiver.
///
public event EventHandler Message;
LibPDPrintHook PrintHook;
LibPDBangHook BangHook;
LibPDFloatHook FloatHook;
LibPDSymbolHook SymbolHook;
LibPDListHook ListHook;
LibPDMessageHook MessageHook;
void SetupHooks ()
{
PrintHook = new LibPDPrintHook (RaisePrintEvent);
Native.Messaging.set_printhook (Native.Messaging.print_concatenator);
Native.Messaging.set_concatenated_printhook (PrintHook);
BangHook = new LibPDBangHook (RaiseBangEvent);
Native.Messaging.set_banghook (BangHook);
FloatHook = new LibPDFloatHook (RaiseFloatEvent);
Native.Messaging.set_floathook (FloatHook);
SymbolHook = new LibPDSymbolHook (RaiseSymbolEvent);
Native.Messaging.set_symbolhook (SymbolHook);
ListHook = new LibPDListHook (RaiseListEvent);
Native.Messaging.set_listhook (ListHook);
MessageHook = new LibPDMessageHook (RaiseMessageEvent);
Native.Messaging.set_messagehook (MessageHook);
}
}
}