summaryrefslogtreecommitdiff
path: root/CSharp
diff options
context:
space:
mode:
authorfcolin2007-02-01 09:56:08 +0000
committerfcolin2007-02-01 09:56:08 +0000
commitf23c66a2b5ade0dbf601d9657f327789e909d560 (patch)
tree1afabbf764ffc6ebd7aef69b40fbd7d5d76dd4c9 /CSharp
parent6eb6f27858cd1822ef93e6988a95d3325a69ee8a (diff)
downloadivy-csharp-f23c66a2b5ade0dbf601d9657f327789e909d560.zip
ivy-csharp-f23c66a2b5ade0dbf601d9657f327789e909d560.tar.gz
ivy-csharp-f23c66a2b5ade0dbf601d9657f327789e909d560.tar.bz2
ivy-csharp-f23c66a2b5ade0dbf601d9657f327789e909d560.tar.xz
Utilisateur : Fcolin Date : 23/06/06 Heure : 11:12 Archivé dans $/CSharp/Ivy/Ivy Commentaire: (vss 66)
Diffstat (limited to 'CSharp')
-rw-r--r--CSharp/Ivy/IvyPPC/Ivy.cs269
1 files changed, 149 insertions, 120 deletions
diff --git a/CSharp/Ivy/IvyPPC/Ivy.cs b/CSharp/Ivy/IvyPPC/Ivy.cs
index a64acb8..5f29976 100644
--- a/CSharp/Ivy/IvyPPC/Ivy.cs
+++ b/CSharp/Ivy/IvyPPC/Ivy.cs
@@ -24,6 +24,11 @@ namespace IvyBus
using System.ComponentModel;
using System.Diagnostics;
+ using System.ComponentModel;
+ using System.ComponentModel.Design;
+ using System.Drawing.Design;
+
+
/// <summary> The Main bus Class
/// </summary>
///
@@ -33,7 +38,7 @@ namespace IvyBus
[Description("IVY Main API")]
#endif
[DesignerCategory("Component")]
- public class Ivy : System.ComponentModel.Component, ISupportInitialize
+ public class Ivy : System.ComponentModel.Component, ISupportInitialize
{
/* Event */
/// <summary>fires when a new client connect to the bus</summary>
@@ -192,18 +197,18 @@ namespace IvyBus
#if (!PocketPC)
[Category("Ivy")]
#endif
- [DefaultValue(null)]
- public StringCollection SentMessageClasses
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ // sinon bug System.String constructor not found !
+ [Editor(
+ "System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
+ "System.Drawing.Design.UITypeEditor,System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
+ )]
+ public StringCollection SentMessageFilter
{
get
{
- return sent_messageClasses;
- }
- set
- {
- sent_messageClasses = value;
+ return sent_messageFilter;
}
-
}
/// <summary>ReadyMessage message send when Application receive all the regexp at the connection of the client</summary>
@@ -229,6 +234,34 @@ namespace IvyBus
syncControl = value;
}
}
+#if (!PocketPC)
+ [Category("Ivy")]
+#endif
+
+ [DefaultValue(null)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
+ [Editor(typeof(IvyBindingCollectionEditor), typeof(UITypeEditor))]
+ public List<IvyApplicationBinding> Bindings
+ {
+ get { return app_bindings; }
+ //set { app_bindings = value; }
+ }
+ //create a collection editor class
+
+ private class IvyBindingCollectionEditor : CollectionEditor
+ {
+ public IvyBindingCollectionEditor(Type type)
+ : base(type)
+ {
+ }
+
+ //Over ride the function which will return the STYLES collection
+ protected override System.Type[] CreateNewItemTypes()
+ {
+ return new Type[] { typeof(IvyApplicationBinding) };
+ }
+ }
+
internal class MyTcpListener : TcpListener
{
public MyTcpListener(IPAddress address, int port)
@@ -240,7 +273,6 @@ namespace IvyBus
return this.Active;
}
}
-
/// the name of the application on the bus
internal string appName;
/// the port for the UDP rendez vous, if none is supplied
@@ -250,25 +282,17 @@ namespace IvyBus
/// the domain for the UDP rendez vous
private static readonly string DEFAULT_DOMAIN = "127.255.255.255:" + DEFAULT_PORT;
internal int protocolVersion = 3;
- private static bool debug; // false by deflaut runtime
+ private static bool debug; // false by default runtime
private static ushort serial; /* an unique ID for each regexp */ // 0 by default runtime
private MyTcpListener app;
private List<IvyWatcher> watchers;
private volatile Thread serverThread; // to ensure quick communication of the end
- internal enum BindingType { BindRegexp, BindSimple };
- internal struct ApplicationBinding /* Self Applications bindings */
- {
- internal BindingType type;
- internal ushort key;
- internal EventHandler<IvyMessageEventArgs> callback;
- internal string expression;
- internal object[] args;
- }
-
- internal Dictionary<int, ApplicationBinding> bindings;
+ internal Dictionary<int, IvyApplicationBinding> bindings;
+ //TODO should be remove samve as above
+ private List<IvyApplicationBinding> app_bindings;
private List<IvyClient> clients;
- private StringCollection sent_messageClasses;
+ private StringCollection sent_messageFilter;
private bool stopped = true;
internal ushort applicationPort; /* Application port number */
internal IPAddress applicationHost; /* Application host number */
@@ -283,7 +307,9 @@ namespace IvyBus
public Ivy()
{
clients = new List<IvyClient>();
- bindings = new Dictionary<int, ApplicationBinding>();
+ bindings = new Dictionary<int, IvyApplicationBinding>();
+ app_bindings = new List<IvyApplicationBinding>();
+ sent_messageFilter = new StringCollection();
#if (!PocketPC )
debug = Properties.Settings.Default.IvyDebug;
protocolVersion = Properties.Settings.Default.IvyProtocolVersion;
@@ -341,6 +367,7 @@ namespace IvyBus
base.Dispose(disposing);
}
}
+
// Autobinding on static method
public void AutoBinding(Type type)
{
@@ -570,6 +597,9 @@ namespace IvyBus
// instead of one for all the clients. It might be a performance issue
lock (clients)
{
+ // hash message in V4 protocol only
+ if (ProtocolVersion == 4)
+ IvyBindingSimple.Prepare(msg);
foreach (IvyClient client in clients)
{
count += client.sendMsg(msg);
@@ -577,7 +607,22 @@ namespace IvyBus
}
return count;
}
-
+ //
+ public ushort BindMsg(IvyApplicationBinding newbind)
+ {
+ newbind.Key = serial++;
+
+ lock (bindings) bindings.Add(newbind.Key, newbind);
+ // notifies the other clients this new regexp
+ lock (clients)
+ {
+ foreach (IvyClient c in clients)
+ {
+ c.stream.TokenAddBinding(newbind.Binding, newbind.Key, newbind.Expression);
+ }
+ }
+ return newbind.Key;
+ }
/// <summary> Subscribes to a regular expression.
/// </summary>
/// <remarks>
@@ -605,22 +650,13 @@ namespace IvyBus
public ushort BindMsg(string regexp, EventHandler<IvyMessageEventArgs> callback, params object[] args)
{
// creates a new binding (regexp,callback)
- ApplicationBinding newbind;
- newbind.type = BindingType.BindRegexp;
- newbind.key = serial++;
- newbind.expression = regexp;
- newbind.callback = callback;
- newbind.args = args;
- lock (bindings) bindings.Add(newbind.key, newbind);
- // notifies the other clients this new regexp
- lock (clients)
- {
- foreach (IvyClient c in clients)
- {
- c.stream.TokenAddBinding(newbind);
- }
- }
- return newbind.key;
+ IvyApplicationBinding newbind;
+ newbind = new IvyApplicationBinding();
+ newbind.Binding = BindingType.Regexp;
+ newbind.Expression = regexp;
+ newbind.Callback += callback;
+ newbind.Args = args;
+ return BindMsg(newbind);
}
/// <summary> unsubscribes a regular expression
@@ -634,7 +670,6 @@ namespace IvyBus
{
throw new IvyException("client wants to remove an unexistant regexp " + id);
}
- //ApplicationBinding bind = (ApplicationBinding)bindings[id];
lock (clients)
{
foreach (IvyClient c in clients)
@@ -655,13 +690,13 @@ namespace IvyBus
/// </param>
public bool UnbindMsg(string re)
{
- foreach (ApplicationBinding bind in bindings.Values)
+ foreach (IvyApplicationBinding bind in bindings.Values)
{
- if (bind.expression == re)
+ if (bind.Expression == re)
{
try
{
- UnbindMsg(bind.key);
+ UnbindMsg(bind.Key);
}
catch (IvyException)
{
@@ -684,7 +719,7 @@ namespace IvyBus
///
/// <param name='regexp'>a regular expression, groups are done with parenthesis
/// </param>
- /// <param name='callback'>any objects implementing the Ivy.MessageListener
+ /// <param name='callback'>any objects implementing the EventHandler<IvyMessageEventArgs>
/// </param>
/// <returns>the id of the regular expression
///
@@ -693,22 +728,13 @@ namespace IvyBus
public int BindSimpleMsg(string expression, EventHandler<IvyMessageEventArgs> callback, params object[] args)
{
// creates a new binding (regexp,callback)
- ApplicationBinding newbind;
- newbind.type = BindingType.BindSimple;
- newbind.key = serial++;
- newbind.expression = expression;
- newbind.callback = callback;
- newbind.args = args;
- lock (bindings) bindings.Add(newbind.key, newbind);
- // notifies the other clients this new regexp
- lock (clients)
- {
- foreach (IvyClient c in clients)
- {
- c.stream.TokenAddBinding(newbind);
- }
- }
- return newbind.key;
+ IvyApplicationBinding newbind;
+ newbind = new IvyApplicationBinding();
+ newbind.Binding = BindingType.Simple;
+ newbind.Expression = expression;
+ newbind.Callback += callback;
+ newbind.Args = args;
+ return BindMsg(newbind);
}
public int Die(string target, string message)
{
@@ -735,86 +761,77 @@ namespace IvyBus
return true;
else return false;
}
- internal virtual void OnDirectMessage(IvyEventArgs e)
+ internal virtual void FireEvent(EventHandler<IvyEventArgs> ev, IvyEventArgs e)
{
- if (DirectMessageReceived != null)
+ if (ev != null)
{
if (IsSynchronous())
- syncControl.Invoke(DirectMessageReceived, this, e );
- else DirectMessageReceived(this, e);
+ syncControl.Invoke(ev, this, e);
+ else ev(this, e);
}
}
+ internal virtual void OnDirectMessage(IvyEventArgs e)
+ {
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = DirectMessageReceived;
+ FireEvent(temp,e);
+ }
internal virtual void OnClientConnected(IvyEventArgs e)
{
- if (ClientConnected != null)
- {
- if (IsSynchronous())
- syncControl.Invoke(ClientConnected, this, e );
- else ClientConnected(this,e);
- }
-
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = ClientConnected;
+ FireEvent(temp,e);
}
internal virtual void OnClientDisconnected(IvyEventArgs e)
{
- if (ClientDisconnected != null)
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = ClientDisconnected;
+ try
{
- try
- {
- if (IsSynchronous())
- syncControl.Invoke(ClientDisconnected, this, e );
- else ClientDisconnected(this,e);
- }
- catch (ObjectDisposedException )
- {
- // protect terminaison
- }
+ FireEvent(temp,e);
}
+ catch (ObjectDisposedException)
+ {
+ // protect terminaison
+ }
+
}
internal virtual void OnClientAddBinding(IvyEventArgs e)
{
- if (BindingAdd != null)
- {
- if (IsSynchronous())
- syncControl.Invoke(BindingAdd, this, e );
- else BindingAdd(this, e);
- }
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = BindingAdd;
+ FireEvent(temp,e);
}
internal virtual void OnClientRemoveBinding(IvyEventArgs e)
{
- if (BindingRemove != null)
- {
- if (IsSynchronous())
- syncControl.Invoke(BindingRemove, this, e );
- else BindingRemove(this, e);
- }
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = BindingRemove;
+ FireEvent(temp,e);
}
internal virtual void OnClientFilterBinding(IvyEventArgs e)
{
- if (BindingFilter != null)
- {
- if (IsSynchronous())
- syncControl.Invoke(BindingFilter, this, e);
- else BindingFilter(this, e);
- }
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = BindingFilter;
+ FireEvent(temp,e);
}
- internal virtual void OnDie(IvyDieEventArgs e)
+ internal virtual void OnError(IvyEventArgs e)
{
- if (DieReceived != null)
- {
- if (IsSynchronous())
- syncControl.Invoke(DieReceived, this, e );
- else DieReceived(this, e);
- }
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyEventArgs> temp = ErrorMessage;
+ FireEvent(temp, e);
}
- internal virtual void OnError(IvyEventArgs e)
+ internal virtual void OnDie(IvyDieEventArgs e)
{
- if (ErrorMessage != null)
+ // Copy to a temporary variable to be thread-safe.
+ EventHandler<IvyDieEventArgs> temp = DieReceived;
+ if (temp != null)
{
if (IsSynchronous())
- syncControl.Invoke(ErrorMessage, this, e );
- else ErrorMessage(this, e);
+ syncControl.Invoke(temp, this, e );
+ else temp(this, e);
}
}
+
/*
* removes a client from the list
@@ -860,16 +877,24 @@ namespace IvyBus
}
}
- internal void FireCallback(IvyMessageEventArgs e)
+ internal void OnMessage(IvyMessageEventArgs e)
{
- ApplicationBinding bind = bindings[e.Id];
- if (bind.callback == null)
+ IvyApplicationBinding bind = bindings[e.Id];
+
+ if (bind == null)
{
throw new IvyException("(callCallback) Not regexp matching id " + e.Id);
}
+ //// Safely invoke an event:
+ EventHandler<IvyMessageEventArgs> temp = bind.CallbackHandler;
+
+ if (temp == null)
+ {
+ throw new IvyException("(callCallback) Not callback for id " + e.Id);
+ }
if (IsSynchronous())
- syncControl.Invoke(bind.callback, this, e );
- else bind.callback(this, e);
+ syncControl.Invoke(temp, this, e );
+ else temp(this, e);
}
public static IPAddress GetLocalIP()
@@ -934,13 +959,13 @@ namespace IvyBus
// Attention Bug
// ClockStop ClockStart & ^Clock(Start|Pause)
// should Stop to the first parent
- if ((sent_messageClasses != null) && exp.StartsWith("^"))
+ if ((sent_messageFilter.Count != 0) && exp.StartsWith("^"))
{
regexp_ok = false;
// extract first word from regexp...
string token = Regex.Replace(exp, @"^\^(?<token>[a-zA-Z_0-9-]+).*", @"${token}");
- foreach (string exp_class in sent_messageClasses)
+ foreach (string exp_class in sent_messageFilter)
{
if (exp_class.StartsWith(token))
return true;
@@ -1087,8 +1112,12 @@ namespace IvyBus
{
if (syncControl != null)
AutoBinding(syncControl);
+ // TODO ugly should be added directly the bindings Dictionary !
+ foreach (IvyApplicationBinding bind in app_bindings)
+ BindMsg(bind);
}
#endregion
+
}
} \ No newline at end of file