refract some code

* change some comments ## to #
* [code-reuse] use inv to print volume
* remove procedure brackets
This commit is contained in:
Anton 2024-04-16 18:36:51 +05:30
parent 26f9538661
commit be71b5ba8a
7 changed files with 111 additions and 140 deletions

View File

@ -1,4 +1,4 @@
import os, terminal, src/[ui, menu]
import os, src/menu
if not dirExists getAppDir() / "assets":
error "data or config files dont exist"

View File

@ -167,71 +167,73 @@ type #enums
ctx.setProperty("property", formatNone, addr value)
]##
fmtNodeArray = 7, ##used with Node (not directly!)
fmtNodeMap = 8, ##see formatNodeArray
fmtByteArray = 9 ##raw, untyped byteArray, used with Node (used for
##screenshot-raw command)
fmtNodeArray = 7, #used with Node (not directly!)
fmtNodeMap = 8, #see formatNodeArray
fmtByteArray = 9 #raw, untyped byteArray, used with Node (used for
#screenshot-raw command)
EventID* = enum ##Event type
IDNone = 0, ##nothing happened (when timeouts or
EventID* = enum #Event type
IDNone = 0, #nothing happened (when timeouts or
##sporadic wakeups)
IDShutdown = 1, ##[ when player quits, it tries to
IDShutdown = 1, #[ when player quits, it tries to
disconnect all clients but most requests to player will fail, so
client should quit with destroy()
]##
IDLogMessage = 2, ##see requestLogMessages()
IDGetPropertyReply = 3, ##reply to getPropertyAsync(),
##(see Event, EventProperty)
IDLogMessage = 2, #see requestLogMessages()
IDGetPropertyReply = 3, #reply to getPropertyAsync(),
#(see Event, EventProperty)
IDSetPropertyReply = 4, ##reply to setPropertyAsync(),
##EventProperty is not used
IDCommandReply = 5, ##reply to commandAsync() or
##commandNodeAsync() (see EventID, EventCmd)
IDSetPropertyReply = 4, #reply to setPropertyAsync(),
#EventProperty is not used
IDCommandReply = 5, #reply to commandAsync() or
#commandNodeAsync() (see EventID, EventCmd)
IDStartFile = 6, ##notification before playback start of
##file (before loading)
IDEndFile = 7, ##notification after playback ends,after
##unloading, see EventID
IDFileLoaded = 8, ##notification when file has been
##loaded (headers read..)
IDStartFile = 6, #notification before playback start of
#file (before loading)
IDEndFile = 7, #notification after playback ends,after
#unloading, see EventID
IDFileLoaded = 8, #notification when file has been
#loaded (headers read..)
IDClientMessage = 16, ##[
IDClientMessage = 16, #[
triggered by script-message input command, it uses first argument
of command as clientName (see getclientName()). to dispatch mesage.
passes all arguments from second arguemnt as strings.
(see Event, ecentClientMessage)
]##
]#
IDVideoReConfig = 17, ##[
IDVideoReConfig = 17, #[
happens when video gets changed. resolution, pixel format or video
filter changes. Event is sent after video filters & VO are
reconfigured. if using mpv window, app should listen this Event
so to resize window if needed. this can happen sporadically and
should manually check if video parameters changed
]##
]#
IDAudioReConfig = 18, ##similar as EventIDVideoReConfig
IDSeek = 20, ##happens when a seek was initiated
##and will resume using EventIDPlaybackRestart when seek is finished
IDAudioReConfig = 18, #similar as EventIDVideoReConfig
IDSeek = 20, #[
happens when a seek was initiated and will resume
using EventIDPlaybackRestart when seek is finished
]#
IDPlayBackRestart = 21, ##[
IDPlayBackRestart = 21, #[
there was discontinuity like a seek, so playback was reinitialized
(happens after seeking, chapter switches). mainly allows client
to detect if seek is finished
]##
]#
IDEventPropertyChange = 22, ##Event sent due to observeProperty().m
##see Event,EventProperty
IDQueueOverFlow = 24, ##[
happens if internal Handle ringBuffer OverFlows, then atleast 1
Event has to be dropped, this can happen if client doesnt read
Event queue quickly with waitEvent() or client makes very large
number of asynchronous calls at once. every delivery will continue
normally once Event gets returned, this forces client to empty queue
]##
IDEventPropertyChange = 22, #Event sent due to observeProperty().m
#see Event,EventProperty
IDQueueOverFlow = 24, #[
happens if internal Handle ringBuffer OverFlows, then atleast 1
Event has to be dropped, this can happen if client doesnt read
Event queue quickly with waitEvent() or client makes very large
number of asynchronous calls at once. every delivery will continue
normally once Event gets returned, this forces client to empty queue
]#
IDEventHook = 25 ##[
IDEventHook = 25 #[
triggered if hook Handler was registered with hookAdd()
and hook is invoked. this must be manually Handled and continue
hook with hookContinue() (see Event, EventHook)
@ -259,12 +261,12 @@ type #enums
llDebug = 60, ##more noisy verbose info
llTrace = 70 ##extermely verbose
{.push bycopy.}
type
#non-enum type objects
Handle* = distinct pointer ##(private) basic type, used by api to
##infer the context
{.push bycopy.}
type
ClientUnionType* {.union.} = object
str*: cstring
flag*, int*: cint
@ -329,7 +331,6 @@ using
proc abortAsyncCmd*(ctx; replyUserData)
{.importc: "mpv_abort_async_command".}
#{.push discardable.}
proc cmd*(ctx; argsArr): cint
{.importc: "mpv_command".}
@ -348,16 +349,15 @@ proc cmdRet*(ctx; argsArr; result): cint
proc cmdString*(ctx; argsStr): cint
{.importc: "mpv_command_string".}
#{.pop.}
proc create*: ptr Handle
{.importc: "mpv_create".} ##[
{.importc: "mpv_create".} #[
create and return a Handle used to control the instance
instance is in preinitialized state. and needs more initialisation
for use with other procs. (see errUnitialised, libmpv/examples/simple.c)
this gives more control over configuration. (see more..)
NO concurrent accesses on uninitialised Handle.
returns nil when out of memory
]##
]#
proc createClient*(ctx; name): ptr Handle
{.importc: "mpv_create_client".}
@ -367,30 +367,30 @@ proc createWeakClient*(ctx; name): ptr Handle
proc destroy*(ctx)
{.importc: "mpv_destroy".}
##finish the Handle, ctx will be deallocated.
#finish the Handle, ctx will be deallocated.
proc errorString*(error): cstring
{.importc: "mpv_error_string".} ##[
{.importc: "mpv_error_string".} #[
return string describing error, if unknown: returns "unknown string",
isStaticConst, (see error: enum)
]##
]#
proc eventName*(Event: EventID): cstring
{.importc: "mpv_event_name".}
proc free*(data)
{.importc: "mpv_free".} ##[
{.importc: "mpv_free".} #[
general proc to dealloc() returned by api procs. !!explicitly used!!,
if called on not mpv's memory: undefined behavoiur happens
valid pointer returned or nil
]##
]#
proc freeNodeContents*(node)
{.importc: "mpv_free_node_contents".}
proc getClientApiVersion*: culong
{.importc: "mpv_client_api_version".}
##return api version of libmpv
#return api version of libmpv
proc getClientName*(ctx): cstring
{.importc: "mpv_client_name".}
@ -423,8 +423,6 @@ proc initialize*(ctx): cint
very important proc for usage if used create() to preinit
]##
#{.push discardable.}
proc loadConfigFile*(ctx; filename: cstring): cint
{.importc: "mpv_load_config_file".}
@ -461,7 +459,6 @@ proc terminateDestroy*(ctx)
proc unobserveProperty*(ctx; registeredReplyUserData: uint64): cint
{.importc: "mpv_unobserve_property".}
#{.pop.}
proc waitAsyncRequests*(ctx)
{.importc: "mpv_wait_async_requests".}

View File

@ -6,7 +6,7 @@ import terminal
when not defined windows: import unicode, macros, os
type
Key* {.pure.} = enum ## Supported single key presses and key combinations
Key* {.pure.} = enum #Supported single key presses and key combinations
None = (-1, "None"),
# Special ASCII characters
@ -239,7 +239,7 @@ when defined(windows):
var gOldConsoleModeInput: DWORD
var gOldConsoleMode: DWORD
proc consoleInit() =
proc consoleInit =
discard getConsoleMode(getStdHandle(STD_INPUT_HANDLE), gOldConsoleModeInput.addr)
if gFullScreen:
if getConsoleMode(getStdHandle(STD_OUTPUT_HANDLE), gOldConsoleMode.addr) != 0:
@ -248,7 +248,7 @@ when defined(windows):
else:
discard getConsoleMode(getStdHandle(STD_OUTPUT_HANDLE), gOldConsoleMode.addr)
proc consoleDeinit() =
proc consoleDeinit =
if gOldConsoleMode != 0:
discard setConsoleMode(getStdHandle(STD_OUTPUT_HANDLE), gOldConsoleMode)
@ -341,7 +341,7 @@ else: # OS X & Linux
consoleInit()
hideCursor()
proc installSignalHandlers() =
proc installSignalHandlers =
signal(SIGCONT, SIGCONT_handler)
signal(SIGTSTP, SIGTSTP_handler)
@ -376,11 +376,11 @@ else: # OS X & Linux
discard select(STDIN_FILENO+1, fds.addr, nil, nil, tv.addr)
return FD_ISSET(STDIN_FILENO, fds)
proc consoleInit() =
proc consoleInit =
nonblock(true)
installSignalHandlers()
proc consoleDeinit() =
proc consoleDeinit =
nonblock(false)
# surely a 100 char buffer is more than enough; the longest
@ -437,7 +437,7 @@ when defined(posix):
XtermColor = "xterm-color"
Xterm256Color = "xterm-256color"
proc enterFullScreen() =
proc enterFullScreen =
## Enters full-screen mode (clears the terminal).
when defined(posix):
case getEnv("TERM"):
@ -450,7 +450,7 @@ proc enterFullScreen() =
else:
eraseScreen()
proc exitFullScreen() =
proc exitFullScreen =
## Exits full-screen mode (restores the previous contents of the terminal).
when defined(posix):
case getEnv("TERM"):
@ -474,11 +474,11 @@ proc illwillInit*(fullScreen = true) =
gIllwillInitialised = true
resetAttributes()
proc checkInit() =
proc checkInit =
if not gIllwillInitialised:
raise newException(IllwillError, "Illwill not initialised")
proc illwillDeinit*() =
proc illwillDeinit* =
checkInit()
if gFullScreen: exitFullScreen()
consoleDeinit()
@ -486,7 +486,7 @@ proc illwillDeinit*() =
resetAttributes()
showCursor()
proc getKey*(): Key =
proc getKey*: Key =
## Reads the next keystroke in a non-blocking manner. If there are no
## keypress events in the buffer, `Key.None` is returned.
## If the module is not intialised, `IllwillError` is raised.

View File

@ -1,4 +1,4 @@
import strutils, #[json,]# httpclient, net, ui
import strutils, httpclient, net, ui
proc cleanLink(str: string): string =
var link = str

View File

@ -9,10 +9,15 @@ template nowStreaming =
say "Now Streaming: " & currentSong, fgGreen
cursorUp()
template endThisCall(str: string) =
template endThisCall(str: string, ret = false) =
warn str
terminateDestroy ctx
break
when ret: return
else:
terminateDestroy ctx
break
proc volumeNotify(volumeUp: bool, val: int) =
inv((if volumeUp: "Volume+: " else: "Volume-: " ) & $val)
proc notifyplayerState(isPaused, isMuted: bool) =
cursorDown()
@ -20,17 +25,14 @@ proc notifyplayerState(isPaused, isMuted: bool) =
if not isPaused:
if isMuted: warn "Muted"
else: say "Playing", fgGreen
else:
if isMuted: warn "paused and muted"
else: warn "Paused"
else: warn if isMuted: "paused and muted"
else: "Paused"
proc call(sub: string; sect = ""; stat, link: string) =
if link == "":
warn "link empty"
return
endThisCall "link empty", ret = true
elif link.contains " ":
warn "link dont exist or is invalid"
return
endThisCall "link dont exist or is invalid", ret = true
clear()
if sect == "": say (("PNimRP > " & sub) & (" > " & stat))
@ -39,20 +41,17 @@ proc call(sub: string; sect = ""; stat, link: string) =
sayTermDraw12()
if not doesLinkWork link:
warn "no link work"
return
endThisCall "no link work", ret = true
var ctx = create()
ctx.init link
var
event = ctx.waitEvent
isPaused = false
isMuted = false
isSetToObserve = false
isPaused, isMuted, isSetToObserve = false
currentSong: string
counter: uint8
try: illwillinit false
except IllWillError: discard
except: discard
cursorDown()
say "Playing", fgGreen
@ -78,51 +77,32 @@ proc call(sub: string; sect = ""; stat, link: string) =
counter = 0
counter += 1
case getKeyWithTimeout(25): #highcpuUsage; use timeout
of Key.P:
if isPaused:
isPaused = false
ctx.pause false
notifyPlayerState(isPaused, isMuted)
else:
ctx.pause true
isPaused = true
notifyPlayerState(isPaused, isMuted)
notifyPlayerState(isPaused, isMuted)
of Key.M:
if isMuted:
ctx.mute false
isMuted = false
notifyPlayerState(isPaused, isMuted)
else:
ctx.mute true
isMuted = true
notifyPlayerState(isPaused, isMuted)
notifyPlayerState(isPaused, isMuted)
of Key.Slash, Key.Plus:
let volumeIncreased = ctx.volume true
cursorDown()
cursorDown()
warn "Volume+: " & $volumeIncreased
cursorUp()
eraseLine()
cursorUp()
cursorUp()
volumeNotify true, ctx.volume true
of Key.Asterisk, Key.Minus:
let volumeDecreased = ctx.volume false
cursorDown()
cursorDown()
warn "Volume-: " & $volumeDecreased
cursorUp()
eraseLine()
cursorUp()
cursorUp()
volumeNotify true, ctx.volume false
of Key.R:
if not isPaused: terminateDestroy ctx
@ -197,7 +177,7 @@ proc menu(sub, file: string; sect = "") =
while true:
try:
case getch():
of '1': call sub, sect, n[0], l[0]; break
of '1': call sub, sect, n[1], l[1]; break
of '2': call sub, sect, n[1], l[1]; break
of '3': call sub, sect, n[2], l[2]; break
of '4': call sub, sect, n[3], l[3]; break
@ -214,7 +194,6 @@ proc menu(sub, file: string; sect = "") =
of 'F', 'f': call sub, sect, n[14], l[14]; break
of 'R', 'r':
returnBack = true
#writeStackTrace()
break
of 'Q', 'q': exitEcho()
else: inv()
@ -234,7 +213,6 @@ proc drawMainMenu*(dir = getAppDir() / "assets") =
sayIter names, ret = if dir != getAppDir() / "assets": true else: false
try:
while true:
#var getch = getch()
case getch():
of '1': menu names[0], files[0]; break
of '2': menu names[1], files[1]; break
@ -263,13 +241,8 @@ proc drawMainMenu*(dir = getAppDir() / "assets") =
break
else: inv()
of 'q', 'Q': exitEcho()
else:
#echo getch
inv()
except IndexDefect:
#warn "indexdefect"
inv()
else: inv()
except IndexDefect: inv()
if returnBack: break
export hideCursor, error

View File

@ -2,6 +2,7 @@ import client
using
ctx: ptr Handle
val: bool
proc init*(ctx; parm: string) =
let file = allocCStringArray ["loadfile", parm] #couldbe file,link,parm
@ -10,19 +11,19 @@ proc init*(ctx; parm: string) =
cE initialize ctx
cE ctx.cmd file
proc pause*(ctx; a: bool) =
var val: cint = if a: 1 else: 0
proc pause*(ctx; val) =
var val = cint val
cE ctx.setProperty("pause", fmtFlag, addr val)
proc mute*(ctx; a: bool) =
var val: cint = if a: 1 else: 0
proc mute*(ctx; val) =
var val = cint val
cE ctx.setProperty("mute", fmtFlag, addr val)
proc volume*(ctx; a: bool): int =
proc volume*(ctx; val): int =
var volumeChanged: int
cE ctx.getProperty("volume", fmtInt64,
addr volumeChanged)
if a: volumeChanged += 5 else: volumeChanged -= 5
if val: volumeChanged += 5 else: volumeChanged -= 5
cE ctx.setProperty("volume", fmtInt64, addr volumeChanged)
volumeChanged

View File

@ -2,18 +2,21 @@ import
terminal, client, random,
json, strutils, os
using
str: string
proc clear* =
eraseScreen()
setCursorPos 0, 0
proc error*(str: string) =
proc error*(str) =
styledEcho fgRed, "Error: ", str
quit QuitFailure
proc parseJArray*(file: string): seq[string] =
proc parseJArray*(str): seq[string] =
try:
result = to(
parseJson(readFile(file)){"pnimrp"},
parseJson(readFile(str)){"pnimrp"},
seq[string]
)
except IOError: error "base assets dont exist?"
@ -55,16 +58,16 @@ proc exitEcho* =
quit QuitSuccess
proc say*(txt: string; color = fgYellow; x = 5; echo = true) =
proc say*(str; color = fgYellow; x = 5; echo = true) =
if color == fgBlue: setCursorXPos x
if color == fgGreen:
setCursorXPos x
if echo: styledEcho fgGreen, txt
else: stdout.styledWrite fgGreen, txt
else: styledEcho color, txt #fgBlue would get true here
if echo: styledEcho fgGreen, str
else: stdout.styledWrite fgGreen, str
else: styledEcho color, str #fgBlue would get true here
proc sayIter(txt: string) =
for f in splitLines txt:
proc sayIter(str) =
for f in splitLines str:
say f, fgBlue
proc sayIter*(txt: seq[string]; ret = true) =
@ -86,28 +89,25 @@ proc sayIter*(txt: seq[string]; ret = true) =
if ret: say "R Return", fgBlue
say "Q Quit", fgBlue
proc warn*(txt: string; x = 4; colour = fgRed) =
proc warn*(str; x = 4; colour = fgRed) =
if x != -1: setCursorXPos x
styledEcho colour, txt
#if echo == false: stdout.styledWrite fgRed,txt
#default Args dosent seem to be working?
styledEcho colour, str
sleep 750
proc inv* =
proc inv*(str = "INVALID CHOICE") =
cursorDown()
cursorDown()
warn "INVALID CHOICE"
warn str
cursorUp()
eraseLine()
cursorUp()
cursorUp()
template sayTermDraw8*() =
proc sayTermDraw8* =
say "Poor Mans Radio Player in Nim-lang " &
'-'.repeat int terminalWidth() / 8
proc sayTermDraw12*() =
proc sayTermDraw12* =
say('-'.repeat((terminalWidth()/8).int) &
'>'.repeat int terminalWidth() / 12, fgGreen, x = 2)