Files
vilya/src/as/com/threerings/ezgame/AbstractGameControl.as
T
Ray Greenwell bc2b47a6ca Comment tweaks.
git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@536 c613c5cb-e716-0410-b11b-feb51c14d237
2007-12-22 01:23:40 +00:00

246 lines
6.8 KiB
ActionScript

//
// $Id: EZGameControl.as 526 2007-12-13 01:42:10Z ray $
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.ezgame {
import flash.display.DisplayObject;
import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* Dispatched when the game client is unloaded and you should clean up any Timers or
* other bits left hanging.
*
* @eventType flash.events.Event.UNLOAD
*/
[Event(name="unload", type="flash.events.Event")]
/**
* Abstract base class for GameControl implementations.
*/
public class AbstractGameControl extends AbstractControl
{
/**
* @param autoReady if true, the game will automatically be started when initialization is
* complete, if false, the game will not start until all clients call {@link #playerReady}.
*/
public function AbstractGameControl (disp :DisplayObject, autoReady :Boolean)
{
if (disp == null || Object(this).constructor == AbstractGameControl) {
throw new IllegalOperationError("Abstract");
}
createSubControls();
var event :DynEvent = new DynEvent();
event.userProps = new Object();
populateProperties(event.userProps);
event.userProps["autoReady_v1"] = autoReady;
disp.root.loaderInfo.sharedEvents.dispatchEvent(event);
if ("ezProps" in event) {
setHostProps(event.ezProps);
}
// set up our focusing click handler
disp.root.addEventListener(MouseEvent.CLICK, handleRootClick);
// set up the unload event to propagate
disp.root.loaderInfo.addEventListener(Event.UNLOAD, dispatch);
}
override public function isConnected () :Boolean
{
return _connected;
}
/**
* Create any subcontrols used by this game.
*/
protected function createSubControls () :void
{
_subControls.push(
_localCtrl = createLocalControl(),
_netCtrl = createNetControl(),
_playerCtrl = createPlayerControl(),
_gameCtrl = createGameControl(),
_servicesCtrl = createServicesControl()
);
}
/**
* Create the 'local' subcontrol.
*/
protected function createLocalControl () :EZLocalSubControl
{
return new EZLocalSubControl(this);
}
/**
* Create the 'net' subcontrol.
*/
protected function createNetControl () :EZNetSubControl
{
return new EZNetSubControl(this);
}
/**
* Create the 'player' subcontrol.
*/
protected function createPlayerControl () :EZPlayerSubControl
{
return new EZPlayerSubControl(this);
}
/**
* Create the 'game' subcontrol.
*/
protected function createGameControl () :EZGameSubControl
{
return new EZGameSubControl(this);
}
/**
* Create the 'services' subcontrol.
*/
protected function createServicesControl () :EZServicesSubControl
{
return new EZServicesSubControl(this);
}
/**
* Populate any properties or functions we want to expose to the other side of the ezgame
* security boundary.
*/
override protected function populateProperties (o :Object) :void
{
super.populateProperties(o);
o["connectionClosed_v1"] = connectionClosed_v1;
for each (var ctrl :AbstractSubControl in _subControls) {
ctrl.populatePropertiesFriend(o);
}
}
/**
* Sets the properties we received from the host framework on the other side of the security
* boundary.
*/
override protected function setHostProps (o :Object) :void
{
super.setHostProps(o);
// see if we're connected
_connected = (o.gameData != null);
for each (var ctrl :AbstractSubControl in _subControls) {
ctrl.setHostPropsFriend(o);
}
// and assign our functions
_funcs = o;
}
override protected function callHostCode (name :String, ... args) :*
{
if (_funcs != null) {
try {
var func :Function = (_funcs[name] as Function);
if (func != null) {
return func.apply(null, args);
}
} catch (err :Error) {
trace(err.getStackTrace());
trace("--");
throw new Error("Unable to call host code: " + err.message);
}
} else {
// if _funcs is null, this will almost certainly throw an error..
checkIsConnected();
}
}
/**
* Internal method that is called whenever the mouse clicks our root.
*/
protected function handleRootClick (evt :MouseEvent) :void
{
if (!isConnected()) {
return;
}
try {
if (evt.target.stage == null || evt.target.stage.focus != null) {
return;
}
} catch (err :SecurityError) {
}
callHostCode("focusContainer_v1");
}
/**
* Private method called when the backend disconnects from us.
*/
private function connectionClosed_v1 () :void
{
_connected = false;
}
/** Are we connected? */
protected var _connected :Boolean;
/** Contains functions exposed to us from the EZGame host. */
protected var _funcs :Object;
/** Holds all our sub-controls. */
protected var _subControls :Array = [];
/** Specific sub-controls. */
protected var _localCtrl :EZLocalSubControl;
protected var _netCtrl :EZNetSubControl;
protected var _playerCtrl :EZPlayerSubControl;
protected var _gameCtrl :EZGameSubControl;
protected var _servicesCtrl :EZServicesSubControl;
}
}
import flash.events.Event;
dynamic class DynEvent extends Event
{
public function DynEvent ()
{
super("ezgameQuery", true, false);
}
override public function clone () :Event
{
return new DynEvent();
}
}