Created
November 11, 2013 01:49
-
-
Save apparentlymart/7406504 to your computer and use it in GitHub Desktop.
Alamatic Clock Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import coll | |
enum HourType: | |
#: A 12-hour time in the morning. | |
AM | |
#: A 12-hour time in the afternoon/evening. | |
PM | |
#: A 24-hour time | |
TWENTYFOUR_HOUR | |
interface Time: | |
#: The hour portion of the time, as an integer from 0 to 23 if :attr:`hour_type` is | |
#: ``TWENTYFOUR_HOUR``, or from 1 to 12 otherwise. | |
prop hour as UInt8 | |
#: The minute portion of the time, as an integer from 0 to 59. | |
prop minute as UInt8 | |
#: The second portion of the time, as an integer from 0 to 60. 60 is used only to describe | |
#: a leap-second, which will not be supported on all time sources. | |
prop second as UInt8 | |
#: The tens part of the hour, as integer from 0 to 2 if :attr:`hour_type` is ``TWENTYFOUR_HOUR``, | |
#: or from 0 to 1 otherwise. | |
prop hour_tens as UInt8 | |
#: The units part of the hour, as an integer from 0 to 9. | |
prop hour_units as UInt8 | |
#: The tens part of the minute, as an integer from 0 to 5. | |
prop minute_tens as UInt8 | |
#: The units part of the minute, as an integer from 0 to 9. | |
prop minute_units as UInt8 | |
#: The tens part of the second, as an integer from 0 to 6. | |
prop second_tens as UInt8 | |
#: The units part of the second, as an integer from 0 to 9. | |
prop second_units as UInt8 | |
#: An indication of how to intepret the hour field of the object. | |
prop hour_type as HourType | |
interface Display: | |
#: Get the width of the text part of the display in characters. A caller may still provide | |
#: a longer string, but this allows the caller to possibly adapt its messaging to fit. | |
prop text_width as UInt8 | |
#: ``true`` if this display can support 24-hour time format, or ``false`` otherwise. | |
#: If ``false``, the caller will never provide a time whose :attr:`Time.hour_type` is | |
#: ``TWENTYFOUR_HOUR``. | |
prop can_support_24hr as Bool | |
#: ``false`` if this display can support 12-hour time format, or ``false`` otherwise. | |
#: If ``false``, the caller will _always_ provide a time whose :attr:`Time.hour_type` is | |
#: ``TWENTYFOUR_HOUR``. | |
prop can_support_12hr as Bool | |
#: Update the time on the display. This will be called whenever the current time has changed | |
#: enough to warrant updating the display. | |
func update_time(time as Ref(Time)) as Void | |
#: Show some text on the display. | |
#: | |
#: If the display cannot concurrently show both the time and some text, text takes priority over | |
#: the time until cleared by a subsequent call to :meth:`clear_text`. | |
func show_text(text as Slice(UInt8)) as Void | |
#: Clear text from the display. | |
func clear_text() as Void | |
interface TimeSource: | |
#: ``true`` if this display can support 24-hour time format, or ``false`` otherwise. | |
#: If ``false``, the caller will never provide a time whose :attr:`Time.hour_type` is | |
#: ``TWENTYFOUR_HOUR``. | |
prop can_support_24hr as Bool | |
#: ``false`` if this display can support 12-hour time format, or ``false`` otherwise. | |
#: If ``false``, the caller will _always_ provide a time whose :attr:`Time.hour_type` is | |
#: ``TWENTYFOUR_HOUR``. | |
prop can_support_12hr as Bool | |
#: Reference to the time as of the last call to :meth:`update_time`. If the time has never been updated, | |
#: the value is undefined. | |
prop latest_time as Ref(Time) | |
#: Set the time format to 24-hour time. Only callable if :attr:`can_support_24hr` is ``true``. | |
func use_24hr_time() as Void, if can_support_24hr | |
#: Set the time format to 12-hour time. Only callable if :attr:`can_support_12hr` is ``true``. | |
func use_12hr_time() as Void, if can_support_12hr | |
#: Update :attr:`latest_time` to reflect the current time provided by the time source. | |
func update_time() as Void | |
class App( | |
const display as Display, | |
const time_source as TimeSource, | |
const update_interval as time.Interval | |
): | |
const has_digit_input = user_input.has_digit_input | |
const display_text_width = display.text_width | |
func __init__(): | |
assert ( | |
(display.can_support_24hr and time_source.can_support_24hr) or | |
(display.can_support_12hr and time_source.can_support_12hr | |
), "Display and source do not support a common time format" | |
# Prefer 24hr time if both display and source support it. | |
# TODO: Some facility to choose. | |
if display.can_support_24hr and display.can_support_24hr: | |
time_source.use_24hr_time() | |
else: | |
time_source.use_12hr_time() | |
when update_interval.tick, self.update | |
func update(): | |
self.time_source.update_time() | |
self.display.update_time(self.time_source.latest_time) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment