This is a python module that enables the use of the Python asyncio module with LDMud 3.6.2 and later. The module doesn't export any names, it just extends the Python asyncio module to work with LDMud.
The efun package can be downloaded from the python package index:
pip3 install --user ldmud-asyncio
You can build the package yourself.
First clone the repository
git clone https://github.com/ldmud/python-asyncio.git
Install the package
cd python-asyncio
python3 setup.py install --user
In your Python startup script for LDMud add the following line:
import ldmud_asyncio
importldmud, ldmud_asyncio, asyncioasyncdefdo_call_out(cb, sec):
awaitasyncio.sleep(sec)
cb()
defefun_call_out(cb: ldmud.Closure, sec: int) ->None:
asyncio.run(do_call_out(cb, sec))
ldmud.register_efun("py_call_out", efun_call_out)importldmud, ldmud_asyncio, asyncioasyncdefdo_exec(prog, cb):
proc=awaitasyncio.create_subprocess_exec(prog, stdout=asyncio.subprocess.PIPE)
asyncforlineinproc.stdout:
cb(line.decode())
awaitproc.wait()
cb(0)
defefun_exec(prog: str, cb: ldmud.Closure) ->None:
asyncio.run(do_exec(prog, cb))
ldmud.register_efun("py_exec", efun_exec)This is the synchronization example from the websockets package. Here we only added an efun to influence the value as well.
This is the Python code:
importldmud, ldmud_asyncio, asyncio, websockets, jsonSTATE= {"value": 0}
USERS=set()
defstate_event():
returnjson.dumps({"type": "state", **STATE})
defusers_event():
returnjson.dumps({"type": "users", "count": len(USERS)})
asyncdefnotify_state():
ifUSERS: # asyncio.wait doesn't accept an empty listmessage=state_event()
awaitasyncio.wait([user.send(message) foruserinUSERS])
asyncdefnotify_users():
ifUSERS: # asyncio.wait doesn't accept an empty listmessage=users_event()
awaitasyncio.wait([user.send(message) foruserinUSERS])
asyncdefregister(websocket):
USERS.add(websocket)
awaitnotify_users()
asyncdefunregister(websocket):
USERS.remove(websocket)
awaitnotify_users()
asyncdefcounter(websocket, path):
# register(websocket) sends user_event() to websocketawaitregister(websocket)
try:
awaitwebsocket.send(state_event())
asyncformessageinwebsocket:
data=json.loads(message)
ifdata["action"] =="minus":
STATE["value"] -=1awaitnotify_state()
elifdata["action"] =="plus":
STATE["value"] +=1awaitnotify_state()
finally:
awaitunregister(websocket)
asyncio.run(websockets.serve(counter, "localhost", 6789))
asyncdefdo_ws_set_value(val):
STATE["value"] =valawaitnotify_state()
defefun_ws_set_value(val: int) ->None:
asyncio.run(do_ws_set_value(val))
ldmud.register_efun("py_ws_set_value", efun_ws_set_value)And here the HTML code to run in the browser:
<!DOCTYPE html><html><head><title>WebSocket demo</title><styletype="text/css">body {
font-family:"Courier New", sans-serif;
text-align: center;
}
.buttons {
font-size:4em;
display: flex;
justify-content: center;
}
.button, .value {
line-height:1;
padding:2rem;
margin:2rem;
border: medium solid;
min-height:1em;
min-width:1em;
}
.button {
cursor: pointer;
user-select: none;
}
.minus {
color: red;
}
.plus {
color: green;
}
.value {
min-width:2em;
}
.state {
font-size:2em;
}
</style></head><body><divclass="buttons"><divclass="minus button">-</div><divclass="value">?</div><divclass="plus button">+</div></div><divclass="state"><spanclass="users">?</span> online
</div><script>varminus=document.querySelector('.minus'),plus=document.querySelector('.plus'),value=document.querySelector('.value'),users=document.querySelector('.users'),websocket=newWebSocket("ws://127.0.0.1:6789/");minus.onclick=function(event){websocket.send(JSON.stringify({action: 'minus'}));}plus.onclick=function(event){websocket.send(JSON.stringify({action: 'plus'}));}websocket.onmessage=function(event){data=JSON.parse(event.data);switch(data.type){case'state':
value.textContent=data.value;break;case'users':
users.textContent=(data.count.toString()+" user"+(data.count==1 ? "" : "s"));break;default:
console.error("unsupported event",data);}};</script></body></html>Have fun!