package controllers
{
import events.VoteEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import models.VoteDefinition;
import netgroup.NetGroupEvent;
import netgroup.NetGroupManager;
/**
* Event sent once the netConnection and netGroup connections have been
* successful, and the group is ready to be used.
*/
[Event("connectedToGroup", type="netgroup.NetGroupEvent")]
/**
* Event sent when the role has been set, by the user of from the netGroup
*/
[Event("roleSet", type="events.VoteEvent")]
[Event("startVote", type="events.VoteEvent")]
[Event("stopVote", type="events.VoteEvent")]
[Event("showResults", type="events.VoteEvent")]
/** answersReceived is sent when receiving an answer which isn't the last one */
[Event("answersReceived", type="events.VoteEvent")]
/**
* VoteController manage the NetGroup connection and all data exchanges.
* VoteController is implemented as a Singleton.
*
*/
public class VoteController extends EventDispatcher
{
static private var _instance:VoteController;
static public function get instance():VoteController
{
if (!_instance) _instance = new VoteController();
return _instance;
}
[Bindable]public var connected:Boolean = false;
static public const ROLE_CLIENT:String = 'client';
static public const ROLE_MANAGER:String = 'manager';
private var _role:String;
[Bindable]public function get role():String { return _role; }
public function set role(value:String):void
{
if (_role != null) return; _role = value;
_handshakeVoteManager();
dispatchEvent(new VoteEvent(VoteEvent.ROLE_SET));
}
static public const SUBJECT_SET_VOTE_MANAGER_EXISTENCE:String = 'setVoteManagerExistence';
static public const SUBJECT_START_VOTE:String = 'startVote';
static public const SUBJECT_STOP_VOTE:String = 'stopVote';
static public const SUBJECT_SUBMIT_ANSWERS:String = 'submitAnswers';
static public const SUBJECT_SHOW_RESULTS:String = 'showResults';
protected var netGroupMgr:NetGroupManager;
public var currentVoteDefinition:VoteDefinition;
public var currentVoteAnswers:Array;
public var currentVoteUsers:int;
public var totalVoteClients:int;
public function VoteController(target:IEventDispatcher=null)
{
super(target);
if (_instance) return;
netGroupMgr = new NetGroupManager();
netGroupMgr.applicationName = "active.tutsplus.exemples/";
netGroupMgr.groupName = "sampleApp";
netGroupMgr.addEventListener(NetGroupEvent.POSTING, onNetGroupMessage, false,0,true);
netGroupMgr.addEventListener(NetGroupEvent.CONNECTED_TO_GROUP, onConnectionEstablished, false,0,true);
netGroupMgr.addEventListener(NetGroupEvent.DISCONNECTED_FROM_GROUP, onConnectionLost, false,0,true);
netGroupMgr.addEventListener(NetGroupEvent.NEIGHBOR_JOINED, onNeighborJoined, false,0,true);
netGroupMgr.connect();
}
protected function onConnectionEstablished(event:NetGroupEvent):void
{
connected = true;
dispatchEvent(new Event(NetGroupEvent.CONNECTED_TO_GROUP));
}
protected function onConnectionLost(event:NetGroupEvent):void
{
connected = false;
}
protected function onNeighborJoined(event:NetGroupEvent):void
{
_handshakeVoteManager();
}
private function _handshakeVoteManager():void
{
if (role == ROLE_MANAGER)
{ netGroupMgr.sendMessage(SUBJECT_SET_VOTE_MANAGER_EXISTENCE, {});
}
}
/**
* doStartVote ill be called by submitVote for the VoteManager, and from
* onNetGroupMessage for the voteClients, when receiving a SUBJECT_START_VOTE message
*/
protected function doStartVote(def:VoteDefinition):void
{
var evt:VoteEvent = new VoteEvent(VoteEvent.START_VOTE);
evt.data = def;
dispatchEvent(evt);
}
protected function registerClientAnswers(answers:Array):void
{
for each (var ind:int in answers)
{
currentVoteAnswers[ind]++;
}
currentVoteUsers++;
dispatchEvent(new VoteEvent(VoteEvent.ANSWERS_RECEIVED));
if (currentVoteUsers >= totalVoteClients)
{
dispatchEvent(new VoteEvent(VoteEvent.STOP_VOTE));
netGroupMgr.sendMessage(SUBJECT_STOP_VOTE, 'all answers received');
}
}
public function parseResultsForBroadcast():void
{
var msg:Object = {
answers:currentVoteAnswers,
voteDefinition:currentVoteDefinition,
voteUserCnt:currentVoteUsers,
totalVoteClients:totalVoteClients
};
netGroupMgr.sendMessage(SUBJECT_SHOW_RESULTS, msg);
}
public function submitVote(def:VoteDefinition):void
{
if (role != ROLE_MANAGER) return;
currentVoteDefinition = def;
currentVoteAnswers = [null,0,0,0,0,0]; currentVoteUsers = 0;
totalVoteClients = netGroupMgr.neighborCount;
doStartVote(def);
netGroupMgr.sendMessage(SUBJECT_START_VOTE, def);
}
public function submitAnswers(answers:Array ):void
{
netGroupMgr.sendMessage(SUBJECT_SUBMIT_ANSWERS, answers);
}
/**
* Callback for all the netGroup message we will receive.
* Message routing, based on the message subject, will be done here.
*/
protected function onNetGroupMessage(event:NetGroupEvent):void
{
var message:Object = event.message;
if (!message) return;
var subject:String = event.subject as String;
switch (subject)
{
case VoteController.SUBJECT_SET_VOTE_MANAGER_EXISTENCE:
if (role == null)
role = ROLE_CLIENT;
break;
case SUBJECT_START_VOTE:
doStartVote(new VoteDefinition(message));
break;
case SUBJECT_SUBMIT_ANSWERS:
if (role == ROLE_MANAGER)
{
registerClientAnswers(message as Array);
}
break;
case SUBJECT_STOP_VOTE:
dispatchEvent(new VoteEvent(VoteEvent.STOP_VOTE));
break;
case SUBJECT_SHOW_RESULTS:
currentVoteDefinition = new VoteDefinition(message.voteDefinition);
currentVoteAnswers = message.answers;
currentVoteUsers = message.voteUserCnt;
totalVoteClients = message.totalVoteClients;
dispatchEvent(new VoteEvent(VoteEvent.SHOW_RESULTS));
break;
}
}
}
}