User Tools

Site Tools


events-ids-references

In order to support fully generalised runtime adaptability throughout all possible design patterns, Dana does not include the concept of self-references from objects. An object cannot therefore use a keyword such as “this” to pass a reference to its own instance to another object.

Dana provides two mechanisms to assist in creating the kinds of design pattern for this self-references are often used. These are unique object identifiers and an event model.

Unique Object Identifiers

Every Dana object inherently supports the getID() function, as declared in the Object type. This function returns a unique identifier for that object as a string. The identifier returned is guaranteed not to be associated with any other object instance that exists. However, Dana does re-cycle object identifiers when objects get cleaned up. Over time you may therefore see the same object identifier being used across different objects due to old objects being garbage collected and their IDs being assigned to newer objects; however no two live objects will ever have the same identifier at the same time.

Because an object can access its own unique ID, by simply calling getID(), this means that objects can pass their own identifier to other objects, for example to have that ID compared against a list of object IDs stored at such other objects.

The Event Model

Dana includes an event model to support design patterns that involve callback-style behaviour, where one object wishes to be notified of something that has happened in another object.

Dana's event model is composed of event sources and event sinks together with the operations sinkevent and emitevent.

Any interface can declare an event source from which notifications are emitted. This is done as follows:

interface MyInterface {
   MyInterface()
 
   const int EVENT_PLAY = 1
   eventsource funEvents
   }

An object implementing this interface can produce events using the emitevent operation:

component provides MyInterface requires time.Timer timer {
 
   void eventProducer()
      {
      while (true)
         {
         timer.sleep(10000)
         emitevent funEvents(MyInterface.EVENT_PLAY, null)
         }
      }
 
   MyInterface:MyInterface()
      {
      asynch::eventProducer()
      }
   }

An object can then receive notifications from this event source by declaring an event sink and using the sinkevent operation as follows:

component provides App requires io.Output out, MyInterface {
 
   eventsink MyEvents(EventData ed)
      {
      if (ed.type == MyInterface.EVENT_PLAY)
         {
         out.println("play time!")
         }
      }
 
   int App:main(AppParam params[])
      {
      MyInterface a = new MyInterface()
      sinkevent MyEvents(a.funEvents)
 
      this.thread.wait()
 
      return 0
      }
   }

As well as the event type identifier, the EventData type also includes a source field which provides a reference to the object that generated the event, and a details field which refers to a Data instance offering additional details relevant to that event. To do this, the second parameter of emitevent can be any data type instance, which is then referenced from the EventData instance delivered to the event sink.

Together, Dana's unique object identifiers and event model support a wide range of design patterns for which self-references would otherwise be needed.

events-ids-references.txt · Last modified: 2017/08/18 09:51 by barryfp

Page Tools