Skip to content

Latest commit

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Python asynchronous I/O package for LDMud

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.

Usage

Install from the python package index

The efun package can be downloaded from the python package index:

pip3 install --user ldmud-asyncio

Build & install the package yourself

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

Automatically load the module at startup

In your Python startup script for LDMud add the following line:

import ldmud_asyncio

Examples

call_out() replacement

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)

Call a program and return the lines

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)

Start a websockets server

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!

About

Python asynchronous I/O package for LDMud

Resources

Stars

0 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages