Android Bug fixes
* Added a UI lock mechanism to avoid render stalls * Fixed initialization issue due to python init offset for android devices * Fixed a hang caused by joining threads on android devices * Fixed a race condition when forcefully stopping threads
This commit is contained in:
parent
b6c77b1992
commit
fc794f969a
@ -281,13 +281,11 @@ init python:
|
|||||||
thread = DollThread(target=_func, args=(self, self._hash))
|
thread = DollThread(target=_func, args=(self, self._hash))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
if settings.get("multithreading"):
|
@property
|
||||||
@property
|
def button(self):
|
||||||
def button(self):
|
if settings.get("multithreading"):
|
||||||
return self._button.get_with_default(self._loading)
|
return self._button.get_with_default(self._loading)
|
||||||
else:
|
else:
|
||||||
@property
|
|
||||||
def button(self):
|
|
||||||
return self._build_button(self._hash)
|
return self._build_button(self._hash)
|
||||||
|
|
||||||
def clear_button_cache(self):
|
def clear_button_cache(self):
|
||||||
|
@ -141,35 +141,38 @@ init python:
|
|||||||
|
|
||||||
return Fixed(*sprites, self.emote, fit_first=True)
|
return Fixed(*sprites, self.emote, fit_first=True)
|
||||||
|
|
||||||
if settings.get("multithreading"):
|
def build_image(self):
|
||||||
def build_image(self):
|
|
||||||
|
|
||||||
def _func(self, hash):
|
def _func(self, hash):
|
||||||
result = self._build_image(hash)
|
result = self._build_image(hash)
|
||||||
self._sprite.put(result)
|
self._sprite.put(result)
|
||||||
|
|
||||||
thread = DollThread(target=_func, args=(self, self._hash))
|
thread = DollThread(target=_func, args=(self, self._hash))
|
||||||
thread.start()
|
thread.start()
|
||||||
else:
|
|
||||||
def build_image(self):
|
|
||||||
self._sprite.put(self._build_image(self._hash))
|
|
||||||
renpy.restart_interaction()
|
|
||||||
|
|
||||||
def _image(self, st, at):
|
def _image(self, st, at):
|
||||||
return self._sprite.get_with_default(Null()), None
|
return self._sprite.get_with_default(Null()), None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image(self):
|
def image(self):
|
||||||
|
if settings.get("multithreading"):
|
||||||
|
|
||||||
if not renpy.is_skipping() and self.is_stale():
|
if not renpy.is_skipping() and self.is_stale():
|
||||||
self.build_image()
|
self.build_image()
|
||||||
|
|
||||||
if renpy.showing(get_character_tag(self.name), layer=self.layer):
|
if renpy.showing(get_character_tag(self.name), layer=self.layer):
|
||||||
self.show()
|
self.show()
|
||||||
elif renpy.in_rollback():
|
# elif renpy.in_rollback():
|
||||||
self.build_image()
|
# self.build_image()
|
||||||
|
|
||||||
return DynamicDisplayable(self._image)
|
return DynamicDisplayable(self._image)
|
||||||
|
else:
|
||||||
|
if not renpy.is_skipping() and self.is_stale():
|
||||||
|
|
||||||
|
if renpy.showing(get_character_tag(self.name), layer=self.layer):
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
return self._build_image(self._hash)
|
||||||
|
|
||||||
def equip(self, obj, remove_old=True):
|
def equip(self, obj, remove_old=True):
|
||||||
"""Takes DollCloth or DollOutfit object to equip."""
|
"""Takes DollCloth or DollOutfit object to equip."""
|
||||||
|
@ -180,13 +180,11 @@ init python:
|
|||||||
thread = DollThread(target=_func, args=(self, self._hash, subcat))
|
thread = DollThread(target=_func, args=(self, self._hash, subcat))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
if settings.get("multithreading"):
|
@property
|
||||||
@property
|
def button(self):
|
||||||
def button(self):
|
if settings.get("multithreading"):
|
||||||
return self._button.get_with_default(self._loading)
|
return self._button.get_with_default(self._loading)
|
||||||
else:
|
else:
|
||||||
@property
|
|
||||||
def button(self):
|
|
||||||
global current_subcategory
|
global current_subcategory
|
||||||
return self._build_button(self._hash, current_subcategory)
|
return self._build_button(self._hash, current_subcategory)
|
||||||
|
|
||||||
|
@ -40,18 +40,24 @@ init python early:
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._stop.set()
|
self._stop.set()
|
||||||
DollThread._instances.remove(self)
|
|
||||||
DollThread._count -= 1
|
if self in DollThread._instances:
|
||||||
|
DollThread._instances.remove(self)
|
||||||
|
DollThread._count -= 1
|
||||||
|
|
||||||
|
if DollThread._count <= 0:
|
||||||
|
renpy.restart_interaction()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def stop_all(cls):
|
def stop_all(cls):
|
||||||
with cls.__lock:
|
for thread in cls._instances:
|
||||||
for thread in cls._instances:
|
|
||||||
thread.stop()
|
|
||||||
|
|
||||||
# Allow threads to exit gracefully before forceful termination
|
# Allow threads to exit gracefully before forceful termination
|
||||||
for thread in cls._instances:
|
thread.stop()
|
||||||
thread.join()
|
|
||||||
|
# if not renpy.android:
|
||||||
|
# # Then forcefully terminate the remainders (except on android because that stalls the renderer)
|
||||||
|
# for thread in cls._instances:
|
||||||
|
# thread.join()
|
||||||
|
|
||||||
class DefaultQueue(queue.Queue, NoRollback):
|
class DefaultQueue(queue.Queue, NoRollback):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -89,4 +95,4 @@ init python early:
|
|||||||
return (DefaultQueue, ())
|
return (DefaultQueue, ())
|
||||||
|
|
||||||
def __reduce_ex__(self, protocol):
|
def __reduce_ex__(self, protocol):
|
||||||
return DefaultQueue, (), self.__getstate__(), None, iter([])
|
return DefaultQueue, (), self.__getstate__(), None, iter([])
|
||||||
|
@ -10,7 +10,7 @@ default preferences.renderer = "auto"
|
|||||||
default preferences.gl_powersave = False
|
default preferences.gl_powersave = False
|
||||||
default preferences.audio_when_minimized = False
|
default preferences.audio_when_minimized = False
|
||||||
|
|
||||||
init -5 python:
|
init python:
|
||||||
settings.default("theme", "auto")
|
settings.default("theme", "auto")
|
||||||
settings.default("text_color_day", "#402313ff")
|
settings.default("text_color_day", "#402313ff")
|
||||||
settings.default("text_color_night", "#341c0fff")
|
settings.default("text_color_night", "#341c0fff")
|
||||||
|
@ -6,7 +6,7 @@ init offset = -10
|
|||||||
default persistent.custom_settings = {}
|
default persistent.custom_settings = {}
|
||||||
default persistent.custom_settings_default = {}
|
default persistent.custom_settings_default = {}
|
||||||
|
|
||||||
init -10 python in settings:
|
init python in settings:
|
||||||
from store import persistent, Action, DictEquality
|
from store import persistent, Action, DictEquality
|
||||||
|
|
||||||
not_set = object()
|
not_set = object()
|
||||||
|
@ -35,10 +35,19 @@ init python:
|
|||||||
_lock = False
|
_lock = False
|
||||||
|
|
||||||
def rebuild_wardrobe_icons(items, subcat):
|
def rebuild_wardrobe_icons(items, subcat):
|
||||||
|
if not settings.get("multithreading"):
|
||||||
|
return
|
||||||
|
|
||||||
|
if subcat == "import":
|
||||||
|
return
|
||||||
|
|
||||||
for i in items.get(subcat, []):
|
for i in items.get(subcat, []):
|
||||||
i.build_button(subcat)
|
i.build_button(subcat)
|
||||||
|
|
||||||
def lock_wardrobe_icon(icon):
|
def lock_wardrobe_icon(icon):
|
||||||
|
if not settings.get("multithreading"):
|
||||||
|
return icon
|
||||||
|
|
||||||
lock = bool(DollThread._count)
|
lock = bool(DollThread._count)
|
||||||
|
|
||||||
return gray_tint(icon) if lock else icon
|
return gray_tint(icon) if lock else icon
|
||||||
@ -629,9 +638,10 @@ screen wardrobe_menu(xx, yy):
|
|||||||
button:
|
button:
|
||||||
focus_mask None
|
focus_mask None
|
||||||
xysize (72, 72)
|
xysize (72, 72)
|
||||||
background icon
|
background lock_wardrobe_icon(icon)
|
||||||
activate_sound "sounds/scroll.ogg"
|
activate_sound "sounds/scroll.ogg"
|
||||||
tooltip category
|
tooltip category
|
||||||
|
sensitive (not bool(DollThread._count))
|
||||||
action Return(["category", category])
|
action Return(["category", category])
|
||||||
if current_category == category:
|
if current_category == category:
|
||||||
xoffset icon_xoffset
|
xoffset icon_xoffset
|
||||||
@ -646,8 +656,9 @@ screen wardrobe_menu(xx, yy):
|
|||||||
button:
|
button:
|
||||||
focus_mask None
|
focus_mask None
|
||||||
xysize (72, 72)
|
xysize (72, 72)
|
||||||
background Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/outfits.webp", zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5)), icon_frame)
|
background lock_wardrobe_icon(Fixed(icon_bg, Transform("interface/wardrobe/icons/categories/outfits.webp", zoom=0.45, anchor=(0.5, 0.5), align=(0.5, 0.5)), icon_frame))
|
||||||
tooltip "Outfits Manager"
|
tooltip "Outfits Manager"
|
||||||
|
sensitive (not bool(DollThread._count))
|
||||||
action Return(["category", "outfits"])
|
action Return(["category", "outfits"])
|
||||||
if current_category == "outfits":
|
if current_category == "outfits":
|
||||||
yoffset icon_yoffset
|
yoffset icon_yoffset
|
||||||
@ -758,7 +769,7 @@ screen wardrobe_menuitem(xx, yy):
|
|||||||
pos (12, 108)
|
pos (12, 108)
|
||||||
|
|
||||||
for subcategory in category_items.keys():
|
for subcategory in category_items.keys():
|
||||||
$ icon = "interface/wardrobe/icons/{}.webp".format(subcategory)
|
$ icon = lock_wardrobe_icon("interface/wardrobe/icons/{}.webp".format(subcategory))
|
||||||
|
|
||||||
button:
|
button:
|
||||||
focus_mask None
|
focus_mask None
|
||||||
@ -767,6 +778,7 @@ screen wardrobe_menuitem(xx, yy):
|
|||||||
selected_background Transform(icon, size=(72, 72), fit="contain", )
|
selected_background Transform(icon, size=(72, 72), fit="contain", )
|
||||||
selected (subcategory == current_subcategory)
|
selected (subcategory == current_subcategory)
|
||||||
tooltip subcategory
|
tooltip subcategory
|
||||||
|
sensitive (not bool(DollThread._count))
|
||||||
action Return(["subcategory", subcategory])
|
action Return(["subcategory", subcategory])
|
||||||
|
|
||||||
# # Item icons
|
# # Item icons
|
||||||
@ -810,7 +822,7 @@ screen wardrobe_outfit_menuitem(xx, yy):
|
|||||||
pos (8, 108)
|
pos (8, 108)
|
||||||
|
|
||||||
for subcategory in category_items.keys():
|
for subcategory in category_items.keys():
|
||||||
$ icon = "interface/wardrobe/icons/{}.webp".format(subcategory)
|
$ icon = lock_wardrobe_icon("interface/wardrobe/icons/{}.webp".format(subcategory))
|
||||||
$ action = Return(["subcategory", subcategory])
|
$ action = Return(["subcategory", subcategory])
|
||||||
|
|
||||||
if subcategory == "schedule" and not get_character_scheduling(states.active_girl):
|
if subcategory == "schedule" and not get_character_scheduling(states.active_girl):
|
||||||
@ -823,6 +835,7 @@ screen wardrobe_outfit_menuitem(xx, yy):
|
|||||||
background Transform(icon, alpha=0.65, xsize=72, fit="contain")
|
background Transform(icon, alpha=0.65, xsize=72, fit="contain")
|
||||||
selected_background Transform(icon, xsize=72, fit="contain")
|
selected_background Transform(icon, xsize=72, fit="contain")
|
||||||
selected (subcategory == current_subcategory)
|
selected (subcategory == current_subcategory)
|
||||||
|
sensitive (not bool(DollThread._count))
|
||||||
tooltip subcategory
|
tooltip subcategory
|
||||||
action action
|
action action
|
||||||
|
|
||||||
@ -846,8 +859,10 @@ screen wardrobe_outfit_menuitem(xx, yy):
|
|||||||
textbutton "Save":
|
textbutton "Save":
|
||||||
focus_mask None
|
focus_mask None
|
||||||
xysize icon_size
|
xysize icon_size
|
||||||
|
insensitive_background "#0000001A"
|
||||||
idle_background "#00000033"
|
idle_background "#00000033"
|
||||||
text_align (0.5, 0.5)
|
text_align (0.5, 0.5)
|
||||||
|
sensitive (not bool(DollThread._count))
|
||||||
action Return(["addoutfit", None])
|
action Return(["addoutfit", None])
|
||||||
|
|
||||||
if current_subcategory == "import":
|
if current_subcategory == "import":
|
||||||
@ -895,6 +910,7 @@ style wardrobe_button is empty:
|
|||||||
|
|
||||||
style wardrobe_button_text:
|
style wardrobe_button_text:
|
||||||
color "#fff"
|
color "#fff"
|
||||||
|
insensitive_color "#808080"
|
||||||
size 20
|
size 20
|
||||||
outlines [ (2, "#000", 0, 0) ]
|
outlines [ (2, "#000", 0, 0) ]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user