Skip to content

Commit

Permalink
Message improvements (#35)
Browse files Browse the repository at this point in the history
Allow messages to be sent with a reply callback.
Demo application.
  • Loading branch information
c-jo authored Nov 15, 2023
1 parent ccf2a0a commit d34e769
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 30 deletions.
5 changes: 5 additions & 0 deletions demo/!MsgDemo/!Run,feb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
If "<Python3$Dir>" = "" Then Error "!Python3 has not been seen."
Set MsgDemo$Dir <Obey$Dir>
WimpSlot -min 3M
Run <Python3$Dir>.bin.python38 <MsgDemo$Dir>.!RunImage
| > RAM:Log 2>&1
103 changes: 103 additions & 0 deletions demo/!MsgDemo/!RunImage,a73
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import swi
import sys
import os
import ctypes

import riscos_toolbox as toolbox
from riscos_toolbox import Point, BBox, Wimp

from riscos_toolbox.objects.iconbar import Iconbar, IconbarClickedEvent
from riscos_toolbox.events import toolbox_handler, message_handler, reply_handler, UserMessage
from riscos_toolbox.application import Application

Message_Hello = 0xabcd
Message_AddRequest = 0xadd0
Message_AddResult = 0xadd1
Message_NoMessage = 0xdead

class HelloMessage(UserMessage):
event_id = Message_Hello
_fields_ = [
("name", ctypes.c_char*10),
]

class AddRequestMessage(UserMessage):
event_id = Message_AddRequest
_fields_ = [
("a", ctypes.c_uint32),
("b", ctypes.c_uint32),
]

class AddResultMessage(UserMessage):
event_id = Message_AddResult
_fields_ = [
("q", ctypes.c_uint32),
]

class NoMessage(UserMessage):
event_id = Message_NoMessage

class MsgDemo(Application):
def __init__(self):
super().__init__('<MsgDemo$Dir>')

@message_handler(HelloMessage)
def reset_request(self, code, id_block, message):
if code is not None:
if code.recorded:
message.acknowledge()

@message_handler(AddRequestMessage)
def add_request(self, code, id_block, message):
arr = AddResultMessage()
arr.q = message.a + message.b
message.reply(arr)

@toolbox_handler(0xd1e)
def quit(self, event, id_block, poll_block):
toolbox.quit()

@toolbox_handler(IconbarClickedEvent)
def iconbar_clicked(self, event, id_block, poll_block):
arq = AddRequestMessage()
arq.a = 1
arq.b = 2
arq.broadcast(recorded=False,
reply_callback=lambda m:self._add_reply(m, arq.a, arq.b))

none = NoMessage()
none.broadcast(recorded=False,
reply_callback=lambda m:self._no_reply(m, False))

none = NoMessage()
none.broadcast(recorded=True,
reply_callback=lambda m:self._no_reply(m, True))

hello = HelloMessage()
hello.name = b"World"
hello.broadcast(recorded=True,
reply_callback=lambda m:self._hello_reply(m))

@reply_handler(AddResultMessage)
def _add_reply(self, code, message, a, b):
if message:
if message.q != a + b:
swi.swi("Wimp_ReportError","sI","FFFFWrong reply.", 1)
else:
swi.swi("Wimp_ReportError","sI","FFFFDidn't get a reply?", 1)

@reply_handler(NoMessage)
def _no_reply(self, code, message, recorded):
if recorded and message is None:
swi.swi("Wimp_ReportError","sI","FFFFNo bounce.", 1)
if not recorded and message is not None:
swi.swi("Wimp_ReportError","sI","FFFFGot a reply?", 1)

@reply_handler(HelloMessage)
def _hello_reply(self, code, message):
if code is not None:
swi.swi("Wimp_ReportError","sI","FFFFMessage bounced", 1)

if __name__ == "__main__":
app = MsgDemo()
app.run()
2 changes: 2 additions & 0 deletions demo/!MsgDemo/Messages
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#
_TaskName:Message Demo
Binary file added demo/!MsgDemo/Res,fae
Binary file not shown.
40 changes: 20 additions & 20 deletions riscos_toolbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,11 @@
import ctypes
import traceback
import struct
import sys

from ._types import *
from ._consts import *
from .base import Object, _objects, get_object, create_object, find_objects, _application
from .events import *
from ._consts import Wimp


class Toolbox:
Error = 0x44ec0
ObjectAutoCreated = 0x44ec1
ObjectDeleted = 0x44ec2


class Messages:
Quit = 0


_quit = False
Expand Down Expand Up @@ -84,10 +73,10 @@ def _handler_block(handlers, add=[]):
block[index] = id
return block

wimp_messages = _handler_block(events._message_handlers)
toolbox_events = _handler_block(
events._toolbox_handlers,
[Toolbox.ObjectAutoCreated, Toolbox.ObjectDeleted])
wimp_messages = _handler_block(events._message_handlers,
list(events._reply_messages))
toolbox_events = _handler_block(events._toolbox_handlers,
[Toolbox.ObjectAutoCreated, Toolbox.ObjectDeleted])

wimp_ver, task_handle, sprite_area = \
swi.swi('Toolbox_Initialise', '0IbbsbI;III',
Expand All @@ -108,9 +97,11 @@ def run(application):
global _quit

while not _quit:
flags = application.poll_flags
if events.null_polls():
flags = flags & ~Wimp.Poll.NullMask
reason, sender = swi.swi(
'Wimp_Poll', 'II;I.I',
application.poll_flags,
'Wimp_Poll', 'II;I.I', flags,
ctypes.addressof(poll_buffer))

try:
Expand All @@ -134,13 +125,22 @@ def run(application):

toolbox_dispatch(event_code, application, _id_block, poll_block)

elif reason in (Wimp.UserMessage, Wimp.UserMessageRecorded):
message = struct.unpack("I", poll_block[16:20])[0]
elif reason in [
Wimp.UserMessage,
Wimp.UserMessageRecorded,
Wimp.UserMessageAcknowledge
]:
message = MessageInfo.create(
reason, *struct.unpack("IIIII", poll_block[0:20]))

if message == Messages.Quit:
_quit = True
continue

message_dispatch(message, application, _id_block, poll_block)
else:
if reason == Wimp.Null:
events.null_poll()
wimp_dispatch(reason, application, _id_block, poll_block)

except Exception as e:
Expand Down
12 changes: 12 additions & 0 deletions riscos_toolbox/_consts.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""RISC OS Toolbox library: constants"""


class Wimp:
Null = 0
Expand Down Expand Up @@ -35,3 +37,13 @@ class Poll:
PollWord = (1 << 22)
PollWordHighPriority = (1 << 23)
SaveFPRegs = (1 << 24)


class Toolbox:
Error = 0x44ec0
ObjectAutoCreated = 0x44ec1
ObjectDeleted = 0x44ec2


class Messages:
Quit = 0
Loading

0 comments on commit d34e769

Please sign in to comment.