From ee871c3f2f8284f2bfcc930ba90c712d2459eb61 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Wed, 14 Feb 2007 23:50:33 +0000 Subject: [PATCH] Occupant events. Undocumented, I'm sure we'll change some things around soon. Fixed a few bugs, too. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@190 c613c5cb-e716-0410-b11b-feb51c14d237 --- src/as/com/threerings/ezgame/EZGameControl.as | 24 ++++++ .../threerings/ezgame/OccupantChangedEvent.as | 45 ++++++++++ .../ezgame/OccupantChangedListener.as | 9 ++ .../ezgame/client/GameControlBackend.as | 82 +++++++++++++++++-- 4 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 src/as/com/threerings/ezgame/OccupantChangedEvent.as create mode 100644 src/as/com/threerings/ezgame/OccupantChangedListener.as diff --git a/src/as/com/threerings/ezgame/EZGameControl.as b/src/as/com/threerings/ezgame/EZGameControl.as index c561fa1a..fb249ada 100644 --- a/src/as/com/threerings/ezgame/EZGameControl.as +++ b/src/as/com/threerings/ezgame/EZGameControl.as @@ -190,6 +190,13 @@ public class EZGameControl extends EventDispatcher StateChangedEvent.GAME_ENDED, scl.stateChanged, false, 0, true); } + if (obj is OccupantChangedListener) { + var ocl :OccupantChangedListener = (obj as OccupantChangedListener); + addEventListener(OccupantChangedEvent.OCCUPANT_ENTERED, ocl.occupantEntered, + false, 0, true); + addEventListener(OccupantChangedEvent.OCCUPANT_LEFT, ocl.occupantLeft, + false, 0, true); + } } /** @@ -216,6 +223,11 @@ public class EZGameControl extends EventDispatcher removeEventListener( StateChangedEvent.GAME_ENDED, scl.stateChanged); } + if (obj is OccupantChangedListener) { + var ocl :OccupantChangedListener = (obj as OccupantChangedListener); + removeEventListener(OccupantChangedEvent.OCCUPANT_ENTERED, ocl.occupantEntered); + removeEventListener(OccupantChangedEvent.OCCUPANT_LEFT, ocl.occupantLeft); + } } /** @@ -540,6 +552,7 @@ public class EZGameControl extends EventDispatcher o["gameDidStart_v1"] = gameDidStart_v1; o["gameDidEnd_v1"] = gameDidEnd_v1; o["dispatchEvent_v1"] = dispatch; + o["occupantChanged_v1"] = occupantChanged_v1; } /** @@ -584,6 +597,17 @@ public class EZGameControl extends EventDispatcher dispatch(new StateChangedEvent(StateChangedEvent.GAME_ENDED, this)); } + /** + * Private method to post a OccupantEvent. + */ + private function occupantChanged_v1 (occupantId :int, player :Boolean, enter :Boolean) :void + { + dispatch(new OccupantChangedEvent( + enter ? OccupantChangedEvent.OCCUPANT_ENTERED + : OccupantChangedEvent.OCCUPANT_LEFT, + this, occupantId, player)); + } + /** * Sets the properties we received from the EZ game framework * on the other side of the security boundary. diff --git a/src/as/com/threerings/ezgame/OccupantChangedEvent.as b/src/as/com/threerings/ezgame/OccupantChangedEvent.as new file mode 100644 index 00000000..e9521cce --- /dev/null +++ b/src/as/com/threerings/ezgame/OccupantChangedEvent.as @@ -0,0 +1,45 @@ +package com.threerings.ezgame { + +import flash.events.Event; + +public class OccupantChangedEvent extends EZEvent +{ + public static const OCCUPANT_ENTERED :String = "OccupantEntered"; + public static const OCCUPANT_LEFT :String = "OccupantLeft"; + + /** The occupantId of the occupant that entered or left. */ + public function get occupantId () :int + { + return _occupantId; + } + + /** Is/was the occupant a player? If false, they are/were a watcher. */ + public function get player () :Boolean + { + return _player; + } + + public function OccupantChangedEvent ( + type :String, ezgame :EZGameControl, occupantId :int, player :Boolean) + { + super(type, ezgame); + _occupantId = occupantId; + _player = player; + } + + override public function toString () :String + { + return "[OccupantChangedEvent type=" + type + + ", occupantId=" + _occupantId + + ", player=" + _player + "]"; + } + + override public function clone () :Event + { + return new OccupantChangedEvent(type, _ezgame, _occupantId, _player); + } + + protected var _occupantId :int; + protected var _player :Boolean; +} +} diff --git a/src/as/com/threerings/ezgame/OccupantChangedListener.as b/src/as/com/threerings/ezgame/OccupantChangedListener.as new file mode 100644 index 00000000..e76d4862 --- /dev/null +++ b/src/as/com/threerings/ezgame/OccupantChangedListener.as @@ -0,0 +1,9 @@ +package com.threerings.ezgame { + +public interface OccupantChangedListener +{ + function occupantEntered (event :OccupantChangedEvent) :void; + + function occupantLeft (event :OccupantChangedEvent) :void; +} +} diff --git a/src/as/com/threerings/ezgame/client/GameControlBackend.as b/src/as/com/threerings/ezgame/client/GameControlBackend.as index 843e7567..9a1591c0 100644 --- a/src/as/com/threerings/ezgame/client/GameControlBackend.as +++ b/src/as/com/threerings/ezgame/client/GameControlBackend.as @@ -32,18 +32,26 @@ import com.threerings.presents.client.ResultWrapper; import com.threerings.presents.client.InvocationService_ConfirmListener; import com.threerings.presents.client.InvocationService_ResultListener; +import com.threerings.presents.dobj.ElementUpdateListener; +import com.threerings.presents.dobj.ElementUpdatedEvent; import com.threerings.presents.dobj.EntryAddedEvent; import com.threerings.presents.dobj.EntryRemovedEvent; import com.threerings.presents.dobj.EntryUpdatedEvent; -import com.threerings.presents.dobj.SetListener; import com.threerings.presents.dobj.MessageAdapter; import com.threerings.presents.dobj.MessageEvent; import com.threerings.presents.dobj.MessageListener; +import com.threerings.presents.dobj.ObjectAddedEvent; +import com.threerings.presents.dobj.ObjectRemovedEvent; +import com.threerings.presents.dobj.OidListListener; +import com.threerings.presents.dobj.SetListener; import com.threerings.crowd.data.BodyObject; import com.threerings.crowd.data.OccupantInfo; +import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.util.CrowdContext; +import com.threerings.parlor.game.data.GameObject; + import com.threerings.ezgame.data.EZGameObject; import com.threerings.ezgame.data.PropertySetEvent; import com.threerings.ezgame.data.PropertySetListener; @@ -54,7 +62,8 @@ import com.threerings.ezgame.util.EZObjectMarshaller; * Manages the backend of the game. */ public class GameControlBackend - implements MessageListener, SetListener, PropertySetListener + implements MessageListener, SetListener, ElementUpdateListener, + PropertySetListener { public var log :Log = Log.getLog(this); @@ -225,6 +234,10 @@ public class GameControlBackend public function getPlayers_v1 () :Array { + if (_ezObj.players.length == 0) { + // party game + return getOccupants_v1(); + } var playerIds :Array = []; for (var ii :int = 0; ii < _ezObj.players.length; ii++) { var occInfo :OccupantInfo = _ezObj.getOccupantInfo(_ezObj.players[ii] as Name); @@ -253,7 +266,7 @@ public class GameControlBackend if (occInfo == null) { return -1; } - return ArrayUtil.indexOf(_ezObj.players, occInfo.username); + return _ezObj.getPlayerIndex(occInfo.username); } // TODO: table only @@ -608,23 +621,69 @@ public class GameControlBackend // from SetListener public function entryAdded (event :EntryAddedEvent) :void { - if (EZGameObject.USER_COOKIES == event.getName()) { + var name :String = event.getName(); + switch (name) { + case EZGameObject.USER_COOKIES: receivedUserCookie(event.getEntry() as UserCookie); + break; + + case PlaceObject.OCCUPANT_INFO: + var occInfo :OccupantInfo = (event.getEntry() as OccupantInfo) + callUserCode("occupantChanged_v1", occInfo.bodyOid, isPlayer(occInfo.username), true); + break; } } // from SetListener public function entryUpdated (event :EntryUpdatedEvent) :void { - if (EZGameObject.USER_COOKIES == event.getName()) { + var name :String = event.getName(); + switch (name) { + case EZGameObject.USER_COOKIES: receivedUserCookie(event.getEntry() as UserCookie); + break; } } // from SetListener public function entryRemoved (event :EntryRemovedEvent) :void { - // nada + var name :String = event.getName(); + switch (name) { + case PlaceObject.OCCUPANT_INFO: + var occInfo :OccupantInfo = (event.getOldEntry() as OccupantInfo) + callUserCode("occupantChanged_v1", occInfo.bodyOid, isPlayer(occInfo.username), false); + break; + } + } + + // from ElementUpdateListener + public function elementUpdated (event :ElementUpdatedEvent) :void + { + var name :String = event.getName(); + if (name == GameObject.PLAYERS) { + var oldPlayer :Name = (event.getOldValue() as Name); + var newPlayer :Name = (event.getValue() as Name); + var occInfo :OccupantInfo; + if (oldPlayer != null) { + occInfo = _ezObj.getOccupantInfo(oldPlayer); + if (occInfo != null) { + // old player became a watcher + // send player-left, then occupant-added + callUserCode("occupantChanged_v1", occInfo.bodyOid, true, false); + callUserCode("occupantChanged_v1", occInfo.bodyOid, false, true); + } + } + if (newPlayer != null) { + occInfo = _ezObj.getOccupantInfo(newPlayer); + if (occInfo != null) { + // watcher became a player + // send occupant-left, then player-added + callUserCode("occupantChanged_v1", occInfo.bodyOid, false, false); + callUserCode("occupantChanged_v1", occInfo.bodyOid, true, true); + } + } + } } // from PropertySetListener @@ -690,6 +749,17 @@ public class GameControlBackend } } + /** + * Given the specified occupant name, return if they are a player. + */ + protected function isPlayer (occupantName :Name) :Boolean + { + if (_ezObj.players.length == 0) { + return true; // party game: all occupants are players + } + return (-1 == _ezObj.getPlayerIndex(occupantName)); + } + protected var _ctx :CrowdContext; protected var _userListener :MessageAdapter =