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); } } }