python弱引用来管理游戏中组件式的UI

本文介绍了一种组件式UI管理方案,通过弱引用来确保UI组件能够在不同场景下动态加载与卸载,同时保证资源的有效回收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题介绍:

项目中有一种组件式的UI,即一些UI的小部件,可以随时地卸载或显示,而不依赖于当前所在的场景,如左上角角色信息、右上角小地图、菜单、聊天框等。为了统一地对这些组件UI进行管理,需要做到:
 
    1. 开发更多组件UI时,需要实现展示和隐藏的接口
    2. 统一地管理添加、删除和隐藏组件UI
    3. 索引不影响UI对象的正常释放
 

实现:

为了在任何场景中都可以有选择的动态添加、删除或隐藏这些UI部件,我约定了一个组件UI接口类UIComponent,然后用一个全局列表索引所有组件,这样对外只需要留很少的接口就可以管理这些组件了。
 
但是,由于组件的UI有可能因为各种形式被程序的逻辑移除,导致组件UI的索引表失效,于是便引入了python的弱引用
 
python的内存是通过引用计数垃圾回收来管理的,当一个Python对象被引用时其引用计数增加1,当其不再被一个变量引用时则计数减1。当引用计数等于0时对象被删除。我们可以很轻易地用sys.getrefcount(o)这个函数来打印出python对象的引用计数。
 
同时,python也提供了一个weakref模块,创建了一个弱引用后,可以引用python的对象,而不增加其引用计数。弱引用提供一个函数来查询所引用的对象是否有效。
下面是python里面使用弱引用的例子:
01 >>> import sys
02 >>> import weakref
03 >>> class Class1:
04   def test(self):
05     print "test..."
06     
07 >>> o = Class1()
08 >>> sys.getrefcount(o)
09 2
10 >>> r = weakref.ref(o) # 创建一个弱引用
11 >>> sys.getrefcount(o) # 引用计数并没有改变
12 2
13 >>>  o = None
14 >>>  r # 当对象引用计数为零时,弱引用失效。
15 <weakref at 00D3B3F0; dead>

 

这样,上面的组件UI全局索引改成对UI对象弱引用的索引,而不用影响UI对象的正常释放回收。相当于一个透明对这些组件UI进行管理。
01 class UIComponent(object):
02     """组件式的UI,统一隐藏和显示行为"""
03     def __init__(self, host):
04         self._ret_host = weakref.ref(host)
05  
06         self._show_ui_callback = None
07         self._hide_ui_callback = None
08  
09         # 创建宿主的弱引用,检查宿主失效,并清理
10         G_COMPONENT_UI[self._ret_host] = weakref.ref(self)
11  
12     def destory(self):
13         del G_COMPONENT_UI[self._ret_host]
14  
15     def show_component_ui_callback(self, callback):
16         self._show_ui_callback = callback
17  
18     def hide_component_ui_callback(self, callback):
19         self._hide_ui_callback = callback
20  
21 G_COMPONENT_UI = {}
22 def hide_all_compent_ui():
23     del_list = []
24     for ref_host, ui_component in G_COMPONENT_UI.iteritems():
25         host = ref_host()
26         if not host:
27             del_list.append(ref_host)
28         else:
29             ui_component = ui_component()
30             if not ui_component:
31                 del_list.append(ref_host)
32             elif ui_component._hide_ui_callback:
33                 ui_component._hide_ui_callback()
34             else:
35                 if hasattr(host,"hide"):
36                     host.hide()
37  
38     for i,ref_host in enumerate(del_list):
39         del G_COMPONENT_UI[ref_host]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值