Created
August 17, 2011 22:28
-
-
Save amacdougall/1152808 to your computer and use it in GitHub Desktop.
Model.as, setValue refactoring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sets the value targeted by the key to the value. Only handles key formats | |
* that have been seen "in the wild," but adding new ones is a cinch. Known | |
* formats so far: | |
* | |
* event | |
* event.card | |
* event.card.fonts | |
* event.card.sides.0.assets.0.propertyName | |
* event.card.side(paper,front,0).assets | |
* event.card.side(paper,front,0).asset(123abc) | |
* event.card.side(paper,front,0).asset(123abc).propertyName | |
* | |
* @param key The target path of the asset to be set, in one of the formats | |
* listed above. | |
* @param value The value to be set. May be any value JSON value. | |
* @param callback The ExternalInterface function to be called on completion. | |
* @param onRendered The ExternalInterface function to be called when rendered. | |
* | |
* @throws ArgumentError if no handler was ultimately found for the key. | |
*/ | |
public function setValue_experimental(key:String, value:*, callback:String = null, onRendered:String=null):void | |
{ | |
Debug.log("Model.setValue_experimental(): " + key + " -> " + JSON.encode(value)); | |
Debug.indent(); | |
/** | |
* With a key and an array of {pattern: RegExp, handler: Function} | |
* objects, call the handler function associated with the first | |
* matching regex pattern. | |
*/ | |
function callMatchingHandler(key:String, mappings:Array):void { | |
var patternsTested:Array = []; | |
for each (var mapping:Object in mappings) { | |
if (mapping.pattern.test(key)) { | |
mapping.handler(); | |
return; | |
} else { | |
patternsTested.push(mapping.pattern); | |
} | |
} | |
// if no successful match caused a return from this function... | |
Debug.unindent(); | |
throw new ArgumentError("Model.setValue: found no matching handler for key \"" + key + "\"\n" + | |
"Patterns tested:\n" + patternsTested.join("\n")); | |
} | |
if (key.match(/^event\.card\.side/)) { | |
// define side variable if the key refers to one | |
var side:Side = null; | |
if (key.match(/^event\.card\.sides\.\d+/)) { | |
var sideIndexPattern:RegExp = /^event\.card\.sides\.(\d+)/; | |
var sideIndex:int = parseInt(key.match(sideIndexPattern)[1]); | |
side = event.card.sides[sideIndex]; | |
} else if (key.match(/^event\.card\.side\(/)) { | |
var sideArgumentsPattern:RegExp = /^event\.card\.side\((\w+,\w+,\d+)\)/; | |
var sideArguments:Array = key.match(sideArgumentsPattern)[1].split(","); | |
side = event.card.side.apply(side, sideArguments); | |
} | |
if (!side) { | |
Debug.unindent(); | |
throw new Error("Unable to find a side with arguments " + sideArguments.join(",")); | |
} | |
} | |
if (key.match(/\.asset(s\.\d+|\()/)) { // e.g. ".assets.2" or ".asset(" | |
var asset:Asset = null; | |
// define asset varaible if the key refers to one | |
if (key.match(/\.assets\.\d+\.\w+$/)) { | |
var assetIndexPattern:RegExp = /^event\.card\.sides\.\d+\.assets\.(\d+)/; | |
var assetIndex:int = parseInt(key.match(assetIndexPattern)[1]); | |
asset = side.assets[assetIndex]; | |
} else if (key.match(/\.asset\(\w+\)/)) { | |
var uuid:String = key.match(/\.asset\((\w+)\)/)[1]; | |
asset = side.asset(uuid); | |
} | |
if (!asset) { | |
Debug.unindent(); | |
throw new Error("Unable to find an asset with uuid " + uuid); | |
} | |
} | |
callMatchingHandler(key, [ | |
// e.g.: "event" | |
{ pattern: /^event$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern /^event$/"); | |
event.updateData(value); | |
PP.instance.cache.create_version = value.create_version; | |
_lastJSONModel = JSON.encode(event); | |
/* If this is the first setValue call, _firstData will be false | |
* and we'll wait for JS to send an update call. Otherwise, | |
* fire Event.INIT. | |
*/ | |
// TODO: rename to hasReceivedData or something. | |
if (_firstData) { | |
Debug.log("Model.setValue(): Dispatching Event.INIT"); | |
dispatchEvent(new Event(Event.INIT)); | |
} else { | |
_firstData = true; | |
} | |
} | |
}, | |
// e.g.: "event.card" | |
{ pattern: /^event\.card$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern /^event\\.card$/"); | |
event.card.updateData(value); | |
/* If this is the first setValue call, _firstData will be false | |
* and we'll wait for JS to send an update call. Otherwise, | |
* fire Event.INIT. | |
*/ | |
// TODO: rename to hasReceivedData or something. | |
if (_firstData) { | |
Debug.log("Model.setValue(): Dispatching Event.INIT"); | |
dispatchEvent(new Event(Event.INIT)); | |
} else { | |
_firstData = true; | |
} | |
} | |
}, | |
// e.g.: "event.card.fonts" | |
{ pattern: /^event\.card\.fonts$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern /^event\\.card\\.fonts$/"); | |
event.card.fonts = value; | |
if (!app.rendering) { | |
PP.instance.cache.fontsChanged = true; | |
} | |
} | |
}, | |
// e.g.: "event.card.sides.0.assets.0.asset" | |
// "event.card.sides.0.assets.2.image_url" | |
{ pattern: /^event\.card\.sides\.\d+\.assets\.\d+\.\w+$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern " + | |
"/^event\\.card\\.sides\\.\\d+\\.assets\\.\\d+\\.\\w+$/"); | |
var propertyName:String = key.match(/\w+$/)[0]; | |
if (propertyName == "color") { | |
asset[propertyName] = int(value); | |
} else { | |
asset[propertyName] = value; | |
} | |
invalidate([asset]); | |
} | |
}, | |
// e.g.: "event.card.side(paper,front,0).assets" | |
{ pattern: /^event\.card\.side\(\w+,\w+,\d+\)\.assets$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern " + | |
"/^event\\.card\\.side\\(\\w+,\\w+,\\d+\\)\\.assets$/"); | |
side.updateAssets(value); | |
invalidate(side.assets); | |
} | |
}, | |
// e.g.: "event.card.side(paper,front,0).asset(123456abcdef)" | |
{ pattern: /^event\.card\.side\(\w+,\w+,\d+\)\.asset\(\w+\)$/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern " + | |
"/^event\\.card\\.side\\(\\w+,\\w+,\\d+\\)\\.asset\\(\\w+\\)$/"); | |
asset.updateData(value); | |
invalidate([asset]); | |
} | |
}, | |
// e.g.: "event.card.side(paper,front,0).asset(123456abcdef).color" | |
{ pattern: /^event\.card\.side\(\w+,\w+,\d+\)\.asset\(\w+\)\.\w+/, | |
handler: function():void { | |
Debug.log("Handling \"" + key + "\" with pattern " + | |
"/^event\\.card\\.side\\(\\w+,\\w+,\\d+\\)\\.asset\\(\\w+\\)\\.\\w+/"); | |
var propertyName:String = key.match(/\w+$/)[0]; | |
if (propertyName == "color") { | |
asset[propertyName] = parseInt(value); | |
} else { | |
asset[propertyName] = value; | |
} | |
invalidate([asset]); | |
} | |
} | |
]); | |
app.rendering = false; | |
callback && ExternalInterface.call(callback); // needs no arguments, says William C. | |
onRendered && _callbacks.push(onRendered); | |
Debug.unindent(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment