Skip to content

Instantly share code, notes, and snippets.

@Ahrengot
Created August 25, 2013 18:43
Show Gist options
  • Save Ahrengot/6335516 to your computer and use it in GitHub Desktop.
Save Ahrengot/6335516 to your computer and use it in GitHub Desktop.
define ["underscore", "model/Rectangle"], (_, Rectangle) ->
class ConfigRuleBook
constructor: () ->
# Relationship between fronts and shelves
@frontShelfRelationship =
"skuffe_1x05": "hylde_1"
"skuffe_1x1": "hylde_1"
"bakker_1": "hylde_1"
"skuffe_2x1": "hylde_2"
"klap_2x1": "hylde_2"
"klap_2x1_stof_hvidt": "hylde_2"
"klap_2x1_stof_sort": "hylde_2"
"klap_2x1_stof_soelv": "hylde_2"
"klap_2x1": "hylde_2"
"bakker_2": "hylde_2"
"270_skuffe_1x1": "265_hylde_1"
isTopElement: (el, container) ->
containerTop = container.grids[el.level].vertical[0]
elementTop = el.containerRect.y
return Math.abs( containerTop - elementTop ) < app.config.board.overlap_tolerance
hasItemDirectlyAbove: (el, container) ->
tolerance = app.config.board.overlap_tolerance
r = el.containerRect
hitbox = new Rectangle( r.x, r.y - tolerance, r.width, tolerance + 1 )
# Figure out if there are any overlapping elements
overlappingElements = ( element for element in container.elements when app.utils.rectanglesOverlap( element.containerRect, hitbox ) )
# If there are overlapping elements, figure out if their match levels conflict with this element
if overlappingElements.length then for overlappingEl in overlappingElements
# Skip own element – We don't have view id, so use views rect id, which is also unique
unless overlappingEl.containerRect.id is el.containerRect.id
if el.matchLevel & overlappingEl.matchLevel
return yes
# If no rectangles overlap or match levels conflict, then return false
return no
hasShelfAlready: (el, container, shelfName) ->
shelvesMatchingName = ( el for el in container.elements when el.name is shelfName )
# No shelves? Return
return false if shelvesMatchingName.length < 1
# Go through each shelf and see if it's rect overlap with provided element.
for shelf in shelvesMatchingName when app.utils.rectanglesOverlap( shelf.containerRect, el.containerRect )
return true
return false
getMissingShelf: (el, container) ->
# Check if there should be a shelf behind this item
if @frontShelfRelationship[el.name]?
return false if @isTopElement( el, container )
return false if @hasItemDirectlyAbove( el, container )
return false if @hasShelfAlready( el, container, @frontShelfRelationship[el.name] )
# We passed the tests. Return shelf.
return @frontShelfRelationship[el.name]
else return false
addBookcaseDoorsNeeded: (container, doorPool) ->
doorsNeeded = { left: [], right: [] }
doorsInContainer = {
left: _.where( doorPool.left, { parent:container.cid } )
right: _.where( doorPool.right, { parent:container.cid } )
}
# Mark doors in container as used, so that other containers can't claim them.
leftDoor.usedBy = container.cid for leftDoor in doorsInContainer.left
rightDoor.usedBy = container.cid for rightDoor in doorsInContainer.right
# Make sure doorPool.left and doorPool.right are defined
if not doorPool.left then doorPool.left = []
if not doorPool.right then doorPool.right = []
# Figure out have many doors we need after converting single doors to sets
missingLeftDoors = doorPool.left.length % 2
missingRightDoors = doorPool.right.length % 2
# Check if we need to add any extra doors
if missingLeftDoors > 0 then for i in [0...missingLeftDoors]
container.elements.push _.clone( doorsInContainer.left[0] )
if missingRightDoors > 0 then for i in [0...missingRightDoors]
container.elements.push _.clone( doorsInContainer.right[0] )
changeBlackDoors: (container) ->
blackLeft = {
"066": "066"
"126": "126"
}
blackRight = {
"066": "067"
"126": "127"
}
# Check if el is a left or right door of a certain type
for el in container.elements when _.contains(blackLeft, el.product_name) or _.contains(blackRight, el.product_name)
# Check if the door is black and sitting in either side
if el.colorCode is 75 and el.side
# Remap product_name
dictionary = if el.side is 1 then blackLeft else blackRight
el.product_name = dictionary[el.product_name]
insertDoors: (name, productName, color, count, group) ->
###
void(^insertDoors)(NSString*, NSString*, DAColor*, int, PGGroup*) = ^(NSString *elementName, NSString *productName, DAColor *color, int count, PGGroup *group) {
DAElement *element = [[DAModel sharedInstance] elementWithName:elementName];
HMNode *node = [[HMNode alloc] initWithElement:element color:color];
PGItem *item = [[PGItem alloc] initWithNode:node productName:productName];
item.count = count;
[group addItem:item];
};
###
changeWoodDoors: (container, doorPool) ->
productNamesSet = {
"066": "068"
"126": "128"
}
productNamesLeft = {
"066": "066"
"126": "126"
}
productNamesRight = {
"066": "067"
"126": "127"
}
namesSet = {
"066": "066L_laage_3"
"126": "126L_laage_2"
}
namesLeft = {
"066": "066L_laage_3"
"126": "126L_laage_2"
}
namesRight = {
"066": "067R_laage_3"
"126": "127R_laage_2"
}
console.group "Running door logic"
# Use do to prevent variable creep (Essentially a self-invoking anonymous function)
console.time "changing wood doors takes"
do ->
for type, colors of doorPool
for color, sides of colors
console.groupCollapsed "Comparing before/after for container #{container.cid}"
# 1st loop, update doors
for side, doors of sides
# Reject doors from the door pool that aren't made of wood
doors = _.reject( doors, (d) -> d.colorGroup isnt 3 )
# Remove doors belonging to this container because we're adding them as sets below
for door in doors when door.parent is container.cid
delete container.elements[i] for el, i in container.elements when el.containerRect.id is door.containerRect.id
# Add doors back to pool
doorPool[type][color][side] = doors
# 2nd loop, go over door pool and convert doors to sets.
for side, doors of sides
console.log "There are #{doors.length} type #{type} #{side}-side doors in #{container.cid}"
console.groupEnd()
console.timeEnd "changing wood doors takes"
###
for type, doors of doorPool
leftCount = if doors.left then doors.left.length else 0
rightCount = if doors.right then doors.right.length else 0
setCount = Math.min( leftCount, rightCount )
if setCount
leftCount -= setCount
rightCount -= setCount
# @insertDoors( namesSet[type], )
console.log "number of left #{type} doors in total: ", leftCount
console.log "number of right #{type} doors in total: ", rightCount
###
console.groupEnd()
###
for(PGGroup *group in groups) {
NSMutableArray *doors = [NSMutableArray array];
// process all doors in group
for(PGItem *item in group.items) {
if(item.count>0 && [productNamesSet objectForKey:item.productName] && item.node.color && item.node.element.side) {
// must be wood door
int cg = item.node.color.colorGroup;
if(cg==3) {
// count number of doors in group
[PGDoor addDoorToArray:doors withProductName:item.productName color:item.node.color side:item.node.element.side];
// remove original
item.count = 0;
}
}
}
// insert needed doors
for(PGDoor *door in doors) {
NSString *name = door.productName;
int leftCount = door.leftCount;
int rightCount = door.rightCount;
int setCount = MIN(leftCount, rightCount);
if(setCount) {
leftCount -= setCount;
rightCount -= setCount;
insertDoors([namesSet objectForKey:name], [productNamesSet objectForKey:name], door.color, setCount, group);
}
if(leftCount) {
insertDoors([namesLeft objectForKey:name], [productNamesLeft objectForKey:name], door.color, leftCount, group);
}
if(rightCount) {
insertDoors([namesRight objectForKey:name], [productNamesRight objectForKey:name], door.color, rightCount, group);
}
}
}
###
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment