-
-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
trigger
and friends without pattern IDs
#970
Conversation
Hey @mindofmatthew thanks a lot for looking into this!
I might well be missing something, but would it be possible to do without patControls?
I'm also confused about what reset is for. Probably I attempted to implement this feature twice and they both made it! If you agree it's a duplication, then yes please remove it.
I guess this was so that you could reset pattern b whenever pattern a was evaluated. I've never found this useful so would be happy with this being removed for the sake of simplicity. It's just a feature that fell out of a pattern not knowing its own id really.
Is there a use case for this? I think once/first are mainly useful for playing single events asap.
Yes, maybe it's easier to solve with the changes to stream post-link.
Good point.. Maybe UI for now? |
792bbf7
to
b9eb0c8
Compare
Yes, definitely. The benefits of separately storing With that, I also removed the global state values for pattern evaluation times as we discussed. I also removed
My use case is something like I also left the functions in Controls.hs for now. We should probably do a bigger code reorganization coinciding with 2.0. Anyway, this is ready to be merged unless you've got other comments. This will change the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work! Really appreciate that you're addressing this annoyance which has been bugging me too!
let x = queryArc pat (Arc 0 0) | ||
pMap <- seq x $ takeMVar (sPMapMV stream) | ||
let playState = updatePS $ Map.lookup (fromID k) pMap | ||
putMVar (sPMapMV stream) $ Map.insert (fromID k) playState pMap | ||
where updatePS (Just playState) = do playState {pattern = pat', history = pat:(history playState)} | ||
updatePS Nothing = PlayState pat' False False [pat'] | ||
pat' = pat # pS "_id_" (pure $ fromID k) | ||
patControls = Map.singleton "_t_pattern" (VR t) | ||
pat' = withQueryControls (Map.union patControls) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beware that this adds a new operation which happens at every query. I see a risk for lower performance in the critical path. I would prefer that we do some benchmarking before accepting the PR. I am also curious whether it would be possible to make a larger restructuring in order to achieve your goal some other way. For example, could we change the pattern datastructure type? If Time is now included in all patterns, it should perhaps not be part of the pattern map since it's not optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I haven't spent much time with the benchmark tests, but I can play around and figure out a test for this case.
I would point out that this shouldn't be any more expensive than the # pS "_id_" (pure $ fromID k)
that we already do on every query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point - we are already performing a very similar Map.union here. Complexity wise, you are fully correct. From real performance perspective, this might be negligible as well - I don't know before we check some benchmarks. I really don't want to discourage this from being merged as long as performance is not too affected. My proposal could be part of a different change and a larger overhaul.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have a look at benchmarking, there is a benchmarking suite but I think no-one ever really looked at performance issues with it.
Otherwise, shall we go ahead and merge this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I also think we should go ahead with merging this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I added one last tweak, and am good with this getting merged.
I figured out how to get the benchmark tests to run the other day. I'm still wrapping my head around the strategy for writing useful tests, but happy to help look for performance issues. My current goal is breaking up some of the stream code into smaller, more modular pieces, so that will help with testing (both unit tests and benchmarks).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely, @mindofmatthew!
Did you manage to make any comparison in the benchmark between before and after based on the benchmarks that already exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet. There are only a few benchmarks for individual pattern functions. I completely agree that this is the process where performance is critical—I want to build a benchmark that tests all of the relevant code so we have a sense of what's adding expense.
Looking into the
trigger
family of functions, I wanted to see how easily it would be to get rid of the redundancy of having to specify the pattern ID, which I've found confusing before. Since Alex seems open to getting rid of it, I went ahead and wrote up a change that would do just that.This introduces a new set of controls that would be stored per-pattern and then merged into the rest of the query controls when the patterns are queried. I could see this mechanism eventually including the pattern ID itself, mute/solo state, as well as other information supplied by the editor (for example, code line number(s) and so on). In theory, the pattern history could also be passed in as a per-pattern control, allowing for transitions to be implemented as patterns themselves.
For now, I wanted to see what you all (@yaxu and maybe @Zalastax and anyone else with an opinion) thought about this approach. There are still a few open questions that I have:
patControls
should probably be saved in history and reverted when a pattern is reverted. That's different from (but I think an improvement over) the current behavior.reset
, but I haven't touched it yet, because I don't really understand it. As far as I can tell,reset
is equivalent toftrigger $ filterWhen (>= 0)
, butftrigger
always places the 0 point slightly before the pattern is started, so the filter has no effect (except, I guess, if the user callsresetCycles
). I can't find much documentation—is this function worth keeping?cf0 "_t_1"
,cf0 "_t_2"
, etc. Is that ever useful? Is it useful to have the ability to trigger a pattern based on when a different pattern was first evaluated?trigger
could also play nice withonce
/first
, but I don't know enough about howonce
/first
are supposed to work to understand how they'd work withtrigger
.trigger
has the same problem thatresetCycles
used to have where events happening immediately at the start of the trigger get skipped by the next pattern query. That's a problem with the existing behavior as well, and should probably be a separate bug.trigger
and friends shouldn't be inControl.hs
, since they're not specific to control patterns. Where should they be?This fixes #968, albeit by changing function signatures and thereby introducing a breaking change. I'm open to suggestions as to when would be a good time to merge/release this. Thanks so much!