Continuities/adarkroom — pull request #50 by LucidCrux (2013-07-28 00:16:28+00:00)
Title: State manager 2

Hopefully working and ready to go. More bug hunting may be needed though, I just did one debug enabled run.

I know I add a lot of comments, hopefully this isn't a bad thing for anyone.

Some things I wanted to accomplish and things to think about when using or reworking the $SM:
1.) Try to "think globaly" for states. For example, buildings may be used by other future locations or referenced in events, same with population, workers, builder level, perks, punches, etc.

2.) game.. try to only use this for things that probably won't be called or used by other locations but still need saved, things like game.outside.seenForest, and game.spaceShip.seenWarning.

3.) Don't use states for variables that should be location properties and there is little to no benefit in saving them. This is an extension of the above. Room.fire, Room.temperature are examples. If later on someone does want to hook into them or they need saved, they can be made into states. But states have a lot more overhead than object properties in order to ensure save integrity.

4.) States should NOT rely on location functions or data. Again, a reason Room.fire/temperature were not good candidates. If a state cannot function or be properly set without location code, something needs fixed so that it can. States should be stand-alone data, not functions or objects. How a location uses that data should be determined by the location itself.

5.) Try to write for states so that modification by another location will not break the game. Room code for game.builder.level (formerly room.builder) is a good example of how to do this. The final comparison check is for builder.level > 4. This means if another location takes builder development further, there should be far less chance of Room breaking because of it.

6.) It might be good to come up with some kind of State declaration standardization. Something like listing states used/created/whatever in the file header. It would make it easier for developers to search for possible collision, naming, and redundancy issues.

Below is the very long summary of what was changed in case you don't want to look at individual commits.

Added StateManager or $SM to handle all getting and setting of State properties

State Updated to 1.3

Added $.Dispatch to handle object level events, enabling State change listening

=================================

refactor Outside.js to use the $SM

====state changes====
//these were changed for the opposite reason the Room states were. These seem like states that other locations and events may very well want to interact with and possibly alter themselves
game.outside.buildings >> game.buildings
game.outside.population >> game.population
game.outside.workders >> game.workers

====functions removed====
Outside.numBuilding // just a $SM.get, no shortcut really needed since Outside.numBuilding is a pretty long name
Outside.getPopulation // same here
Outside.addBuilding // just an add
Outside.addBuildings // just addM, but wasn't even actually used

====functions refactored====
Outside.killVillagers //moved updates to handler
Outside.updateWorkersView //added local to reduce gets
Outside.increasePopulation //updates moved to handler
Outside.increaseWorker // updates moved to handler
Outside.decreaseWorkder // updates moved to handler

=========================================

=========================================

refactor Room.js for use the $SM

====state changes====
game.room.fire >> changed to property Room.fire //only used by Room, no reason to save it
game.room.tempurature >> changed to property Room.tempurature //only used by Room, no reason to save it
**You always load into 'a dark room' now, kind of fitting right?
game.room.buttons >> changed to property Room.buttons //only used by Room, easily rebuilt on load with no code changes
game.room.builder >> game.builder.level

====functions refactored====
Room.unlockForext //remove update calls
Room.buy //remove update calls
Room.build //remove update calls
Room.cooFire //added locals to reduce gets
Room.adjustTemp //added locals to reduce gets
Room.updateBuilderState //added local to reduce gets
Room.craftUnlocked //Room unlock is always going to be true, don't need to check parents to avoid errors anymore
Room.buyUnlocked //Room unlock is always going to be true, don't need to check parents to avoid errors anymore

=========================================

=========================================

refactor Engine.js for use with $SM

====functions removed====
//I just removed these because most were simpler or at least equal as	direct $SM get/set/add calls, I realize the store ones are kind of subjective since calls were about equal, but oh well. If someone really feels we need the shortcut/named functions for manipulating	stores specifically, it shouldn't be crazy to reimplement in $SM
Engine.setStore >> $SM.set
Engine.setStores >> $SM.setM
Engine.addStore >> $SM.add
Engine.addStores >> $SM.addM
Engine.getStore >> $SM.get(requestZero = true)
Engine.storeAvailable >> $SM.get;
Engine.removeIncome >> $SM.remove //updates moved to handler

====functions moved====
//Any moved function I felt was more directly related to States or	didn't belong where it was
Engine.addPerk > $SM.addPerk //kept function for now because of notify	call inside, 'deep' state
Engine.hasPerk > $SM.hasPerk //kept function because of 'deep' state	name
Engine.setIncome > $SM.setIncome //kept because it has internal logic
**Engine.getIncome > $SM.getIncome //**easily removable with	Outside.updateVillageIncome refactor
Engine.openPath > Path.openPath //Since I'm refactoring anyways
Engine.addStolen > $SM.addStolen //internal logic
Engine.startThieves > $SM.startThieves //not sure $SM is a better place, but Engine should be nice and clean by the end of this, handling only engine mechanics
Engine.num > $SM.num //after Outside refacter, this is basically just a fancy $SM.get
Engine.upgradeState > $SM.updateOldState

====functions refactored====
$SM.addPerk; //updates moved to event handler, no check/create new perk
$SM.hasPerk; //don't need to check exist and ==true
$SM.collectIncome //removed changed check, update calls now handled by	'stateUpdate' event listening
$SM.addStolen //fix to set stolen items in case a partial steal happens
$SM.startThieves //updates in handler
$SM.updateOldState //use $SM calls, add placeholder for updating to post $SM state when more finalized

====functions affected (by removed)====
Engine.init (Engine.getStore, Engine.storeAvailable)
Engine.collectIncome (Engine.addStores)
Engine.num (Engine.getStore)
Engine.travelTo (Engine.storeAvailable)

Room.init (Engine.getStore)
Room.unlockForest (Engine.setStore)
Room.lightFire (Engine.setStore, Engine.getStore, Engine.storeAvailable)
Room.stokeFire (Engine.setStore, Engine.getStore, Engine.storeAvailable)
Room.coolFire (Engine.setStore)
Room.buy (Engine.setStores, Engine.addStore, Engine.getStore)
Room.build (Engine.setStores, Engine.getStore)
Room.craftUnlocked (Engine.getStore, Engine.storeAvailable)
Room.buyUnlocked (Engine.storeAvailable)
Room.updateButton (Engine.storeAvailable)

Outside.gatherWood (Engine.addStores)
Outside.checkTraps (Engine.addStores, Engine.getStore)
Outside.updateVillage (Engine.getStore)

Path.embark (Engine.addStore)
Path.getCapacity (Engine.getStore)
Path.updateOutfitting (Engine.getStore)
Path.createOutfittingRow (Engine.getStore)
Path.increaseSupply (Engine.getStore)

World.goHome (Engine.addStore)
World.updateSupplies (Engine.getStore)
World.checkDanger (Engine.getStore)
World.getMaxHealth (Engine.getStore)
World.getMaxWater (Engine.getStore)

Ship.reinforceHull (Engine.addStore, Engine.getStore)
Ship.upgradeEngine (Engine.addStore, Engine.getStore)

Events.loadScene (Engine.addStores)
Events.updateButtons (Engine.getStore)
Events.buttonClick (Engine.getStore)

Events.Global (Engine.addStores, Engine.removeIncome)
Events.Room (Engine.addStore, Engine.addStores, Engine.getStore, Engine.storeAvailable)

=========================================

=========================================

The changes to states are as follows:

.room (exists) > features.location.room
.room > game.room
.room.builder > game.room.builder > game.builder.level
.room.temperature > game.room.temperature > Room.temperature (not a state)
.room.fire > game.room.fire > Room.fire (not a state)
.room.buttons > game.room.buttons > Room.buttons (not a state)

.outside (exists) > features.location.outside
.outside > game.outside
.outside.population > game.outside.population
.outside.buildings > game.outside.buildings
.outside.workers > game.outside.workers
.outside.seenForest > game.outside.seenForest

.world (exists) > features.location.world
.world > game.world
.world.map > game.world.map
.world.mask > game.world.mask
.starved > character.starved
.dehydrated > character.dehydrated

.ship (exists) > featuers.location.spaceShip
.ship > game.spaceShip
.ship.hull > game.spaceShip.hull
.ship.thrusters > game.spaceShip.thrusters
.ship.seenWarning > game.spaceShip.seenWarning
.ship.seenShip > game.spaceShip.seenShip

.punches > character.punches
.perks > character.perks

.thieves > game.thieves
.stolen > game.stolen
.cityCleared > game.cityCleared

.stores > stores
.income > income