Skip to content

Client strategy container relationship

rondevera edited this page Sep 13, 2010 · 23 revisions

Components

Client

The primary client class is XMPPClient (com.mintdigital.hemlock.XMPPClient), and serves as a facade for its __connection__. Containers and __widgets__ should never interact directly with the connection — all incoming and outgoing data should go through the client, which handles connection interactions.

A client instance has three primary responsibilities:

  • Maintain the user’s session data. This includes the user’s username and current XMPP room.
  • Interpret incoming data from the connection. An XMPPClient instance listens for incoming data events coming from its XMPPConnection instance. When these events occur on the XMPPConnection instance, the XMPPClient will either pass the event to a strategy instance (if the event is a MessageEvent), or pass the event to any listening containers by redispatching the event on itself.
  • Prepare outgoing data and send to the connection. An XMPPClient can receive outgoing data in any form (e.g., string, data object), and converts this data into an XMPPStanza (e.g., <message>, <presence>). This XMPPStanza is then passed to the XMPPConnection, which handles sending it out to the Internet.

Strategy

Strategy instances are used only for handling incoming <message> stanzas, which may contain either a plain-text message or a data payload. (For more information on data payloads, see DataMessage class.) A strategy instance is used to differentiate between plain-text messages and data messages, and if the latter, determine what kind of data payload the message contains.

When the client receives an incoming MessageEvent (which contains a Message instance), the event is handled as follows:

  1. The event is passed to the client’s internal stack of strategy instances. (The stack is constructed by the container; this is discussed in the Container section.)
  2. Each strategy in the client’s stack checks to see if the event contains a certain type of data payload, such as a vote, a game move, or a chatroom message. The first strategy to recognize the data payload’s type extracts the required data from the payload. The incoming data is wrapped in a MessageEvent, which is not always appropriate. Therefore, the strategy uses the extracted data to create a new event (e.g., VoteEvent, MoveEvent).
  3. The strategy dispatches the new event on the client. This is transparent to the container, which is listening to the client for these special events. As a result, the container now receives data from the original payload, and can pass the data on to its widgets. (See Container-widget relationship for more information.)

All strategy classes should implement the IEventStrategy interface (com.mintdigital.hemlock.strategies.IEventStrategy), such as MessageEventStrategy. When building a Hemlock app with custom data payloads, each payload type should have its own strategy, which understands how to convert a MessageEvent’s data payload into a custom event tailored to that payload type. This makes it easy to create a custom payload type that can be shared across apps: simply define the payload’s structure, then define a strategy class that can be easily plugged into other apps.

Container

The container is the heart of every Hemlock app, and is the starting point during compilation. Every container should extend HemlockContainer, and should be named according to the app (e.g., an “Extreme Lawnmowing” game would have a container called ExtremeLawnmowing.as). The container has many responsibilities:

  • Maintain an XMPPClient instance. The container listens to this client instance for incoming data events, and sends outgoing data to this client instance.
  • Add strategies to the XMPPClient instance. The container can call client.addEventStrategies([...]) to add strategy instances to the top of the client’s strategy stack in a specific order.
  • Maintain widgets. Every HemlockContainer constructs and tracks widgets in its private _widgets object, and uses its addWidgets() function to add those widgets to the stage in a specific order.
  • Passing events to its widgets. When a container handles an event, it can broadcast that event to its widgets by redispatching the event on itself. As a result, any widgets that are listening to the container for that particular event type will hear it. (See also Container-widget relationship.)
  • Manage system notifications. A system notification can be triggered by a widget, an incoming data event from the client, or the container itself. System notifications are independent of any widget.

More on event handling

Clone this wiki locally