Skip to content

Commit

Permalink
Implement support for client ID in client
Browse files Browse the repository at this point in the history
  • Loading branch information
MaddyGuthridge committed Mar 30, 2024
1 parent ca73cf3 commit 98e583a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
21 changes: 16 additions & 5 deletions flapi/__comms.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,14 @@ def hello() -> bool:
If no data is received, this function returns `False`.
"""
log.debug("heartbeat")
client_id = get_context().client_id
log.debug(f"Attempt hello with {client_id=}")
assert client_id is not None
start = time.time()
try:
send_msg(consts.SYSEX_HEADER + bytes([
MessageOrigin.CLIENT,
client_id,
MessageType.CLIENT_HELLO,
]))
response = receive_message()
Expand All @@ -172,10 +175,12 @@ def version_query() -> tuple[int, int, int]:
"""
Query and return the version of Flapi installed to FL Studio.
"""
client_id = get_context().client_id
assert client_id is not None
log.debug("version_query")
send_msg(
consts.SYSEX_HEADER
+ bytes([MessageOrigin.CLIENT, MessageType.VERSION_QUERY])
+ bytes([MessageOrigin.CLIENT, client_id, MessageType.VERSION_QUERY])
)
response = receive_message()
log.debug("version_query: got response")
Expand All @@ -193,10 +198,12 @@ def fl_exec(code: str) -> None:
"""
Output Python code to FL Studio, where it will be executed.
"""
client_id = get_context().client_id
assert client_id is not None
log.debug(f"fl_exec: {code}")
send_msg(
consts.SYSEX_HEADER
+ bytes([MessageOrigin.CLIENT, MessageType.EXEC])
+ bytes([MessageOrigin.CLIENT, client_id, MessageType.EXEC])
+ code.encode()
)
response = receive_message()
Expand All @@ -210,10 +217,12 @@ def fl_eval(expression: str) -> Any:
Output a Python expression to FL Studio, where it will be evaluated, with
the result being returned.
"""
client_id = get_context().client_id
assert client_id is not None
log.debug(f"fl_eval: {expression}")
send_msg(
consts.SYSEX_HEADER
+ bytes([MessageOrigin.CLIENT, MessageType.EVAL])
+ bytes([MessageOrigin.CLIENT, client_id, MessageType.EVAL])
+ expression.encode()
)
response = receive_message()
Expand All @@ -229,9 +238,11 @@ def fl_print(text: str):
"""
Print the given text to FL Studio's Python console.
"""
client_id = get_context().client_id
assert client_id is not None
log.debug(f"fl_print (not expecting response): {text}")
send_msg(
consts.SYSEX_HEADER
+ bytes([MessageOrigin.CLIENT, MessageType.STDOUT])
+ bytes([MessageOrigin.CLIENT, client_id, MessageType.STDOUT])
+ b64encode(text.encode())
)
5 changes: 5 additions & 0 deletions flapi/__context.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class FlapiContext:
we can set them back as required.
"""

client_id: int | None
"""
Unique client ID for this instance of the Flapi client
"""


context: Optional[FlapiContext] = None
"""
Expand Down
16 changes: 10 additions & 6 deletions flapi/__enable.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
Code for initializing/closing Flapi
"""
import logging
import random
import mido # type: ignore
from typing import Protocol, Generic, TypeVar, Optional
from mido.ports import BaseOutput, BaseInput, IOPort # type: ignore
from . import _consts as consts
from .__context import set_context, pop_context, FlapiContext
from .__context import set_context, get_context, pop_context, FlapiContext
from .__comms import fl_exec, hello, version_query, poll_for_message
from .__decorate import restore_original_functions, add_wrappers
from .errors import FlapiPortError, FlapiConnectionError, FlapiVersionError
Expand Down Expand Up @@ -113,24 +114,26 @@ def enable(
functions_backup = add_wrappers()

# Register the context
set_context(FlapiContext(port, functions_backup))
set_context(FlapiContext(port, functions_backup, None))

return try_init()
return try_init(random.randrange(1, 0x7F))


def init():
def init(client_id: int):
"""
Initialize Flapi, so that it can send commands to FL Studio.
"""
if not try_init():
if not try_init(client_id):
raise FlapiConnectionError(
"FL Studio did not connect to Flapi - is it running?")


def try_init() -> bool:
def try_init(client_id: int) -> bool:
"""
Attempt to initialize Flapi, returning whether the operation was a success.
"""
assert get_context().client_id is None
get_context().client_id = client_id
# Poll for any new messages from FL Studio and handle them as required
poll_for_message()
# Attempt to send a heartbeat message - if we get a response, we're already
Expand All @@ -139,6 +142,7 @@ def try_init() -> bool:
setup_server()
return True
else:
get_context().client_id = None
return False


Expand Down
3 changes: 2 additions & 1 deletion flapi/cli/repl.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import click
import sys
import time
import random
from typing import Optional
from traceback import print_exc
import flapi
Expand Down Expand Up @@ -67,7 +68,7 @@ def ellipsis(delta: float) -> str:
return " "

start_time = time.time()
while not try_init():
while not try_init(random.randrange(1, 0x7F)):
delta = time.time() - start_time
if delta > max_wait:
return False
Expand Down

0 comments on commit 98e583a

Please sign in to comment.