Simplification of the event handling

Current implementation:

	public enum EventType 
	{
		Warning,
		Informative,
		ValueOutOfRange,
		GlobalProgress,
		TimeStepProgres,
		DataChanged,
		TargetBeforeGetValuesCall,
		SourceAfterGetValuesCall,
		SourceBeforeGetValuesReturn,
		TargetAfterGetValuesReturn,
		Other
	}

	public interface IEvent
	{
		EventType Type {get;}
		string Description {get;}
		IPublisher Sender {get;}
		DateTime SimulationTime {get;}
		object GetAttribute(string key);
	}

	public interface IListener
	{
		void OnEvent(IEvent anEvent);
		int GetAcceptedEventTypeCount();
		EventType GetAcceptedEventType(int acceptedEventTypeIndex);
	}

	public interface IPublisher 
	{
		void Subscribe(IListener listener, EventType eventType);
		void UnSubscribe(IListener listener, EventType eventType);
		void SendEvent(IEvent Event);
		int GetPublishedEventTypeCount();
		EventType GetPublishedEventType(int providedEventTypeIndex);
	}

        public interface ILinkableComponent : IPublisher
        {
                ...
        }

This is quite a long way as for an ordinary user who implements simple linkable component (or even complex one).

Suggestion is to simplify it and say that in OpenMI we define a number of events, only for real communication like:

  • Data changed - new values were computed
  • Progress

Also for logging events shouldn't be used at all since there are libraries like log4net, log4j available so sending Debug, Info, Warning, Error message should be part of it, which means - only in SDK and implementation of components.

Then event-related code will look like:

        // event args which will be used only when we need to pass additional data there, otherwise null
        public interface ILinkableComponentEventArgs
        {
                EventType Type { get; }
		string Description { get; }
		DateTime Time { get; }
                IExchangeItem ChangedItem { get; }
                bool Stop { get; set; } // used if simulation should be stopped!
        }


        public enum EventType 
	{
		Warning,
		Informative,
		ValueOutOfRange,
		GlobalProgress,
		TimeStepProgres,
		DataChanged,
		TargetBeforeGetValuesCall,
		SourceAfterGetValuesCall,
		SourceBeforeGetValuesReturn,
		TargetAfterGetValuesReturn,
		Other
	}

    // C# way
    
    public delegate void LinkableComponentEventHandler(object source, ILinkableComponentEventArgs args);

    public interface ILinkableComponent
    {
        event LinkableComponentEventHandler Progressed;
    }



    // Java way (Observable is a class, Observer is an interface!)

    public class LinkableComponentObservable extends Observable
    {
        public void notifyObservers(ILinkableComponentEventArgs args);
    }


    public interface ILinkableComponent
    {
        public LinkableComponentObservable getObservable();
    }

Here we are (only) replacing the OpenMI definition of the IListener and IPublisher interfaces in the Standard with the language specific classes that implement the notification/event mechanism in C# and Java. Development becomes a little bit easier (which in my opinion can also (and better) be done in the SDK), but the Standard no longer contains only interfaces and becomes more implementation language specific.

Logging in the OpenMI SDK

And for logging, somewhere in SDK it will be:

             ... somewhere in the component implementation:

             log.Info("How beautyful the console looks like ");
             log.Warn("You are great you did this");
             log.Error("Who make you know is the best", exception);
             log.Fatal("sadi the great", exception);          

Plus using log4net these messages can be redirected to any window, file, etc. It is a standard way to do logging in both .NET and Java!

  • No labels