Skip to content
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

Investigate "SelectProjectInstance()" for TODO's missing ability to specify ReaProject #47

Open
GavinRay97 opened this issue Apr 23, 2021 · 3 comments

Comments

@GavinRay97
Copy link
Contributor

GavinRay97 commented Apr 23, 2021

Uncertain what this does (never seen it used in code), but if it switches the internal pointer to the current ReaProject for functions that don't take a ReaProject as a param, maybe it could work to quickly swap to another project + back to the original hackily?

https://www.reaper.fm/sdk/reascript/reascripthelp.html#SelectProjectInstance

So maybe we can fix this -> :(
// TODO-low reaper::InsertTrackAtIndex unfortunately doesn't allow to specify ReaProject :(

Current impl:

// TODO-low Introduce variant that doesn't notify ControlSurface
pub fn insert_track_at(self, index: u32) -> Track {
    self.complain_if_not_available();
    // TODO-low reaper::InsertTrackAtIndex unfortunately doesn't allow to specify ReaProject :(
    let reaper = Reaper::get().medium_reaper();
    reaper.insert_track_at_index(index, TrackDefaultsBehavior::OmitDefaultEnvAndFx);
    reaper.track_list_update_all_external_surfaces();
    let media_track = reaper.get_track(Proj(self.rea_project), index).unwrap();
    Track::new(media_track, Some(self.rea_project))
}

Naive theoretical impl (if SelectProjectInstance does what I hope):

// TODO-low Introduce variant that doesn't notify ControlSurface
pub fn insert_track_at(self, index: u32, project: Project) -> Track {
    self.complain_if_not_available();

    let reaper = Reaper::get().medium_reaper();
    let current_project = Reaper::get().current_project();

    unsafe {
        reaper.low().SelectProjectInstance(project.rea_project);
    }

    reaper.insert_track_at_index(index, TrackDefaultsBehavior::OmitDefaultEnvAndFx);
    reaper.track_list_update_all_external_surfaces();
    let media_track = reaper.get_track(Proj(self.rea_project), index).unwrap();

    unsafe {
        reaper.low().SelectProjectInstance(current_project.rea_project);
    }

    Track::new(media_track, Some(self.rea_project))
}

🙂

@helgoboss
Copy link
Owner

Thanks Gavin! That could be a solution. Just would need to make sure that the function doesn't do anything with the GUI, otherwise this could lead to flickering.

@GavinRay97
Copy link
Contributor Author

Thanks Gavin! That could be a solution. Just would need to make sure that the function doesn't do anything with the GUI, otherwise this could lead to flickering.

I just tested, it actually does visually swap the project tabs =/

gqh7JMveN9

@GavinRay97
Copy link
Contributor Author

GavinRay97 commented May 11, 2021

Spoke with @cfillion about this, he said calling reaper.PreventUIRefresh() at the beginning and end of the function will prevent the flicker! 😃

proj1, _ = reaper.EnumProjects(0)
proj2, _ = reaper.EnumProjects(1)

reaper.PreventUIRefresh(1)

reaper.SelectProjectInstance(proj2)
t = reaper.GetTrack(0, 0) -- 0 = "current project"
_, name = reaper.GetTrackName(t)
reaper.ShowConsoleMsg("Proj2 track 1 name = " .. name)
reaper.SelectProjectInstance(proj1)

reaper.PreventUIRefresh(-1)

Can probably make this a generic/higher-order function or trait, something roughly like this (excuse poor Rust):
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=67923d3fc92d3776473a9af26e6d3072

fn prevent_ui_refresh<FnType, FnReturn>(F: FnType) -> FnReturn
where
    F: Fn() -> FnReturn
{
    reaper.PreventUIRefresh(1);
    let result = f();
    reaper.PreventUIRefresh(-1);
    return result;
}

fn main() {
    let myfunc = |x: i32| -> i32 { x * x };
    
    let result = prevent_ui_refresh(|| {
        myfunc(5)
    });

    println!("Result is {}", result);
}

QWMfgg9V5Y

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants