Created
August 25, 2013 18:43
-
-
Save Ahrengot/6335516 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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