1
0
Fork 0
wasp-os/wasp/apps/software.py
Daniel Thompson 2858826921 apps: Replace del self.x with self.x = None in all apps
Testing has demonstrated that del self.x does not make the memory used to
store x available for garbage collection.

There is clearly an additional reference from another place. In fact
*after* del self.x then the memory can be made available for GC by
assignment (e.g. self.x = None). However I haven't found how to release
this reference and there is nothing in self.__dict__ that can help.

For now we'll use a twp-step process where we set the variable to None
before deleting it.

This has a big impact on memory usage. For Software it is almost 1k
(a.k.a. about 10% impact on free RAM).

Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
2021-07-28 22:01:04 +01:00

115 lines
3.5 KiB
Python

# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2020 Daniel Thompson
"""Software
~~~~~~~~~~~
A tool to enable/disable applications.
.. figure:: res/SoftwareApp.png
:width: 179
Most applications are disabled by default at boot in order to conserve
RAM (which is in short supply and very useful to anyone wanting to
write an application). This tools allows us to boot and conserve RAM
whilst still allowing users to activate so many awesome applications!
"""
import wasp
import icons
class SoftwareApp():
"""Enable and disable applications."""
NAME = 'Software'
ICON = icons.software
def foreground(self):
"""Activate the application."""
def factory(label):
nonlocal y
cb = wasp.widgets.Checkbox(0, y, label)
y += 40
if y > 160:
y = 0
return cb
y = 0
db = []
db.append(('alarm', factory('Alarm')))
db.append(('calc', factory('Calculator')))
db.append(('faces', factory('Faces')))
db.append(('gameoflife', factory('Game Of Life')))
db.append(('musicplayer', factory('Music Player')))
db.append(('play2048', factory('Play 2048')))
db.append(('snake', factory('Snake Game')))
db.append(('sports', factory('Sports')))
db.append(('flashlight', factory('Torch')))
db.append(('testapp', factory('Test')))
db.append(('timer', factory('Timer')))
db.append(('weather', factory('Weather')))
# Get the initial state for the checkboxes
for _, checkbox in db:
label = checkbox.label.replace(' ', '')
for app in wasp.system.launcher_ring:
if type(app).__name__.startswith(label):
checkbox.state = True
break
self.si = wasp.widgets.ScrollIndicator()
self.page = 0
self.db = db
self._draw()
wasp.system.request_event(wasp.EventMask.TOUCH |
wasp.EventMask.SWIPE_UPDOWN)
def background(self):
self.si = None
del self.si
self.page = None
del self.page
self.db = None
del self.db
def get_page(self):
i = self.page * 5
return self.db[i:i+5]
def swipe(self, event):
"""Notify the application of a touchscreen swipe event."""
page = self.page
pages = (len(self.db)-1) // 5
if event[0] == wasp.EventType.DOWN:
page = page - 1 if page > 0 else pages
if event[0] == wasp.EventType.UP:
page = page + 1 if page < pages else 0
self.page = page
mute = wasp.watch.display.mute
mute(True)
self._draw()
mute(False)
def touch(self, event):
"""Notify the application of a touchscreen touch event."""
for module, checkbox in self.get_page():
if checkbox.touch(event):
label = checkbox.label.replace(' ', '')
if checkbox.state:
wasp.system.register('apps.{}.{}App'.format(module, label))
else:
for app in wasp.system.launcher_ring:
if type(app).__name__.startswith(label):
wasp.system.launcher_ring.remove(app)
break
break
def _draw(self):
"""Draw the display from scratch."""
wasp.watch.drawable.fill()
self.si.draw()
for _, checkbox in self.get_page():
checkbox.draw()