From d94bd39e528e351d8e8358a678ecf6327143f2b7 Mon Sep 17 00:00:00 2001 From: Andrew Miner Date: Thu, 15 Jan 2015 17:12:12 -0800 Subject: [PATCH] Refactor the SAYT code to return better results --- .../controllers/inventory_controller.coffee | 9 ++- .../controllers/item_page_controller.coffee | 5 +- src/scripts/models/mod_pack.coffee | 15 ---- src/scripts/models/mod_version.coffee | 16 ---- src/scripts/models/name_finder.coffee | 79 +++++++++++++++++++ test/mod_pack.test.coffee | 27 ------- test/mod_version.test.coffee | 21 ----- 7 files changed, 87 insertions(+), 85 deletions(-) create mode 100644 src/scripts/models/name_finder.coffee diff --git a/src/scripts/controllers/inventory_controller.coffee b/src/scripts/controllers/inventory_controller.coffee index 345e640b9..669215c70 100644 --- a/src/scripts/controllers/inventory_controller.coffee +++ b/src/scripts/controllers/inventory_controller.coffee @@ -9,6 +9,7 @@ BaseController = require './base_controller' {Duration} = require '../constants' {Key} = require '../constants' ImageLoader = require './image_loader' +NameFinder = require '../models/name_finder' StackController = require './stack_controller' ######################################################################################################################## @@ -21,10 +22,10 @@ module.exports = class InventoryController extends BaseController if not options.model? then throw new Error 'options.model is required' if not options.modPack? then throw new Error 'options.modPack is required' - options.icon ?= '/images/chest_front.png' options.editable ?= true + options.nameFinder ?= new NameFinder options.modPack + options.icon ?= '/images/chest_front.png' options.imageLoader ?= new ImageLoader defaultUrl:'/images/unknown.png' - options.gatherNames ?= -> @modPack.gatherNames() options.title ?= 'Inventory' options.templateName = 'inventory' @@ -34,7 +35,7 @@ module.exports = class InventoryController extends BaseController @icon = options.icon @imageLoader = options.imageLoader @modPack = options.modPack - @gatherNames = options.gatherNames + @nameFinder = options.nameFinder @title = options.title @_stackControllers = [] @@ -173,7 +174,7 @@ module.exports = class InventoryController extends BaseController onSelected = => @onItemSelected() @$nameField.autocomplete - source: @gatherNames() + source: (request, callback)=> callback @nameFinder.search request.term delay: 0 minLength: 0 change: onChanged diff --git a/src/scripts/controllers/item_page_controller.coffee b/src/scripts/controllers/item_page_controller.coffee index b9a8e44c7..7f6932637 100644 --- a/src/scripts/controllers/item_page_controller.coffee +++ b/src/scripts/controllers/item_page_controller.coffee @@ -11,6 +11,7 @@ ImageLoader = require './image_loader' InventoryController = require './inventory_controller' ItemPage = require '../models/item_page' ModPackController = require './mod_pack_controller' +NameFinder = require '../models/name_finder' ######################################################################################################################## @@ -45,7 +46,7 @@ module.exports = class ItemPageController extends BaseController imageLoader: @imageLoader model: @model.plan.have modPack: @model.modPack - gatherNames: -> @modPack.gatherNames includeGatherable:true + nameFinder: new NameFinder @model.modPack, includeGatherable:true title: 'Items you have' @needController = @addChild InventoryController, '.need', @@ -63,7 +64,7 @@ module.exports = class ItemPageController extends BaseController @modPackController = @addChild ModPackController, '.view__mod_pack', model:@model.modPack - @$('.want .toolbar').append '' @$includeToolsBox = @$('.includeTools') super diff --git a/src/scripts/models/mod_pack.coffee b/src/scripts/models/mod_pack.coffee index 787ab62ae..54dcab29c 100644 --- a/src/scripts/models/mod_pack.coffee +++ b/src/scripts/models/mod_pack.coffee @@ -76,21 +76,6 @@ module.exports = class ModPack extends BaseModel result.itemUrl = Url.item result return result - gatherNames: (options={})-> - options.includeGatherable ?= false - options.includeDisabled ?= false - - nameData = {} - for modVersion in @modVersions - continue unless modVersion.enabled or options.includeDisabled - modVersion.gatherNames nameData, options - - result = [] - names = _.keys(nameData).sort() - for name in names - result.push nameData[name] - return result - hasRecipe: (name, options={})-> options.includeDisabled ?= false diff --git a/src/scripts/models/mod_version.coffee b/src/scripts/models/mod_version.coffee index 94b898f21..34c00b73e 100644 --- a/src/scripts/models/mod_version.coffee +++ b/src/scripts/models/mod_version.coffee @@ -55,22 +55,6 @@ module.exports = class ModVersion extends BaseModel findName: (slug)-> return @names[slug] - gatherNames: (result={}, options={})-> - options.includeGatherable ?= false - - for slug, item of @items - continue if result[item.slug] - if not item.isCraftable - continue unless options.includeGatherable - result[item.slug] = value:item.name, label:"#{item.name} (from #{@name} #{@version})" - - if options.includeGatherable - for slug, name of @names - continue if result[slug] - result[slug] = value:name, label:"#{name} (from #{@name} #{@version})" - - return result - hasRecipe: (name)-> item = @findItemByName name return false unless item? diff --git a/src/scripts/models/name_finder.coffee b/src/scripts/models/name_finder.coffee new file mode 100644 index 000000000..b4ea08051 --- /dev/null +++ b/src/scripts/models/name_finder.coffee @@ -0,0 +1,79 @@ +### +Crafting Guide - name_finder.coffee + +Copyright (c) 2015 by Redwood Labs +All rights reserved. +### + +######################################################################################################################## + +module.exports = class NameFinder + + constructor: (modPack, options={})-> + if not modPack? then throw new Error 'modPack is required' + + options.includeGatherable ?= false + options.includeDisabledMods ?= false + options.limit ?= 25 + + @includeDisabledMods = options.includeDisabledMods + @includeGatherable = options.includeGatherable + @limit = options.limit + @modPack = modPack + @names = [] + @_nameMap = {} + + # Public Methods ############################################################################### + + search: (nameHint='')-> + nameHint = null if nameHint.trim() is '' + nameHint = nameHint.toLowerCase() if nameHint? + names = @_findNames nameHint + + names.sort (a, b)-> + c = a.modVersion.compareTo b.modVersion + if c isnt 0 then return c + + return 0 if a.label is b.label + return if a.label < b.label then -1 else +1 + + names = names[0...@limit] + + return names + + # Private Methods ############################################################################## + + _isMatch: (name, hint)-> + nameWords = name.split ' ' + hintWords = hint.split ' ' + + for hintWord in hintWords + while true + return false if nameWords.length is 0 + nameWord = nameWords.shift() + break if nameWord.indexOf(hintWord) is 0 + + return true + + _findNames: (nameHint=null)-> + names = [] + nameMap = {} + + for modVersion in @modPack.modVersions + continue unless modVersion.enabled or @includeDisabledMods + + for slug, name of modVersion.names + continue if nameMap[name] + + item = modVersion.items[slug] + if not @includeGatherable + continue unless item? and (not item.isGatherable) + + scanName = "#{modVersion.name} : #{name}" + if nameHint? + continue unless @_isMatch scanName.toLowerCase(), nameHint + + nameMap[name] = name + names.push value:name, label:scanName, modVersion:modVersion + + return names diff --git a/test/mod_pack.test.coffee b/test/mod_pack.test.coffee index 2a80ba277..6b72cfe43 100644 --- a/test/mod_pack.test.coffee +++ b/test/mod_pack.test.coffee @@ -99,33 +99,6 @@ describe 'ModPack', -> display.itemName.should.equal 'Iron Chestplate' display.modSlug.should.equal 'minecraft' - describe 'gatherNames', -> - - it 'finds all registered item names', -> - buildcraft.enabled = true - industrialCraft.enabled = true - (i.value for i in modPack.gatherNames()).sort().should.eql ['Bed', 'Rubber', 'Stone Gear'] - - it 'ignores duplicate item names', -> - buildcraft.enabled = true - names = modPack.gatherNames() - bedName = (e for e in names when e.value is 'Bed')[0] - bedName.should.eql value:'Bed', label:'Bed (from Minecraft 1.7.10)' - - it 'alphabetizes the item names', -> - buildcraft.enabled = true - industrialCraft.enabled = true - (i.value for i in modPack.gatherNames()).should.eql ['Bed', 'Rubber', 'Stone Gear'] - - it 'ignores non-craftable items', -> - (n.value for n in modPack.gatherNames()).sort().should.eql ['Bed'] - - it 'ignores disabled mod versions', -> - (n.value for n in modPack.gatherNames()).should.not.include 'Stone Gear' - - it "doesn't ignore disabled mod versions when include disabled is requested", -> - (n.value for n in modPack.gatherNames(includeDisabled:true)).should.include 'Stone Gear' - describe 'hasRecipe', -> it 'returns true when the item is present and has recipes', -> diff --git a/test/mod_version.test.coffee b/test/mod_version.test.coffee index ba7c28009..b4fd49b2a 100644 --- a/test/mod_version.test.coffee +++ b/test/mod_version.test.coffee @@ -59,27 +59,6 @@ describe 'ModVersion', -> new Item modVersion:modVersion, name:'Crafting Table' modVersion.findItemByName('Crafting Table').slug.should.equal 'crafting_table' - describe 'gatherNames', -> - - it 'skips names already found', -> - new Item modVersion:modVersion, name:'Wool' - new Item modVersion:modVersion, name:'Oak Wood Planks', recipes:['foo'] - names = modVersion.gatherNames {wool:true} - names.wool.should.be.true - names.oak_wood_planks.value.should.equal 'Oak Wood Planks' - - it 'only includes craftable items', -> - new Item modVersion:modVersion, name:'Wool' - new Item modVersion:modVersion, name:'Oak Wood Planks', recipes:['foo'] - names = modVersion.gatherNames() - _.keys(names).should.eql ['oak_wood_planks'] - - it 'computes the proper value and label', -> - new Item modVersion:modVersion, name:'Oak Wood Planks', recipes:['foo'] - names = modVersion.gatherNames() - names.oak_wood_planks.value.should.equal 'Oak Wood Planks' - names.oak_wood_planks.label.should.equal 'Oak Wood Planks (from Test 0.0)' - describe 'hasRecipe', -> it 'returns false for an unknown item', ->