Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 728139
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T06:38:50+00:00 2026-05-14T06:38:50+00:00

I’m literally banging my head against a wall here (as in, yes, physically, at

  • 0

I’m literally banging my head against a wall here (as in, yes, physically, at my current location, I am damaging my cranium). Basically, I’ve got a Python/Pygame game with some typical game “rooms”, or “screens.” EG title screen, high scores screen, and the actual game room. Something bad is happening when I switch between rooms: the old room (and its various items) are not removed from memory, or from my event listener. Not only that, but every time I go back to a certain room, my number of event listeners increases, as well as the RAM being consumed! (So if I go back and forth between the title screen and the “game room”, for instance, the number of event listeners and the memory usage just keep going up and up.

The main issue is that all the event listeners start to add up and really drain the CPU. I’m new to Python, and don’t know if I’m doing something obviously wrong here, or what.

I will love you so much if you can help me with this!

Below is the relevant source code. Complete source code at http://www.necessarygames.com/my_games/betraveled/betraveled_src0328.zip
(Requires Python 2.6 + Pygame 1.9)

MAIN.PY

class RoomController(object):
    """Controls which room is currently active (eg Title Screen)"""

    def __init__(self, screen, ev_manager):
        self.room = None
        self.screen = screen
        self.ev_manager = ev_manager
        self.ev_manager.register_listener(self)
        self.room = self.set_room(config.room)

    def set_room(self, room_const):
        #Unregister old room from ev_manager
        if self.room:
            self.room.ev_manager.unregister_listener(self.room)
            self.room = None
        #Set new room based on const
        if room_const == config.TITLE_SCREEN:
            return rooms.TitleScreen(self.screen, self.ev_manager)
        elif room_const == config.GAME_MODE_ROOM:
            return rooms.GameModeRoom(self.screen, self.ev_manager)        
        elif room_const == config.GAME_ROOM:
            return rooms.GameRoom(self.screen, self.ev_manager)
        elif room_const == config.HIGH_SCORES_ROOM:
            return rooms.HighScoresRoom(self.screen, self.ev_manager)

    def notify(self, event):
        if isinstance(event, ChangeRoomRequest):
            if event.game_mode:
                config.game_mode = event.game_mode            
            self.room = self.set_room(event.new_room)

#Run game 
def main():
    pygame.init()
    screen = pygame.display.set_mode(config.screen_size)

    ev_manager = EventManager()
    spinner = CPUSpinnerController(ev_manager)
    room_controller = RoomController(screen, ev_manager)    
    pygame_event_controller = PyGameEventController(ev_manager)

    spinner.run()

EVENT_MANAGER.PY

class EventManager:

    #This object is responsible for coordinating most communication
    #between the Model, View, and Controller.
    def __init__(self):
        from weakref import WeakKeyDictionary
        self.last_listeners = {}
        self.listeners = WeakKeyDictionary()
        self.eventQueue= []
        self.gui_app = None

    #----------------------------------------------------------------------
    def register_listener(self, listener):
        self.listeners[listener] = 1

    #----------------------------------------------------------------------
    def unregister_listener(self, listener):
        if listener in self.listeners:
            del self.listeners[listener]

    #----------------------------------------------------------------------
    def clear(self):
        del self.listeners[:]

    #----------------------------------------------------------------------
    def post(self, event):
#        if  isinstance(event, MouseButtonLeftEvent):
#            debug(event.name)
        #NOTE: copying the list like this before iterating over it, EVERY tick, is highly inefficient,
        #but currently has to be done because of how new listeners are added to the queue while it is running
        #(eg when popping cards from a deck). Should be changed. See: http://dr0id.homepage.bluewin.ch/pygame_tutorial08.html
        #and search for "Watch the iteration"

        print 'Number of listeners: ' + str(len(self.listeners))

        for listener in list(self.listeners):                               
            #NOTE: If the weakref has died, it will be 
            #automatically removed, so we don't have 
            #to worry about it.
            listener.notify(event)

    def notify(self, event):
        pass

#------------------------------------------------------------------------------
class PyGameEventController:
    """..."""
    def __init__(self, ev_manager):
        self.ev_manager = ev_manager
        self.ev_manager.register_listener(self) 
        self.input_freeze = False

    #----------------------------------------------------------------------
    def notify(self, incoming_event):

        if isinstance(incoming_event, UserInputFreeze):
            self.input_freeze = True

        elif isinstance(incoming_event, UserInputUnFreeze):
            self.input_freeze = False        

        elif isinstance(incoming_event, TickEvent) or isinstance(incoming_event, BoardCreationTick):

            #Share some time with other processes, so we don't hog the cpu
            pygame.time.wait(5)

            #Handle Pygame Events
            for event in pygame.event.get():
                #If this event manager has an associated PGU GUI app, notify it of the event
                if self.ev_manager.gui_app:
                    self.ev_manager.gui_app.event(event)
                #Standard event handling for everything else
                ev = None
                if event.type == QUIT:
                    ev = QuitEvent()
                elif event.type == pygame.MOUSEBUTTONDOWN and not self.input_freeze:
                    if event.button == 1:    #Button 1
                        pos = pygame.mouse.get_pos()
                        ev = MouseButtonLeftEvent(pos)
                elif event.type == pygame.MOUSEBUTTONDOWN and not self.input_freeze:
                    if event.button == 2:    #Button 2
                        pos = pygame.mouse.get_pos()
                        ev = MouseButtonRightEvent(pos)   
                elif event.type == pygame.MOUSEBUTTONUP and not self.input_freeze:
                    if event.button == 2:    #Button 2 Release
                        pos = pygame.mouse.get_pos()
                        ev = MouseButtonRightReleaseEvent(pos)                                              
                elif event.type == pygame.MOUSEMOTION:
                        pos = pygame.mouse.get_pos()
                        ev = MouseMoveEvent(pos)

                #Post event to event manager
                if ev:
                    self.ev_manager.post(ev)        

#        elif isinstance(event, BoardCreationTick):
#            #Share some time with other processes, so we don't hog the cpu
#            pygame.time.wait(5)               
#                           
#            #If this event manager has an associated PGU GUI app, notify it of the event
#            if self.ev_manager.gui_app:
#                self.ev_manager.gui_app.event(event)

#------------------------------------------------------------------------------            
class CPUSpinnerController:

    def __init__(self, ev_manager):
        self.ev_manager = ev_manager
        self.ev_manager.register_listener(self)
        self.clock = pygame.time.Clock()
        self.cumu_time = 0

        self.keep_going = True


    #----------------------------------------------------------------------
    def run(self):
        if not self.keep_going:
            raise Exception('dead spinner')        
        while self.keep_going: 
            time_passed = self.clock.tick()
            fps = self.clock.get_fps()
            self.cumu_time += time_passed
            self.ev_manager.post(TickEvent(time_passed, fps))

            if self.cumu_time >= 1000:
                self.cumu_time = 0
                self.ev_manager.post(SecondEvent(fps=fps))

        pygame.quit()


    #----------------------------------------------------------------------
    def notify(self, event):
        if isinstance(event, QuitEvent):
            #this will stop the while loop from running
            self.keep_going = False       

EXAMPLE CLASS USING EVENT MANAGER

class Timer(object):

    def __init__(self, ev_manager, time_left):
        self.ev_manager = ev_manager
        self.ev_manager.register_listener(self)
        self.time_left = time_left
        self.paused = False

    def __repr__(self):
        return str(self.time_left)

    def pause(self):
        self.paused = True

    def unpause(self):
        self.paused = False

    def notify(self, event):
        #Pause Event
        if isinstance(event, Pause):   
            self.pause() 
        #Unpause Event
        elif isinstance(event, Unpause):   
            self.unpause()                
        #Second Event
        elif isinstance(event, SecondEvent):   
            if not self.paused: 
                self.time_left -= 1   
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T06:38:50+00:00Added an answer on May 14, 2026 at 6:38 am

    Well, temporarily “solved” this by adding a clear() function to my event manager, and calling that before every room switch, clearing out all listeners except for my three controllers:

    def clear(self):    
        for listener in list(self.listeners):
            if not isinstance(listener, CPUSpinnerController):  
                if not isinstance(listener, RoomController):  
                    if not isinstance(listener, PyGameEventController):  
                        self.unregister_listener(listener)
    

    Doesn’t seem like the best method though. If anyone has any insight as to why this isn’t working, or why my event listener has to be manually cleared even though I’m using a weak ref dictionary to hold the listeners, I’d love to hear it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got a string that has curly quotes in it. I'd like to replace
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
Seemingly simple, but I cannot find anything relevant on the web. What is the
Does anyone know how can I replace this 2 symbol below from the string
this is what i have right now Drawing an RSS feed into the php,
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.