Add visitor pattern to crafting nodes

This commit is contained in:
Andrew Miner
2015-08-28 19:16:12 -07:00
parent badb854107
commit f6b71c9464
7 changed files with 203 additions and 91 deletions
@@ -29,6 +29,24 @@ module.exports = class CraftingNode
queue.push child queue.push child
return queue return queue
acceptVisitor: (visitor)->
enter = visitor[@ENTER_METHOD]
if enter?
enter.call visitor, this
else
enter = visitor['onEnterOtherNode']
if enter? then enter.call visitor, this
for child in @_children
child.acceptVisitor visitor
leave = visitor[@LEAVE_METHOD]
if leave?
leave.call visitor, this
else
leave = visitor['onLeaveOtherNode']
if leave? then leave.call visitor, this
# Property Methods ############################################################################# # Property Methods #############################################################################
getChildren: -> getChildren: ->
@@ -12,6 +12,9 @@ ItemNode = require './item_node'
module.exports = class InventoryNode extends CraftingNode module.exports = class InventoryNode extends CraftingNode
@::ENTER_METHOD = 'onEnterInventoryNode'
@::LEAVE_METHOD = 'onLeaveInventoryNode'
constructor: (options={})-> constructor: (options={})->
if not options.inventory? then throw new Error 'options.inventory is required' if not options.inventory? then throw new Error 'options.inventory is required'
super options super options
@@ -38,10 +41,14 @@ module.exports = class InventoryNode extends CraftingNode
# Object Overrides ############################################################################# # Object Overrides #############################################################################
toString: (indent='')-> toString: (options={})->
options.indent ?= ''
options.recursive ?= true
completeText = if @complete then 'complete' else 'incomplete' completeText = if @complete then 'complete' else 'incomplete'
parts = ["#{indent}#{@completeText} InventoryNode for #{@inventory}"] parts = ["#{options.indent}#{@completeText} InventoryNode for #{@inventory}"]
nextIndent = indent + ' ' nextIndent = options.indent + ' '
for child in @children if options.recursive
parts.push child.toString nextIndent for child in @children
parts.push child.toString indent:nextIndent
return parts.join '\n' return parts.join '\n'
+12 -5
View File
@@ -12,6 +12,9 @@ RecipeNode = require './recipe_node'
module.exports = class ItemNode extends CraftingNode module.exports = class ItemNode extends CraftingNode
@::ENTER_METHOD = 'onEnterItemNode'
@::LEAVE_METHOD = 'onLeaveItemNode'
constructor: (options={})-> constructor: (options={})->
if not options.item? then throw new Error 'options.item is required' if not options.item? then throw new Error 'options.item is required'
super options super options
@@ -60,10 +63,14 @@ module.exports = class ItemNode extends CraftingNode
# Object Overrides ############################################################################# # Object Overrides #############################################################################
toString: (indent)-> toString: (options={})->
options.indent ?= ''
options.recursive ?= true
completeText = if @complete then 'complete' else 'incomplete' completeText = if @complete then 'complete' else 'incomplete'
parts = ["#{indent}#{@completeText} ItemNode for #{@item.name}"] parts = ["#{options.indent}#{@completeText} ItemNode for #{@item.name}"]
nextIndent = indent + ' ' nextIndent = options.indent + ' '
for child in @children if options.recursive
parts.push child.toString nextIndent for child in @children
parts.push child.toString indent:nextIndent
return parts.join '\n' return parts.join '\n'
+12 -5
View File
@@ -12,6 +12,9 @@ CraftingNode = require './crafting_node'
module.exports = class RecipeNode extends CraftingNode module.exports = class RecipeNode extends CraftingNode
@::ENTER_METHOD = 'onEnterRecipeNode'
@::LEAVE_METHOD = 'onLeaveRecipeNode'
constructor: (options={})-> constructor: (options={})->
if not options.recipe? then throw new Error 'options.recipe is required' if not options.recipe? then throw new Error 'options.recipe is required'
super options super options
@@ -52,10 +55,14 @@ module.exports = class RecipeNode extends CraftingNode
# Object Overrides ############################################################################ # Object Overrides ############################################################################
toString: (indent)-> toString: (options={})->
options.indent ?= ''
options.recursive ?= true
completeText = if @complete then 'complete' else 'incomplete' completeText = if @complete then 'complete' else 'incomplete'
parts = ["#{indent}#{@completeText} RecipeNode for #{@recipe.slug}"] parts = ["#{options.indent}#{@completeText} RecipeNode for #{@recipe.slug}"]
nextIndent = indent + ' ' nextIndent = options.indent + ' '
for child in @children if options.recursive
parts.push child.toString nextIndent for child in @children
parts.push child.toString indent:nextIndent
return parts.join '\n' return parts.join '\n'
+44
View File
@@ -0,0 +1,44 @@
###
Crafting Node - crafting_node.test.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
fixtures = require './fixtures'
########################################################################################################################
root = null
########################################################################################################################
describe 'crafting_node.coffee', ->
describe 'acceptVisitor', ->
it 'can provide a prefix, depth-first traversal', ->
root = fixtures.makeTree 'test__iron_ingot'
visitor =
nodes: []
onEnterOtherNode: (node)-> visitor.nodes.push node
root.acceptVisitor visitor
(v.constructor.name.replace('Node', '') for v in visitor.nodes).should.eql [
"Inventory", "Item", "Recipe", "Item", "Item", "Recipe", "Item", "Item", "Recipe", "Item", "Item"
]
it 'can provide a postfix, depth-first traversal', ->
root = fixtures.makeTree 'test__iron_ingot'
visitor =
nodes: []
onLeaveOtherNode: (node)-> visitor.nodes.push node
root.acceptVisitor visitor
(n.constructor.name.replace('Node', '') for n in visitor.nodes).should.eql [
"Item", "Item", "Item", "Recipe", "Item", "Recipe", "Item", "Item", "Recipe", "Item", "Inventory"
]
+102
View File
@@ -0,0 +1,102 @@
###
Crafting Guide - sample_modpack.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
GraphBuilder = require '../../src/coffee/models/crafting/graph_builder'
ItemSlug = require '../../src/coffee/models/item_slug'
Mod = require '../../src/coffee/models/mod'
ModPack = require '../../src/coffee/models/mod_pack'
ModVersion = require '../../src/coffee/models/mod_version'
########################################################################################################################
MOD_VERSION_FILE =
"""
schema: 1
item: Charcoal
recipe:
input: 8 Oak Wood, Coal
pattern: .0. ... .1.
item: Crafting Table
recipe:
input: Oak Planks
pattern: .00 .00 ...
item: Coal
item: Cobblestone
item: Furnace
recipe:
input: Cobblestone
pattern: 000 0.0 000
tools: Crafting Table
item: Iron Ore
item: Iron Ingot
recipe:
input: 8 Iron Ore, Charcoal
pattern: .0. ... .1.
tools: Furnace
recipe:
input: 8 Iron Ore, Coal
pattern: .0. ... .1.
tools: Furnace
item: Iron Sword
recipe:
input: Iron Ingot, Stick
pattern: .0. .0. .1.
tools: Crafting Table
item: Lever
recipe:
input: Stick, Cobblestone
pattern: .0. .1. ...
item: Oak Planks
recipe:
input: Oak Wood
pattern: ... .0. ...
quantity: 4
item: Oak Wood
item: Stick
recipe:
input: Oak Planks
pattern: .0. .0. ...
quantity: 4
"""
########################################################################################################################
module.exports = fixtures =
makeModPack: ->
modPack = new ModPack
mod = new Mod name:'Test', slug:'test'
modPack.addMod mod
modVersion = new ModVersion modSlug:'test', version:'0.0'
modVersion.parse MOD_VERSION_FILE
mod.addModVersion modVersion
return modPack
makeGraphBuilder: ->
return new GraphBuilder modPack:fixtures.makeModPack()
makeTree: (itemSlug)->
builder = fixtures.makeGraphBuilder()
builder.wanted.add ItemSlug.slugify itemSlug
builder.expandGraph()
return builder.rootNode
+3 -76
View File
@@ -5,92 +5,19 @@ Copyright (c) 2015 by Redwood Labs
All rights reserved. All rights reserved.
### ###
GraphBuilder = require '../../src/coffee/models/crafting/graph_builder' fixtures = require './fixtures'
ItemSlug = require '../../src/coffee/models/item_slug' ItemSlug = require '../../src/coffee/models/item_slug'
Mod = require '../../src/coffee/models/mod'
ModPack = require '../../src/coffee/models/mod_pack'
ModVersion = require '../../src/coffee/models/mod_version'
######################################################################################################################## ########################################################################################################################
SAMPLE_MOD_VERSION_TEXT = """ builder = null
schema: 1
item: Charcoal
recipe:
input: 8 Oak Wood, Coal
pattern: .0. ... .1.
item: Crafting Table
recipe:
input: Oak Planks
pattern: .00 .00 ...
item: Coal
item: Cobblestone
item: Furnace
recipe:
input: Cobblestone
pattern: 000 0.0 000
tools: Crafting Table
item: Iron Ore
item: Iron Ingot
recipe:
input: 8 Iron Ore, Charcoal
pattern: .0. ... .1.
tools: Furnace
recipe:
input: 8 Iron Ore, Coal
pattern: .0. ... .1.
tools: Furnace
item: Iron Sword
recipe:
input: Iron Ingot, Stick
pattern: .0. .0. .1.
tools: Crafting Table
item: Lever
recipe:
input: Stick, Cobblestone
pattern: .0. .1. ...
item: Oak Planks
recipe:
input: Oak Wood
pattern: ... .0. ...
quantity: 4
item: Oak Wood
item: Stick
recipe:
input: Oak Planks
pattern: .0. .0. ...
quantity: 4
"""
builder = mod = modPack = modVersion = null
######################################################################################################################## ########################################################################################################################
describe 'GraphBuilder.coffee', -> describe 'GraphBuilder.coffee', ->
beforeEach -> beforeEach ->
modPack = new ModPack builder = fixtures.makeGraphBuilder()
mod = new Mod name:'Test', slug:'test'
modPack.addMod mod
modVersion = new ModVersion modSlug:'test', version:'0.0'
modVersion.parse SAMPLE_MOD_VERSION_TEXT
mod.addModVersion modVersion
builder = new GraphBuilder modPack:modPack
describe 'expand', -> describe 'expand', ->