Ethazeriel / discord-bot

Horse.
Other
2 stars 0 forks source link

proposal for shared insertion markers #109

Closed Whuppee closed 1 year ago

Whuppee commented 1 year ago

putting this here because typing it has helped me work through my thoughts/ I don't want to lose them; as you're able, please let me know if you have any thoughts or objections to what I'll be attempting:

Player gets a variant of getNext() that returns the index not the track, and a setter for new variable insertPending:number|null, then all queueX set insertPending = null. change the idle->next event to call next() if (insertionPending == null || insertPending != getNextIndex()) — also setting Pending to null should call next() if idle

then anything that will be calling queueX sets Pending to the index they're targeting before, then just calls queueX(tracks) when fetch returns as normal. except if fetch fails, set Pending null (which if idle, calls next). that's the light version—

when the idle->next event doesn't overlaps, no behavior changes. else the player idles until fetch finishes and things are queued. all queueX already call play() if idle; next() was never called so the playhead doesn't even need moved (change to how queueNow decides between play/next though). and if fetch fails, it just resumes

the only thing I see this breaking is user expectation during concurrency, and this idea is what got me out of bed

we want to sync insertion marks for an accepted drop from one web client into all of them, to help people better coordinate and communicate, and putting this into the playerStatus already synced out makes this easy

this behavior likely better fits user intention in either client when happening to queue something after the playhead, within a few seconds of the current track ending. this prevents needing multiple actions (or waiting) to get that result, and in either case prevents the multiple frivolous media, queue and websyncs that would result

aside the audio just stopping needing an explanation, this explanation also coordinates the same behavior; as an index in player, it should be rather easily hooked into the embeds already being synced out as ( ... PENDING ... ) or whatever

also the fetch-error, set Pending null, idle->next handling I've described would already cleanup/sync in idle->play

Whuppee commented 1 year ago

like how our queue embed doesn't always follow the playhead, neither client should hijack the user's view to center on insertion marks; but both need to somehow convey when something is happening out of sight

Whuppee commented 1 year ago

[also for anyone not us: we've so far decided against interlocks preventing some actions while others are in progress]

less reasonably—ignoring the insertion marks and continuing to queue things will work; requests will still resolve and be inserted at whatever their target index was, violating spatial expectations and in the worst case intermingling results

without much work going into tracking relative positions, resolution order, removals, or a shuffle fucking everything, I don't think there's any way to coordinate multiples without violating expectations; but making insertions key, value pairs would at least allow for multiple to be represented easily, without meaningfully complicating registration/fulfillment

obviously the results won't be great and having only a most-recent marker further disincentivizes this— but they should be rare/ it's on you if you want to share a queue with someone behaving otherwise. mostly it's that having multiple better communicates what's happening, independent of whether it should be happening. and for smaller insertions spaced more widely or where the exact spatial relationships don't matter as much/ there could easily be use cases like allowing (most) anyone to queueLast but for only some to queueNext

okay, I talked myself into doing this by the end

Whuppee commented 1 year ago

and extremely unreasonably relative to our abilities, interest, comfort and not breaking fucking everything, but—

adapt our entire fucking everything so we can queue the promise returned by fetch(), along with a .then() and .catch() to spread-splice the array returned by fetch into the player.queue[] of the index of the promise/ remove it on fail

and being truly in the queue, our embeds/ web client comparably-easily render either a typeof Track or typeof Promise

Whuppee commented 1 year ago

am I wrong or did I just accidentally solved simultaneous insertions resolving to the wrong indexes

Whuppee commented 1 year ago

I'll need to do a little bit of violence to our typing but this sounds amazingly workable actually

Whuppee commented 1 year ago

I've realized that if I can make this work, you could also drag and drop pending promises and I'm going to go lie down

Whuppee commented 1 year ago

04160c4f753b0c142e9981daa227c4ad72bb4cd3