diff --git a/src/as/com/threerings/ezgame/client/GameControlBackend.as b/src/as/com/threerings/ezgame/client/GameControlBackend.as index d3e2b28d..979df3eb 100644 --- a/src/as/com/threerings/ezgame/client/GameControlBackend.as +++ b/src/as/com/threerings/ezgame/client/GameControlBackend.as @@ -33,10 +33,8 @@ import flash.events.MouseEvent; import flash.display.DisplayObject; import flash.display.InteractiveObject; -import flash.utils.IExternalizable; import flash.utils.ByteArray; import flash.utils.Dictionary; -import flash.utils.getQualifiedSuperclassName; import com.threerings.io.TypedArray; @@ -46,6 +44,7 @@ import com.threerings.util.Integer; import com.threerings.util.Iterator; import com.threerings.util.MessageBundle; import com.threerings.util.Name; +import com.threerings.util.ObjectMarshaller; import com.threerings.util.StringUtil; import com.threerings.util.Wrapped; @@ -84,7 +83,6 @@ import com.threerings.ezgame.data.EZGameObject; import com.threerings.ezgame.data.PropertySetEvent; import com.threerings.ezgame.data.PropertySetListener; import com.threerings.ezgame.data.UserCookie; -import com.threerings.ezgame.util.EZObjectMarshaller; /** * Manages the backend of the game. @@ -248,7 +246,7 @@ public class GameControlBackend validateConnected(); validatePropertyChange(propName, value, index); - var encoded :Object = EZObjectMarshaller.encode(value, (index == -1)); + var encoded :Object = ObjectMarshaller.encode(value, (index == -1)); _ezObj.ezGameService.setProperty( _ctx.getClient(), propName, encoded, index, false, null, createLoggingConfirmListener("setProperty")); @@ -263,8 +261,8 @@ public class GameControlBackend validateConnected(); validatePropertyChange(propName, value, index); - var encodedValue :Object = EZObjectMarshaller.encode(value, (index == -1)); - var encodedTestValue :Object = EZObjectMarshaller.encode(testValue, (index == -1)); + var encodedValue :Object = ObjectMarshaller.encode(value, (index == -1)); + var encodedTestValue :Object = ObjectMarshaller.encode(testValue, (index == -1)); _ezObj.ezGameService.setProperty( _ctx.getClient(), propName, encodedValue, index, true, encodedTestValue, createLoggingConfirmListener("setProperty")); @@ -288,7 +286,7 @@ public class GameControlBackend validateName(messageName); validateValue(value); - var encoded :Object = EZObjectMarshaller.encode(value, false); + var encoded :Object = ObjectMarshaller.encode(value, false); _ezObj.ezGameService.sendMessage(_ctx.getClient(), messageName, encoded, playerId, createLoggingConfirmListener("sendMessage")); @@ -409,7 +407,7 @@ public class GameControlBackend var uc :UserCookie = (_ezObj.userCookies.get(playerId) as UserCookie); if (uc != null) { - callback(EZObjectMarshaller.decode(uc.cookie)); + callback(ObjectMarshaller.decode(uc.cookie)); return; } } @@ -434,7 +432,7 @@ public class GameControlBackend validateConnected(); validateValue(cookie); var ba :ByteArray = - (EZObjectMarshaller.encode(cookie, false) as ByteArray); + (ObjectMarshaller.encode(cookie, false) as ByteArray); if (ba.length > MAX_USER_COOKIE) { // not saved! return false; @@ -544,7 +542,7 @@ public class GameControlBackend validateValue(values); var encodedValues :TypedArray = - (EZObjectMarshaller.encode(values) as TypedArray); + (ObjectMarshaller.encode(values, true) as TypedArray); _ezObj.ezGameService.addToCollection( _ctx.getClient(), collName, encodedValues, clearExisting, @@ -721,47 +719,7 @@ public class GameControlBackend */ protected function validateValue (value :Object) :void { - if (value == null) { - return; - - } else if (value is IExternalizable) { - throw new ArgumentError( - "IExternalizable is not yet supported"); - - } else if (value is Array) { - if (ClassUtil.getClassName(value) != "Array") { - // We can't allow arrays to be serialized as IExternalizables - // because we need to know element values (opaquely) on the - // server. Also, we don't allow other types because we wouldn't - // create the right class on the other side. - throw new ArgumentError( - "Custom array subclasses are not supported"); - } - // then, continue on with the sub-properties check (below) - - } else { - var type :String = typeof(value); - if (type == "number" || type == "string" || type == "boolean" ) { - // kosher! - return; - } - if (value is ByteArray) { - return; // kosher - } - var clazz :Class = ClassUtil.getClass(value); - var clazzparentname :String = getQualifiedSuperclassName(clazz); - var rootclass :Boolean = (clazzparentname == null); - if (! rootclass) { - throw new ArgumentError( - "Non-simple properties may not be set."); - } - // fall through and verify the object's sub-properties - } - - // check sub-properties (of arrays and objects) - for each (var arrValue :Object in (value as Array)) { - validateValue(arrValue); - } + ObjectMarshaller.validateValue(value); } /** @@ -900,7 +858,7 @@ public class GameControlBackend if (EZGameObject.USER_MESSAGE == name) { var args :Array = event.getArgs(); callUserCode("messageReceived_v1", (args[0] as String), - EZObjectMarshaller.decode(args[1])); + ObjectMarshaller.decode(args[1])); } else if (EZGameObject.GAME_CHAT == name) { // this is chat send by the game, let's route it like @@ -925,7 +883,7 @@ public class GameControlBackend if (msgName == event.getName()) { var args :Array = event.getArgs(); callUserCode("messageReceived_v1", (args[0] as String), - EZObjectMarshaller.decode(args[1])); + ObjectMarshaller.decode(args[1])); } } @@ -940,7 +898,7 @@ public class GameControlBackend delete _cookieCallbacks[cookie.playerId]; for each (var fn :Function in arr) { try { - fn(EZObjectMarshaller.decode(cookie.cookie)); + fn(ObjectMarshaller.decode(cookie.cookie)); } catch (err :Error) { // cope } diff --git a/src/as/com/threerings/ezgame/data/EZGameConfig.as b/src/as/com/threerings/ezgame/data/EZGameConfig.as index df964ab9..f76c4024 100644 --- a/src/as/com/threerings/ezgame/data/EZGameConfig.as +++ b/src/as/com/threerings/ezgame/data/EZGameConfig.as @@ -35,7 +35,6 @@ import com.threerings.parlor.game.client.GameConfigurator; import com.threerings.parlor.game.data.GameConfig; import com.threerings.ezgame.client.EZGameController; -import com.threerings.ezgame.util.EZObjectMarshaller; /** * A game config for a simple multiplayer ez game. diff --git a/src/as/com/threerings/ezgame/data/EZGameObject.as b/src/as/com/threerings/ezgame/data/EZGameObject.as index 995579a5..248dcc0a 100644 --- a/src/as/com/threerings/ezgame/data/EZGameObject.as +++ b/src/as/com/threerings/ezgame/data/EZGameObject.as @@ -26,6 +26,7 @@ import flash.events.Event; import flash.utils.ByteArray; import com.threerings.util.Name; +import com.threerings.util.ObjectMarshaller; import com.threerings.io.ObjectInputStream; import com.threerings.io.ObjectOutputStream; @@ -36,8 +37,6 @@ import com.threerings.presents.dobj.DSet; import com.threerings.parlor.game.data.GameObject; import com.threerings.parlor.turn.data.TurnGameObject; -import com.threerings.ezgame.util.EZObjectMarshaller; - public class EZGameObject extends GameObject implements TurnGameObject { @@ -142,7 +141,7 @@ public class EZGameObject extends GameObject var count :int = ins.readInt(); while (count-- > 0) { var key :String = ins.readUTF(); - var value :Object = EZObjectMarshaller.decode(ins.readObject()); + var value :Object = ObjectMarshaller.decode(ins.readObject()); _props[key] = value; } } diff --git a/src/as/com/threerings/ezgame/data/PropertySetEvent.as b/src/as/com/threerings/ezgame/data/PropertySetEvent.as index 530e7d7c..c7d442c4 100644 --- a/src/as/com/threerings/ezgame/data/PropertySetEvent.as +++ b/src/as/com/threerings/ezgame/data/PropertySetEvent.as @@ -28,13 +28,12 @@ import com.threerings.io.ObjectInputStream; import com.threerings.io.ObjectOutputStream; import com.threerings.io.Streamer; +import com.threerings.util.ObjectMarshaller; import com.threerings.util.StringBuilder; import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.NamedEvent; -import com.threerings.ezgame.util.EZObjectMarshaller; - /** * Represents a property change on the actionscript object we * use in FlashGameObject. @@ -86,7 +85,7 @@ public class PropertySetEvent extends NamedEvent { super.readObject(ins); _index = ins.readInt(); - _data = EZObjectMarshaller.decode(ins.readObject()); + _data = ObjectMarshaller.decode(ins.readObject()); } // from interface Streamable diff --git a/src/as/com/threerings/ezgame/util/EZObjectMarshaller.as b/src/as/com/threerings/ezgame/util/EZObjectMarshaller.as deleted file mode 100644 index 42d58441..00000000 --- a/src/as/com/threerings/ezgame/util/EZObjectMarshaller.as +++ /dev/null @@ -1,97 +0,0 @@ -// -// $Id$ -// -// 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.util { - -import flash.net.ObjectEncoding; - -import flash.system.ApplicationDomain; - -import flash.utils.ByteArray; -import flash.utils.Endian; - -import com.threerings.io.TypedArray; - -/** - * Utility methods for transferring flash properties via - * the presents dobj system. - */ -public class EZObjectMarshaller -{ - /** - * Encode the specified object as either a byte[] or a byte[][] if it - * is an array. The specific mechanism of encoding is not important, - * as long as decode returns a clone of the original object. - * - * Currently, cycles in the object graph are preserved on the other end. - * TODO: serialize IExternalizable implementations, and take - * into account the ApplicationDomain. - */ - public static function encode ( - obj :Object, encodeArrayElements :Boolean = true) :Object - { - if (obj == null) { - return null; - } - if (encodeArrayElements && obj is Array) { - var src :Array = (obj as Array); - var dest :TypedArray = TypedArray.create(ByteArray); - for each (var o :Object in src) { - dest.push(encode(o, false)); - } - return dest; - } - - // TODO: Our own encoding, that takes into account - // the ApplicationDomain - var bytes :ByteArray = new ByteArray(); - bytes.endian = Endian.BIG_ENDIAN; - bytes.objectEncoding = ObjectEncoding.AMF3; - bytes.writeObject(obj); - return bytes; - } - - public static function decode (encoded :Object) :Object - { - if (encoded == null) { - return null; - } - if (encoded is TypedArray) { - var src :TypedArray = (encoded as TypedArray); - var dest :Array = []; - for each (var b :ByteArray in src) { - dest.push(decode(b)); - } - return dest; - } - var bytes :ByteArray = (encoded as ByteArray); - // re-set the position in case we're decoding the actual same byte - // array used to encode (and not a network reconstruction) - bytes.position = 0; - - // TODO: Our own decoding, that takes into account - // the ApplicationDomain - bytes.endian = Endian.BIG_ENDIAN; - bytes.objectEncoding = ObjectEncoding.AMF3; - return bytes.readObject(); - } -} -}