diff --git a/mod/topic.rpy b/mod/topic.rpy index 2f5c03c..f228475 100644 --- a/mod/topic.rpy +++ b/mod/topic.rpy @@ -74,6 +74,9 @@ label fom_saysomething_event_retry: # 'Import' set_eyes_lock. $ set_eyes_lock = _fom_saysomething.set_eyes_lock + # Set of expressions to remove from Ren'Py image cache after we're done. + $ created_expressions = set() + # We'll keep looping with screen calls since we need to do Monika rendering # out of screen, hence why we'll keep doing it until we get 'nevermind' from # the player or we'll get a signal to say something. @@ -82,6 +85,14 @@ label fom_saysomething_event_retry: # Get expression from picker. $ exp = picker.get_sprite_code() + # If there were too many images saved in cache, free them all. + if len(created_expressions) > 200: + $ _fom_saysomething.remove_renpy_images_bulk(created_expressions) + + # If the spritecode isn't in cache already, mark it for removal. + if _fom_saysomething.is_renpy_image_cached(exp): + $ created_expressions.add(exp) + # During the pose picking, Monika must not blink or transition from # winking to fully open eyes, so here we lock these transitions. if not persistent._fom_saysomething_allow_winking: @@ -109,6 +120,11 @@ label fom_saysomething_event_retry: elif _return == _fom_saysomething.RETURN_RENDER: $ new_exp = picker.get_sprite_code() + # Before rendering, check if the sprite that was already cached + # before render in pose picker; mark for removal later. + if _fom_saysomething.is_renpy_image_cached(exp): + $ created_expressions.add(exp) + # Position or pose/expression update is requested, so do it now. $ renpy.show("monika " + new_exp, [picker.position], zorder=MAS_MONIKA_Z) @@ -221,6 +237,11 @@ label fom_saysomething_event_retry: "No.": m 1hua "Okay~" + # Once done with all the speech/posing, remove the images saved in cache + # that weren't cached before (so that we don't touch MAS sprites.) + $ _fom_saysomething.remove_renpy_images_bulk(created_expressions) + $ del created_expressions + call fom_saysomething_event_buttons(_show=True) return diff --git a/mod/util.rpy b/mod/util.rpy index e2b0333..5e1ef6f 100644 --- a/mod/util.rpy +++ b/mod/util.rpy @@ -46,6 +46,51 @@ init python in _fom_saysomething: elif isinstance(disp, MASMoniWinkTransform): disp.wink_into_open_eyes_dis.new_widget = disp.open_eyes_img + def is_renpy_image_cached(exp): + """ + Checks if a specified image is present in the Ren'Py image cache. + + IN: + exp -> str: + Expression code of the image to be checked. The image is identified + by a tuple ("monika", exp). + + OUT: + bool: + True if the image is present in the cache, False otherwise. + """ + return ("monika", exp) in renpy.display.image.images + + def remove_renpy_images_bulk(exps): + """ + Removes multiple images from the Ren'Py image cache in a single call. + + IN: + exps -> list of str: + A list of expression codes for the images to be removed from the + cache. Each image is identified by a tuple ("monika", exp). + """ + + for exp in exps: + remove_renpy_image(exp) + + def remove_renpy_image(exp): + """ + Removes a specified image from the Ren'Py image cache. No-op if the + spritecode does not exist in Ren'Py cache. Static images + (i.e. "1eua_static") + + IN: + exp -> str: + Expression code of the image to be removed from the cache. The + image is identified by a tuple ("monika", exp). + """ + + for cur_exp in [exp, exp + "_static"]: + tup = ("monika", cur_exp) + if tup in renpy.display.image.images: + del renpy.display.image.images[tup] + def get_screenshot_key(): """ Retrieves user-friendly key combination for a screenshot.