toontown-just-works/otp/margins/MarginManager.py
2024-07-07 18:08:39 -05:00

83 lines
2.7 KiB
Python

from pandac.PandaModules import *
from MarginCell import MarginCell
import random
class MarginManager(PandaNode):
def __init__(self):
PandaNode.__init__(self, 'margins')
self.cells = set()
self.visiblePopups = set()
def addGridCell(self, x, y, a2d):
# Yucky!
nodePath = NodePath.anyPath(self)
a2d.reparentTo(nodePath)
cell = MarginCell(self)
cell.reparentTo(a2d)
cell.setScale(0.2)
cell.setPos(x, 0, y + 0.025)
cell.setAvailable(True)
cell.setPythonTag('MarginCell', cell)
self.cells.add(cell)
self.reorganize()
return cell
def setCellAvailable(self, cell, available):
cell = cell.getPythonTag('MarginCell')
cell.setAvailable(available)
self.reorganize()
def addVisiblePopup(self, popup):
self.visiblePopups.add(popup)
self.reorganize()
def removeVisiblePopup(self, popup):
if popup not in self.visiblePopups: return
self.visiblePopups.remove(popup)
self.reorganize()
def reorganize(self):
# First, get all active cells:
activeCells = [cell for cell in self.cells if cell.isAvailable()]
# Next, get all visible popups, sorted by priority:
popups = list(self.visiblePopups)
popups.sort(key=lambda x: -x.getPriority())
# We can only display so many popups, so truncate to the number of active
# margin cells:
popups = popups[:len(activeCells)]
# Now, we need to build up a list of free cells:
freeCells = []
for cell in activeCells:
if not cell.hasContent():
freeCells.append(cell)
elif cell.getContent() in popups:
# It's already displaying something we want to show, so we can
# safely ignore this cell/popup pair:
popups.remove(cell.getContent())
else:
# It's not displaying something we want to see, evict the old
# popup:
cell.setContent(None)
freeCells.append(cell)
# At this point, there should be enough cells to show the popups:
assert len(freeCells) >= len(popups)
# Now we assign the popups:
for popup in popups:
if popup._lastCell in freeCells and popup._lastCell.isFree():
# The last cell it had assigned is available, so let's assign it
# again:
popup._lastCell.setContent(popup)
freeCells.remove(popup._lastCell)
else:
# We assign a cell at random.
cell = random.choice(freeCells)
cell.setContent(popup)
freeCells.remove(cell)