EZGame API breakup. Possibly a little more to come.

git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@205 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Ray Greenwell
2007-02-22 03:44:12 +00:00
parent 8a2539683b
commit 9e8dce3619
7 changed files with 254 additions and 159 deletions
@@ -0,0 +1,44 @@
package com.threerings.ezgame {
import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.EventDispatcher;
/**
* The abstract base class for EZ controls.
*/
public class BaseControl extends EventDispatcher
{
public function BaseControl ()
{
if (Object(this).constructor == BaseControl) {
throw new IllegalOperationError("Abstract");
}
}
/**
* Your own events may not be dispatched here.
*/
override public function dispatchEvent (event :Event) :Boolean
{
// Ideally we want to not be an EventDispatcher so that people
// won't try to do this on us, but if we do that, then some other
// object will be the target during dispatch, and that's confusing.
throw new IllegalOperationError();
}
/**
* Secret function to dispatch property changed events.
*/
internal function dispatch (event :Event) :void
{
try {
super.dispatchEvent(event);
} catch (err :Error) {
trace("Error dispatching event to user game.");
trace(err.getStackTrace());
}
}
}
}
+3 -3
View File
@@ -19,19 +19,19 @@ public class CardDeck
}
}
_gameCtrl.setCollection(_deckName, deck);
_gameCtrl.collections.create(_deckName, deck);
}
public function dealToPlayer (
playerId :int, count :int, msgName :String) :void
{
// TODO: support the callback
_gameCtrl.dealFromCollection(_deckName, count, msgName, null, playerId);
_gameCtrl.collections.deal(_deckName, count, msgName, null, playerId);
}
public function dealToData (count :int, propName :String) :void
{
_gameCtrl.dealFromCollection(_deckName, count, propName, null);
_gameCtrl.collections.deal(_deckName, count, propName, null);
}
/** The game control. */
@@ -0,0 +1,110 @@
package com.threerings.ezgame {
/**
* Contains EZ methods related to collections.
*/
public class CollectionsControl extends SubControl
{
public function CollectionsControl (ctrl :EZGameControl)
{
super(ctrl);
}
/**
* Create a collection containing the specified values,
* clearing any previous collection with the same name.
*/
public function create (collName :String, values :Array) :void
{
populate(collName, values, true);
}
/**
* Add to an existing collection. If it doesn't exist, it will
* be created. The new values will be inserted randomly into the
* collection.
*/
public function addTo (collName :String, values :Array) :void
{
populate(collName, values, false);
}
/**
* Merge the specified collection into the other collection.
* The source collection will be destroyed. The elements from
* The source collection will be shuffled and appended to the end
* of the destination collection.
*/
public function merge (srcColl :String, intoColl :String) :void
{
_ctrl.callEZCode("mergeCollection_v1", srcColl, intoColl);
}
/**
* Pick (do not remove) the specified number of elements from a collection,
* and distribute them to a specific player or set them as a property
* in the game data.
*
* @param collName the collection name.
* @param count the number of elements to pick
* @param msgOrPropName the name of the message or property
* that will contain the picked elements.
* @param playerId if 0 (or unset), the picked elements should be
* set on the gameObject as a property for all to see.
* If a playerId is specified, only that player will receive
* the elements as a message.
*/
// TODO: a way to specify exclusive picks vs. duplicate-OK picks?
public function pick (
collName :String, count :int, msgOrPropName :String,
playerId :int = 0) :void
{
getFrom(collName, count, msgOrPropName, playerId, false, null);
}
/**
* Deal (remove) the specified number of elements from a collection,
* and distribute them to a specific player or set them as a property
* in the game data.
*
* @param collName the collection name.
* @param count the number of elements to pick
* @param msgOrPropName the name of the message or property
* that will contain the picked elements.
* @param playerId if 0 (or unset), the picked elements should be
* set on the gameObject as a property for all to see.
* If a playerId is specified, only that player will receive
* the elements as a message.
*/
// TODO: figure out the method signature of the callback
public function deal (
collName :String, count :int, msgOrPropName :String,
callback :Function = null, playerId :int = 0) :void
{
getFrom(collName, count, msgOrPropName, playerId, true, callback);
}
// == protected methods ==
/**
* Helper method for create and addTo.
*/
protected function populate (
collName :String, values :Array, clearExisting :Boolean) :void
{
_ctrl.callEZCode("populateCollection_v1", collName, values, clearExisting);
}
/**
* Helper method for pick and deal.
*/
protected function getFrom (
collName :String, count :int, msgOrPropName :String, playerId :int,
consume :Boolean, callback :Function) :void
{
_ctrl.callEZCode("getFromCollection_v2", collName, count, msgOrPropName,
playerId, consume, callback);
}
}
}
+44 -154
View File
@@ -65,7 +65,7 @@ import flash.display.DisplayObject;
*
* TODO: lots of documentation.
*/
public class EZGameControl extends EventDispatcher
public class EZGameControl extends BaseControl
{
/**
* Create an EZGameControl object using some display object currently
@@ -83,15 +83,9 @@ public class EZGameControl extends EventDispatcher
// set up our focusing click handler
disp.root.addEventListener(MouseEvent.CLICK, handleRootClick);
}
/**
* Are we connected and running inside the EZGame environment, or
* has someone just loaded up this swf by itself?
*/
public function isConnected () :Boolean
{
return (_gameData != null);
// TODO: this should only be available if the game uses it
_seating = new SeatingControl(this);
}
// documentation inherited
@@ -108,6 +102,7 @@ public class EZGameControl extends EventDispatcher
if (hasEventListener(type)) { // ensure it was added
callEZCode("alterKeyEvents_v1", type, true);
}
break;
}
}
@@ -123,23 +118,54 @@ public class EZGameControl extends EventDispatcher
if (!hasEventListener(type)) { // once it's no longer needed
callEZCode("alterKeyEvents_v1", type, false);
}
break;
}
}
/**
* Data accessor.
* Are we connected and running inside the EZGame environment, or
* has someone just loaded up this swf by itself?
*/
public function get data () :Object
public function isConnected () :Boolean
{
return _gameData;
return (_gameData != null);
}
/**
* Get the CollectionsControl, which contains methods for utilizing
* the server to dispatch private information.
*/
public function get collections () :CollectionsControl
{
if (_collections == null) {
_collections = new CollectionsControl(this);
}
return _collections;
}
/**
* Get the SeatingControl, which contains methods for checking
* and assigning player seating positions.
*/
public function get seating () :SeatingControl
{
return _seating;
}
// /**
// * Data accessor.
// */
// public function get data () :Object
// {
// return _gameData;
// }
/**
* Get a property from data.
*/
public function get (propName :String, index :int = -1) :Object
{
var value :Object = data[propName];
var value :Object = _gameData[propName];
if (index >= 0) {
if (value is Array) {
return (value as Array)[index];
@@ -300,82 +326,6 @@ public class EZGameControl extends EventDispatcher
callEZCode("checkDictionaryWord_v1", locale, word, callback);
}
/**
* Set the specified collection to contain the specified values,
* clearing any previous values.
*/
public function setCollection (collName :String, values :Array) :void
{
populateCollection(collName, values, true);
}
/**
* Add to an existing collection. If it doesn't exist, it will
* be created. The new values will be inserted randomly into the
* collection.
*/
public function addToCollection (collName :String, values :Array) :void
{
populateCollection(collName, values, false);
}
/**
* Pick (do not remove) the specified number of elements from a collection,
* and distribute them to a specific player or set them as a property
* in the game data.
*
* @param collName the collection name.
* @param count the number of elements to pick
* @param msgOrPropName the name of the message or property
* that will contain the picked elements.
* @param playerId if 0 (or unset), the picked elements should be
* set on the gameObject as a property for all to see.
* If a playerId is specified, only that player will receive
* the elements as a message.
*/
// TODO: a way to specify exclusive picks vs. duplicate-OK picks?
public function pickFromCollection (
collName :String, count :int, msgOrPropName :String,
playerId :int = 0) :void
{
getFromCollection(collName, count, msgOrPropName, playerId,
false, null);
}
/**
* Deal (remove) the specified number of elements from a collection,
* and distribute them to a specific player or set them as a property
* in the game data.
*
* @param collName the collection name.
* @param count the number of elements to pick
* @param msgOrPropName the name of the message or property
* that will contain the picked elements.
* @param playerId if 0 (or unset), the picked elements should be
* set on the gameObject as a property for all to see.
* If a playerId is specified, only that player will receive
* the elements as a message.
*/
// TODO: figure out the method signature of the callback
public function dealFromCollection (
collName :String, count :int, msgOrPropName :String,
callback :Function = null, playerId :int = 0) :void
{
getFromCollection(collName, count, msgOrPropName, playerId,
true, callback);
}
/**
* Merge the specified collection into the other collection.
* The source collection will be destroyed. The elements from
* The source collection will be shuffled and appended to the end
* of the destination collection.
*/
public function mergeCollection (srcColl :String, intoColl :String) :void
{
callEZCode("mergeCollection_v1", srcColl, intoColl);
}
/**
* Send a "message" to other clients subscribed to the game.
* These is similar to setting a property, except that the
@@ -446,25 +396,6 @@ public class EZGameControl extends EventDispatcher
return String(callEZCode("getOccupantName_v1", playerId));
}
// TODO: NEW: Table control
/**
* Get the player's position, or -1 if not a player.
*/
public function getPlayerPosition (playerId :int) :int
{
return int(callEZCode("getPlayerPosition_v1", playerId));
}
// TODO: NEW: Table control
/**
* Get all the players at the table, in their seated position.
* Absent players will be represented by a 0.
*/
public function getPlayers () :Array /* of playerId (int) */
{
return (callEZCode("getPlayers_v1") as Array);
}
// TODO: NEW
public function getMyId () :int
{
@@ -542,38 +473,6 @@ public class EZGameControl extends EventDispatcher
callEZCode.apply(null, args);
}
/**
* Your own events may not be dispatched here.
*/
override public function dispatchEvent (event :Event) :Boolean
{
// Ideally we want to not be an IEventDispatcher so that people
// won't try to do this on us, but if we do that, then some other
// object will be the target during dispatch, and that's confusing.
// It's really nice to be able to
throw new IllegalOperationError();
}
/**
* Helper method for setCollection and addToCollection.
*/
protected function populateCollection (
collName :String, values :Array, clearExisting :Boolean) :void
{
callEZCode("populateCollection_v1", collName, values, clearExisting);
}
/**
* Helper method for pickFromCollection and dealFromCollection.
*/
protected function getFromCollection (
collName :String, count :int, msgOrPropName :String, playerId :int,
consume :Boolean, callback :Function) :void
{
callEZCode("getFromCollection_v2", collName, count, msgOrPropName,
playerId, consume, callback);
}
/**
* Populate any properties or functions we want to expose to
* the other side of the ezgame security boundary.
@@ -658,7 +557,7 @@ public class EZGameControl extends EventDispatcher
/**
* Call a method across the security boundary.
*/
protected function callEZCode (name :String, ... args) :*
internal function callEZCode (name :String, ... args) :*
{
if (_funcs != null) {
try {
@@ -686,24 +585,15 @@ public class EZGameControl extends EventDispatcher
callEZCode("focusContainer_v1");
}
/**
* Secret function to dispatch property changed events.
*/
internal function dispatch (event :Event) :void
{
try {
super.dispatchEvent(event);
} catch (err :Error) {
trace("Error dispatching event to user game.");
trace(err.getStackTrace());
}
}
/** Contains the data properties shared by all players in the game. */
protected var _gameData :Object;
/** Contains functions exposed to us from the EZGame host. */
protected var _funcs :Object;
/** Sub-controls. */
protected var _collections :CollectionsControl;
protected var _seating :SeatingControl;
}
}
@@ -61,7 +61,7 @@ public class PlayersDisplay extends Sprite
maxWidth = label.textWidth + TEXTWIDTH_ADD;
}
var players :Array = _gameCtrl.getPlayers();
var players :Array = _gameCtrl.seating.getPlayerIds();
// create a label for each player
for each (var playerId :int in players) {
@@ -160,7 +160,7 @@ public class PlayersDisplay extends Sprite
*/
protected function displayCurrentTurn () :void
{
var idx :int = _gameCtrl.isInPlay() ? _gameCtrl.getPlayerPosition(_gameCtrl.getTurnHolder()) : -1;
var idx :int = _gameCtrl.isInPlay() ? _gameCtrl.seating.getPlayerPosition(_gameCtrl.getTurnHolder()) : -1;
for (var ii :int = 0; ii < _playerLabels.length; ii++) {
var label :TextField = (_playerLabels[ii] as TextField);
label.backgroundColor = getBackground(ii == idx);
@@ -0,0 +1,29 @@
package com.threerings.ezgame {
public class SeatingControl extends SubControl
{
public function SeatingControl (ctrl :EZGameControl)
{
super(ctrl);
}
/**
* Get the player's position (seated index), or -1 if not a player.
*/
public function getPlayerPosition (playerId :int) :int
{
return int(_ctrl.callEZCode("getPlayerPosition_v1", playerId));
}
/**
* Get all the players at the table, in their seated position.
* Absent players will be represented by a 0.
*/
public function getPlayerIds () :Array /* of playerId (int) */
{
return (_ctrl.callEZCode("getPlayers_v1") as Array);
}
// TODO: methods for allowing a player to pick a seat
}
}
@@ -0,0 +1,22 @@
package com.threerings.ezgame {
import flash.errors.IllegalOperationError;
/**
* Abstract base class. Do not instantiate.
*/
public class SubControl extends BaseControl
{
public function SubControl (ctrl :EZGameControl)
{
super();
if (ctrl == null || Object(this).constructor == SubControl) {
throw new IllegalOperationError("Abstract");
}
_ctrl = ctrl;
}
protected var _ctrl :EZGameControl;
}
}