Codebase list gnome-shell-extension-appindicator / 3e62054
iconCache: don't add an icon multiple times and remove it on destruction When we re-add an icon to the cache we only have to renew its lifetime without the need of doing anything else. Also an icon might be destroyed while it's still in cache, in that case we have to remove it from the cache during destruction (avoiding signal loops). Marco Trevisan (TreviƱo) 6 years ago
1 changed file(s) with 40 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
2626 // If the lifetime of an icon is over, the cache will destroy the icon. (!)
2727 // The presence of an inUse property set to true on the icon will extend the lifetime.
2828
29 const LIFETIME_TIMESPAN = 5000; // milli-seconds
30 const GC_INTERVAL = 10000; // milli-seconds
31
2932 // how to use: see IconCache.add, IconCache.get
3033 var IconCache = new Lang.Class({
3134 Name: 'IconCache',
3235
33 LIFETIME_TIMESPAN: 5000, //5s
34 GC_INTERVAL: 10000, //10s
35
3636 _init: function() {
3737 this._cache = {};
3838 this._lifetime = {}; //we don't want to attach lifetime to the object
39 this._destroyNotify = {};
3940 this._gc();
4041 },
4142
4243 add: function(id, o) {
43 //Util.Logger.debug("IconCache: adding "+id);
44 if (!(o && id)) return null;
45 if (id in this._cache && this._cache[id] !== o)
44 if (!(o && id))
45 return null;
46
47 if (!(id in this._cache) || this._cache[id] !== o) {
4648 this._remove(id);
47 this._cache[id] = o;
48 this._lifetime[id] = new Date().getTime() + this.LIFETIME_TIMESPAN;
49
50 //Util.Logger.debug("IconCache: adding "+id,o);
51 this._cache[id] = o;
52
53 if (typeof this._cache[id].destroy === 'function') {
54 this._destroyNotify[id] = o.connect('destroy', () => {
55 this._remove(id);
56 });
57 }
58 }
59
60 this._renewLifetime(id);
61
4962 return o;
5063 },
5164
5265 _remove: function(id) {
66 if (!(id in this._cache))
67 return;
68
5369 //Util.Logger.debug('IconCache: removing '+id);
54 if ('destroy' in this._cache[id]) this._cache[id].destroy();
70
71 if (typeof this._cache[id].destroy === 'function') {
72 this._cache[id].disconnect(this._destroyNotify[id]);
73 this._cache[id].destroy();
74 }
75
5576 delete this._cache[id];
5677 delete this._lifetime[id];
78 delete this._destroyNotify[id];
79 },
80
81 _renewLifetime: function(id) {
82 if (id in this._cache)
83 this._lifetime[id] = new Date().getTime() + LIFETIME_TIMESPAN;
5784 },
5885
5986 forceDestroy: function(id) {
7097 get: function(id) {
7198 if (id in this._cache) {
7299 //Util.Logger.debug('IconCache: retrieving '+id);
73 this._lifetime[id] = new Date().getTime() + this.LIFETIME_TIMESPAN; //renew lifetime
100 this._renewLifetime(id);
74101 return this._cache[id];
75102 }
76 else return null;
103
104 return null;
77105 },
78106
79107 _gc: function() {
80108 var time = new Date().getTime();
81109 for (var id in this._cache) {
82110 if (this._cache[id].inUse) {
83 //Util.Logger.debug ("IconCache: " + id + " is in use.");
111 //Util.Logger.debug("IconCache: " + id + " is in use.");
84112 continue;
85113 } else if (this._lifetime[id] < time) {
86114 this._remove(id);