wip
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
###
|
||||
Crafting Guide - craftsman.coffee
|
||||
|
||||
Copyright (c) 2015 by Redwood Labs
|
||||
All rights reserved.
|
||||
###
|
||||
|
||||
_ = require 'underscore'
|
||||
BaseModel = require '../base_model'
|
||||
{Event} = require '../../constants'
|
||||
GraphBuilder = require './graph_builder'
|
||||
Inventory = require '../inventory'
|
||||
PlanBuilder = require './plan_builder'
|
||||
PlanEvaluator = require './plan_evaluator'
|
||||
w = require 'when'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class Craftsman extends BaseModel
|
||||
|
||||
@::ANALYZE_STEP_INCREMENT = 100
|
||||
|
||||
@::GRAPH_STEP_INCREMENT = 10
|
||||
|
||||
@::PLAN_STEP_INCREMENT = 50
|
||||
|
||||
@::STAGE =
|
||||
WAITING: 'waiting'
|
||||
GRAPHING: 'examining recipes'
|
||||
PLANNING: 'computing plans'
|
||||
ANALYZING: 'analyzing plans'
|
||||
COMPLETE: 'complete'
|
||||
|
||||
constructor: (modPack)->
|
||||
if not modPack? then throw new Error 'modPack is required'
|
||||
attributes =
|
||||
paused: false
|
||||
stage: @STAGE.WAITING
|
||||
stageCount: 0
|
||||
super attributes, {}
|
||||
|
||||
@_modPack = modPack
|
||||
|
||||
reset = _.throttle (=> @reset()), 100
|
||||
|
||||
@_have = new Inventory
|
||||
@_have.on Event.change, reset
|
||||
|
||||
@_want = new Inventory
|
||||
@_want.on Event.change, reset
|
||||
|
||||
@on Event.change + ':paused', reset
|
||||
@on Event.change + ':stage', => logger.info "Craftsman has started #{@stage}..."
|
||||
@reset()
|
||||
|
||||
# Public Methods ###############################################################################
|
||||
|
||||
work: ->
|
||||
return if @_want.isEmpty
|
||||
logger.verbose => "stage: #{@stage}(#{@stageCount}) working..."
|
||||
|
||||
if not @_graphBuilder?
|
||||
want = new Inventory {modPack:@_modPack}, clone:@_want
|
||||
want.localize()
|
||||
|
||||
have = new Inventory {modPack:@_modPack}, clone:@_have
|
||||
have.localize()
|
||||
|
||||
logger.info -> "Craftsman starting to build #{want} from #{have}"
|
||||
|
||||
@_graphBuilder = new GraphBuilder modPack:@_modPack, want:want, have:have
|
||||
@stage = @STAGE.GRAPHING
|
||||
@stageCount = 0
|
||||
else if not @_graphBuilder.complete
|
||||
@_graphBuilder.expandGraph @GRAPH_STEP_INCREMENT
|
||||
@stageCount = @_graphBuilder.stepCount
|
||||
else if not @_planBuilder?
|
||||
logger.debug => "Craftsman finished computing graph:\n#{@_graphBuilder.rootNode}"
|
||||
|
||||
@_planBuilder = new PlanBuilder @_graphBuilder.rootNode, @_modPack, want:@_graphBuilder.want
|
||||
@stage = @STAGE.PLANNING
|
||||
@stageCount = 0
|
||||
else if not @_planBuilder.complete
|
||||
@_planBuilder.producePlans @PLAN_STEP_INCREMENT
|
||||
@stageCount = @_planBuilder.plans.length
|
||||
else if not @_planEvaluator?
|
||||
@_planEvaluator = new PlanEvaluator @_planBuilder.plans
|
||||
@stage = @STAGE.ANALYZING
|
||||
@stageCount = 0
|
||||
else if not @_planEvaluator.complete
|
||||
@_planEvaluator.scorePlans @ANALYZE_STEP_INCREMENT
|
||||
@stageCount = @_planEvaluator.lastScored
|
||||
else
|
||||
@_plans = [
|
||||
@_planEvaluator.findBestPlan PlanEvaluator::CRITERIA.FEWEST_STEPS
|
||||
@_planEvaluator.findBestPlan PlanEvaluator::CRITERIA.LEAST_MATERIALS
|
||||
]
|
||||
@_plans[0].computeRequired()
|
||||
logger.info => "Craftsman has finished with plans: #{(p.toString() for p in @_plans).join('\n')}"
|
||||
@trigger Event.change + ':complete', this
|
||||
@trigger Event.change, this
|
||||
|
||||
@_scheduleNextWork()
|
||||
return @complete
|
||||
|
||||
reset: ->
|
||||
@_graphBuilder = null
|
||||
@_planBuilder = null
|
||||
@_planEvaluator = null
|
||||
@_plans = null
|
||||
|
||||
@stage = @STAGE.WAITING
|
||||
@stageCount = 0
|
||||
|
||||
@_scheduleNextWork()
|
||||
|
||||
# Property Methods #############################################################################
|
||||
|
||||
Object.defineProperties @prototype,
|
||||
|
||||
complete:
|
||||
get: -> @_plans?
|
||||
|
||||
have:
|
||||
get: -> @_have
|
||||
|
||||
plan:
|
||||
get: -> @_plans?[0]
|
||||
|
||||
want:
|
||||
get: -> @_want
|
||||
|
||||
# Private Methods ##############################################################################
|
||||
|
||||
_scheduleNextWork: ->
|
||||
return if @paused
|
||||
return if @want.isEmpty
|
||||
return if @complete
|
||||
|
||||
_.defer => @work()
|
||||
Reference in New Issue
Block a user