Old 10-04-2019, 08:38 AM   #1
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default Resources for making C++ extensions?

I was thinking of trying to do some extensions in C++. After a bit of searching it seems to be tough to find information about this. A lot of the resources seem to be a bit outdated.

I was wondering if anyone can post any helpful resources or info about making C++ extensions. Stuff that you would consider a must read would be very helpful to me. Thanks for any help!
Alkamist is offline   Reply With Quote
Old 10-04-2019, 09:03 AM   #2
mespotine
Human being with feelings
 
mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig, Germany
Posts: 1,621
Default

Julian Sader's extension is probably a good starting point. It's structured very simple.

You can also read his threads, where he asked questions about doing an extension, as he was going through the same obstacles.
And it's probably the most recent resource on that.

If I ever have the time, I will dig through this to write a tutorial on extension-programming, but hadn't yet...
__________________
Ultraschall-API - a Lua-functions-library4Reaper: https://forum.cockos.com/showthread....98#post2067798
Reaper Internals - Developerdocs4Reaper: https://forum.cockos.com/showthread.php?t=207635
mespotine is offline   Reply With Quote
Old 10-04-2019, 09:24 AM   #3
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by mespotine View Post
Julian Sader's extension is probably a good starting point. It's structured very simple.

You can also read his threads, where he asked questions about doing an extension, as he was going through the same obstacles.
And it's probably the most recent resource on that.

If I ever have the time, I will dig through this to write a tutorial on extension-programming, but hadn't yet...
Thanks for the input! I'll take a look at that and see what I can learn.
Alkamist is offline   Reply With Quote
Old 10-04-2019, 09:39 AM   #4
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

I have a minimal extension plugin example, which I've updated fairly recently :

https://github.com/Xenakios/reaper_very_minimal

The actual extension code is in the main.cpp file. The other files are support files for building the plugin.

It's not literally the most minimal extension example that could be done, but since the most usual use case is for the extension to add new actions into Reaper, the example has that included. I've tried to add useful comments into the code. (Including the .bat file that explains the classic issue about how the built .dll must be named in order for Reaper to scan it as an extension plugin.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-04-2019, 09:55 AM   #5
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
I have a minimal extension plugin example, which I've updated fairly recently...
That looks fantastic! That will really help me get started, thank you!
Alkamist is offline   Reply With Quote
Old 10-04-2019, 11:29 AM   #6
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
I have a minimal extension plugin example, which I've updated fairly recently...
I was able to get it compiled and running.

I would like to do stuff with a GUI though. Judging by this thread, it seems like that might be really complicated.

Do you have any tips for doing stuff with a GUI?
Alkamist is offline   Reply With Quote
Old 10-04-2019, 11:34 AM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
it seems like that might be really complicated.

Do you have any tips for doing stuff with a GUI?
Unfortunately, it is very involved. I have managed to use the Juce framework to some extent within Reaper extensions, but using Juce has its own complications and limitations.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-04-2019, 11:44 AM   #8
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
Unfortunately, it is very involved. I have managed to use the Juce framework to some extent within Reaper extensions, but using Juce has its own complications and limitations.
Juce sounds like a decent place to start. I'll look into it and see if I can get anything to work. Unfortunately I'm no C++ guru so this will likely be an incredibly difficult task.
Alkamist is offline   Reply With Quote
Old 10-04-2019, 11:51 AM   #9
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
Juce sounds like a decent place to start. I'll look into it and see if I can get anything to work. Unfortunately I'm no C++ guru so this will likely be an incredibly difficult task.
Because building stuff with Juce and integrating Juce with Reaper is so involved, I would grudgingly suggest first trying the Windows/Microsoft win32 API instead. (Which is what Reaper itself uses and Cockos has the Swell library that implements parts of win32 for macOS and Linux.) What kind of GUI do you want to do?
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-04-2019, 12:19 PM   #10
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
Because building stuff with Juce and integrating Juce with Reaper is so involved, I would grudgingly suggest first trying the Windows/Microsoft win32 API instead. (Which is what Reaper itself uses and Cockos has the Swell library that implements parts of win32 for macOS and Linux.) What kind of GUI do you want to do?
I'll have to look into that as well. If you have any examples you can point me to that use the win32 API that would help a lot.

What I want to do is create a pitch correction editor. So it would have the ability to have buttons, a file menu, drawing capability to draw graphical things like lines, rectangles, and circles. Also getting input and the location of the mouse and things like that are important. Basically, I could do pretty much what I need with the functionality you get in Lua.

I've already done all of this in Lua, I just really hate working with a GUI limited to 30 fps; it feels really clunky to me.

The other reason I'm looking into C++ is because eventually I want to mess around with machine learning, to try to get it to automatically do pitch corrections for you that you can fine-tune later. Trying to do something like this with Python would probably be a nightmare as far getting it installed for other users.
Alkamist is offline   Reply With Quote
Old 10-04-2019, 12:39 PM   #11
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
I've already done all of this in Lua, I just really hate working with a GUI limited to 30 fps; it feels really clunky to me.
30 FPS should be plenty enough (people are fine with TV and movies at that frame rate or below...), are you sure it's just about the general GUI frame rate? Of course if you do expensive calculations/operations in the GUI thread, the GUI update speed will suffer...(And even C++ doesn't necessarily help you there, I've had plenty of occasions when I get absolutely crawling GUI frame rates with C++...)

One approach you could take is to keep the GUI code in Lua ReaScript, but implement the expensive operations with C++.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-04-2019, 01:01 PM   #12
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
30 FPS should be plenty enough (people are fine with TV and movies at that frame rate or below...), are you sure it's just about the general GUI frame rate? Of course if you do expensive calculations/operations in the GUI thread, the GUI update speed will suffer...(And even C++ doesn't necessarily help you there, I've had plenty of occasions when I get absolutely crawling GUI frame rates with C++...)

One approach you could take is to keep the GUI code in Lua ReaScript, but implement the expensive operations with C++.
30 fps is manageable, however, I tend to be way more picky than most people. I have a 144 hz monitor and play a lot of video games, so 30 fps to me is horrendous.

The calculations do slow the GUI down. I basically have to do large amounts of iterating through time/pitch data and operations on these points. I like having the graphical representation of the pitch data update in real-time when editing. Even iterating through ~500 points can slow the GUI down a ton.

To get around this I had to write all sorts of optimizations to get it to run in real time. It can probably be done way better since I'm not an expert, but it just quickly got unruly. I don't really have experience writing things on different threads, so I'm probably doing all of it on the GUI thread.

I didn't know it was possible to mix and match C++ and Lua. How would you go about doing that?
Alkamist is offline   Reply With Quote
Old 10-04-2019, 02:55 PM   #13
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 6,060
Default

iPlug2 has also a template for REAPER extension.
X-Raym is offline   Reply With Quote
Old 10-04-2019, 03:48 PM   #14
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by X-Raym View Post
iPlug2 has also a template for REAPER extension.
I'll look into this. Currently using the win32 api isn't working so well for me since I don't have any experience with it.
Alkamist is offline   Reply With Quote
Old 10-06-2019, 11:42 AM   #15
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
I don't really have experience writing things on different threads, so I'm probably doing all of it on the GUI thread.

I didn't know it was possible to mix and match C++ and Lua. How would you go about doing that?
Everything in ReaScript happens on the GUI thread. There are no facilities to run stuff in real different threads. (Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.)

You can do a C++ plugin that exports functions for use with ReaScript. But of course even with those, if the execution speed isn't fast enough, you will get GUI lags, if you don't explicitly implement running the functions in other threads or do some other tricks that keep the GUI responsive.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-06-2019, 01:07 PM   #16
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,355
Default

Quote:
Originally Posted by Xenakios View Post
Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.
They specifically don't call them "threads" for that reason - Lua calls them coroutines, and they're the same ideas as the generators that were recently introduced to Javascript. Basically a function that can pause itself and wait to be called again, so you could tell it "Here are 100 items to process. On each script loop, process 5 of them and then take a break."
Lokasenna is online now   Reply With Quote
Old 10-06-2019, 01:12 PM   #17
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
Everything in ReaScript happens on the GUI thread. There are no facilities to run stuff in real different threads. (Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.)

You can do a C++ plugin that exports functions for use with ReaScript. But of course even with those, if the execution speed isn't fast enough, you will get GUI lags, if you don't explicitly implement running the functions in other threads or do some other tricks that keep the GUI responsive.
I see. With that in mind, working with C++ extensions seems to be what I want. A lot of my ReaScript ideas end up being doable in Lua, but tend to be clunky given the restrictions ReaScript has.

I'm currently just trying to get settled with finding a good way to get keyboard/mouse input, and a good way to do GUI stuff. I really dislike the idea of using the Win32 library directly. The documentation for my purposes is incredibly sparse and it just seems like a pain to work with to do simple things.

I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated. I'm really new with all of these compiler settings and CMake shenanigans. There's also a ton of information to sift through.

If you have any advice for this I would be grateful! I'm not sure whether I should try to be making a batch file to run cl.exe like you did in your example, or if I should be trying to make a VS2019 project file and hook everything up from there. I don't know if I should just include the SFML source code, or if I need to build it to a dynamic or static library.

Ideally I could just have people install my extension and not have to worry about any external dependencies.

I'm sure I can figure it out eventually, it will just take a lot of patience with google searches.
Alkamist is offline   Reply With Quote
Old 10-06-2019, 01:20 PM   #18
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,355
Default

It would definitely be worth trying to split your processing up with a coroutine to see if that gets the performance somewhere reasonable. They're fairly straightforward to use; if your existing code uses a loop, it's just a few extra commands.

https://www.tutorialspoint.com/lua/lua_coroutines.htm

As far as GUI, might I suggest my Lua library? (Link in my signature)
Lokasenna is online now   Reply With Quote
Old 10-06-2019, 01:22 PM   #19
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Lokasenna View Post
They specifically don't call them "threads" for that reason - Lua calls them coroutines
Yes, it's confusing because the underlying primitive type in Lua is called a "thread", while what that is actually used for is coroutines. (Coroutines are not well supported with C++ at the moment, so Lua is actually a bit more powerful in that regard for implementing some things natively.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-06-2019, 01:25 PM   #20
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,355
Default

Quote:
Originally Posted by Xenakios View Post
Yes, it's confusing because the underlying primitive type in Lua is called a "thread", while what that is actually used for is coroutines.
I hadn't noticed that; it does seem like silly choice.
Lokasenna is online now   Reply With Quote
Old 10-06-2019, 01:51 PM   #21
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 9,114
Default

@Alkamist
Maybe looking into iPlug2 (as has been mentioned) might indeed be a good starting point as it has a Reaper extension example all set up already?

https://github.com/iPlug2/iPlug2/tre...eaperExtension
nofish is offline   Reply With Quote
Old 10-06-2019, 01:52 PM   #22
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
I really dislike the idea of using the Win32 library directly. The documentation for my purposes is incredibly sparse and it just seems like a pain to work with to do simple things.

...

I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated.

...

whether I should try to be making a batch file to run cl.exe like you did in your example, or if I should be trying to make a VS2019 project file and hook everything up from there. I don't know if I should just include the SFML source code, or if I need to build it to a dynamic or static library.
The win32 API is very well documented, each API function has a long explanation at the Microsoft web pages. It will require some effort to get a basic GUI happening at first, though...Also, if you want your code compiled for macOs and/or Linux too, you will have to use a limited subset of the win32 API, as Cockos's Swell library in WDL only implements a small portion of it.

If you are going to use SFML, there's probably no-one who can help you with that when doing Reaper extensions, I am not aware of anyone who would have used that.

But if you are going to use that anyway, you should attempt to build it directly with your project, if at all possible. Dealing with static libraries, or even worse, dynamic libraries, can be quite a headache.

You will of course want to use Visual Studio for large scale development on Windows. The simple example I created used a .bat file for the build because Visual Studio is itself a complicated thing that doesn't directly have to do with Reaper extensions. (And it's kind of a pain to create a Visual Studio project that will work for sure on other people's systems...)

Like was suggested above, maybe trying out IPlug2 could be worth it. I haven't personally tried doing a Reaper extension with it yet.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/

Last edited by Xenakios; 10-06-2019 at 02:07 PM.
Xenakios is online now   Reply With Quote
Old 10-06-2019, 02:09 PM   #23
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by nofish View Post
@Alkamist
Maybe looking into iPlug2 (as has been mentioned)...
IPlug2 seems like a decent option. I was able to get the example up and running. I'm having trouble figuring out how to use it though. I not only want to do GUI stuff, but also have the ability to get user key presses even when a GUI window isn't open. From my initial inspection, it seems like user input is tied to having a window open. I could be wrong about that however.

Quote:
Originally Posted by Xenakios View Post
The win32 API is very well documented, each API function has a long explanation at the Microsoft web pages. It will require some effort to get a basic GUI happening at first, though...Also, if you want your code compiled for macOs and/or Linux too, you will have to use a limited subset of the win32 API, as Cockos's Swell library in WDL only implements a small portion of it.
It's well documented on its own, but not for use with reaper extensions. I have no idea where to put any of their example code with respect to opening a window in a reaper extension. All of their documentation seems to assume you are creating a standalone desktop app.

I would like my code to work cross-platform. Is there some sort of documentation on what parts of the win32 I'm allowed to use to maintain compatibility?
Alkamist is offline   Reply With Quote
Old 10-06-2019, 02:25 PM   #24
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,831
Default

Quote:
Originally Posted by Alkamist View Post
It's well documented on its own, but not for use with reaper extensions. I have no idea where to put any of their example code with respect to opening a window in a reaper extension. All of their documentation seems to assume you are creating a standalone desktop app.
Describe a dialog in a resource file (or construct it dynamically) and open it using functions such as CreateDialogParam and DialogBoxParam (for modeless and modal windows respectively).

https://docs.microsoft.com/en-us/win...x/dialog-boxes

Quote:
Originally Posted by Alkamist View Post
I would like my code to work cross-platform. Is there some sort of documentation on what parts of the win32 I'm allowed to use to maintain compatibility?
These are the functions SWELL supports: https://github.com/justinfrankel/WDL...ll-functions.h. Some are exclusive to SWELL (eg. BrowseForFiles).

Quote:
Originally Posted by Alkamist View Post
I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated. I'm really new with all of these compiler settings and CMake shenanigans. There's also a ton of information to sift through.
There are projects such as Microsoft's vcpkg that are designed to help with this. vcpkg can build many libraries with a single command (it has a sfml package in its repository) and integrates into CMake (or MSBuild-based projects).

Quote:
Originally Posted by Alkamist View Post
I not only want to do GUI stuff, but also have the ability to get user key presses even when a GUI window isn't open.
The REAPER API allows this: https://forum.cockos.com/showthread.php?p=2081123.

Last edited by cfillion; 10-06-2019 at 03:03 PM.
cfillion is offline   Reply With Quote
Old 10-06-2019, 02:48 PM   #25
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post
also have the ability to get user key presses even when a GUI window isn't open.
That is a very bad idea, if the key presses are not supposed to be launching Reaper actions. Users will want to have their usual keyboard shortcuts working when a plugin window isn't in focus. (If key presses are supposed to launch actions, the user should be in full control of that. The design I've decided on is that extension plugins won't register any keyboard shortcuts by default. The user will do it, if he wishes so.)
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-06-2019, 03:01 PM   #26
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by cfillion View Post
Describe a dialog in a resource file...
Thank you for your super helpful post. I'll explore all the things you mentioned.

Quote:
Originally Posted by Xenakios View Post
That is a very bad idea, if the key presses are not supposed to be launching Reaper actions. Users will want to have their usual keyboard shortcuts working when a plugin window isn't in focus. (If key presses are supposed to launch actions, the user should be in full control of that. The design I've decided on is that extension plugins won't register any keyboard shortcuts by default. The user will do it, if he wishes so.)
I wasn't super clear on my intention with that. I don't mean that I want the extension to be doing things in the background based on keyboard presses.

Basically I want to remake my Zoom Tool script I did. The way it works is you bind it to a hotkey, which activates it, and while you continue to hold the button it will do zooming based on your mouse movement. When you let go of the button, it stops. None of this opens a graphics window.

So basically I need a way to tell when the user does a key up to tell the program to stop zooming. Ideally it would be the same key that activated the script in the first place.
Alkamist is offline   Reply With Quote
Old 10-06-2019, 03:24 PM   #27
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 9,114
Default

Quote:
Originally Posted by Alkamist View Post
So basically I need a way to tell when the user does a key up to tell the program to stop zooming. Ideally it would be the same key that activated the script in the first place.
There are some actions in SWS that work like this ('continous actions'), e.g.
SWS/BR: Freehand draw envelope while snapping points to left side grid line (perform until shortcut released).

https://github.com/reaper-oss/sws/bl...nuousActions.h
https://github.com/reaper-oss/sws/bl...ousActions.cpp
nofish is offline   Reply With Quote
Old 10-06-2019, 03:47 PM   #28
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by nofish View Post
There are some actions in SWS that work like this ('continous actions'), e.g.
SWS/BR: Freehand draw envelope while snapping points to left side grid line (perform until shortcut released).

https://github.com/reaper-oss/sws/bl...nuousActions.h
https://github.com/reaper-oss/sws/bl...ousActions.cpp
That seems like what I would want. I'll look into it, thanks for the tip!
Alkamist is offline   Reply With Quote
Old 10-07-2019, 09:45 AM   #29
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

I have some more questions regarding C++ extensions for Reaper:

- It looks to me like the SWS extension uses a precompiled header. Is that something I should be doing? If so, how would I go about getting that set up?

- What is the workflow when wanting to use some code someone else has written? For instance, say I want to use something someone has done in the SWS extension; should I just copy the source code files and paste them into my extension directory?

- What C++ standard should I be using? I see a lot of older looking C++ code while browsing around extension source code. Is there some sort of restriction I should be aware of?

- What are some helpful classes/wrappers people have done for working with Reaper stuff? I would like to avoid reinventing the wheel wherever I can.
Alkamist is offline   Reply With Quote
Old 10-07-2019, 10:25 AM   #30
Wanda Previous
Human being with feelings
 
Join Date: May 2010
Posts: 315
Default

Here's what ya might want to do - but it's kind of advanced and might be overly-complicated.

Create a minimal Reaper plug-in (a DLL), and a traditional GUI-based Win32 applicaton (an EXE). Use two message-only windows - one in the DLL, and one in the EXE for inter-process communication. You will do most of your work in the EXE then pass the results back to reaper using window messages. You'll have to create a new thread inside the plug-in's initialization routine, and then in that new thread ... that is where you create the window and pump the message loop.

Let me know if you understand me so far. Maybe you can guess where I'm gong with this. And even if you don't, maybe you can take the ideas I've given you and figure the rest out for yourself.
Wanda Previous is offline   Reply With Quote
Old 10-07-2019, 10:32 AM   #31
Wanda Previous
Human being with feelings
 
Join Date: May 2010
Posts: 315
Default

Btw - I forgot to mention that you'll have to call CreateProcess() to launch your EXE.



There. I said it.
Wanda Previous is offline   Reply With Quote
Old 10-07-2019, 10:34 AM   #32
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,831
Default

Quote:
Originally Posted by Alkamist View Post
- It looks to me like the SWS extension uses a precompiled header. Is that something I should be doing? If so, how would I go about getting that set up?
Not required (also SWS only does that on Windows). It can help reduce compilation time when including large complex files over and over in many compilation units.

Quote:
Originally Posted by Alkamist View Post
- What C++ standard should I be using? I see a lot of older looking C++ code while browsing around extension source code. Is there some sort of restriction I should be aware of?
Which features you can use depends on which operating system versions you are targeting. For instance, a C++11 standard library is only available on macOS since 10.7 (libc++).

We recently started using C++11 syntax in SWS ("next" branch), but it's limited to an older standard library because it's targeting macOS 10.5.

Quote:
Originally Posted by Alkamist View Post
- What is the workflow when wanting to use some code someone else has written? For instance, say I want to use something someone has done in the SWS extension; should I just copy the source code files and paste them into my extension directory?
It depends what/how much I would say. Most source files from SWS would not be very useful once extracted (often easier/better to just rewrite the desired feature).

Quote:
Originally Posted by Alkamist View Post
- What are some helpful classes/wrappers people have done for working with Reaper stuff? I would like to avoid reinventing the wheel wherever I can.
I have some wrappers in ReaPack (under LGPL) for some Win32 stuff, timer-based asynchronous cross-thread events, API function registration, action registration that should be reusable. It uses C++17 features.

ConfigVar classes coming soon in SWS (under MIT).

Last edited by cfillion; 10-07-2019 at 10:50 AM.
cfillion is offline   Reply With Quote
Old 10-07-2019, 10:56 AM   #33
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by cfillion View Post
Not required (also SWS only does that on Windows)...
Thanks for the info!

Quote:
Originally Posted by Wanda Previous View Post
Here's what ya might want to do - but it's kind of advanced and might be overly-complicated.

Create a minimal Reaper plug-in (a DLL), and a traditional GUI-based Win32 applicaton (an EXE)...
That's probably a bit over my head at the moment unfortunately. Currently, I can't even get a minimal extension to build in Visual Studio, I can only do it with Xenakios' batch file.

I know a decent bit of raw C++ as far as the language is concerned, but I am completely new to doing any development like this. I am entirely self-taught so I lack a lot of foundation in areas like this.

If I can't get what I'm trying to do working, I'll try and work out your post and see if I can do it.
Alkamist is offline   Reply With Quote
Old 10-07-2019, 12:19 PM   #34
moss
Human being with feelings
 
moss's Avatar
 
Join Date: Mar 2007
Location: Germany
Posts: 410
Default

Quote:
Originally Posted by cfillion View Post
Describe a dialog in a resource file (or construct it dynamically) and open it using functions such as CreateDialogParam and DialogBoxParam (for modeless and modal windows respectively).

https://docs.microsoft.com/en-us/win...x/dialog-boxes



These are the functions SWELL supports: https://github.com/justinfrankel/WDL...ll-functions.h. Some are exclusive to SWELL (eg. BrowseForFiles).
Interesting thread! Is it possible to create a dynamic dialog on the fly with SWELL? If yes, is there an example?
moss is online now   Reply With Quote
Old 10-07-2019, 12:37 PM   #35
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,831
Default

This is how dialogs are constructed at runtime by SWELL:
Code:
#include <swell/swell.h>
#include <swell/swell-dlggen.h>

// arbitrary unique identifiers
enum DialogID { IDD_NETCONF_DIALOG = 100 };
enum ControlID { IDC_LABEL = 200, IDC_PROXY, IDC_LABEL2, IDC_STALETHRSH, IDC_VERIFYPEER };

// Register a new dialog ID
// This SWELL_DialogRegHelper object must live forever
// (or update SWELL_curmodule_dialogresource_head when destructing)
static SWELL_DialogRegHelper Register_IDD_NETCONF_DIALOG{
  &SWELL_curmodule_dialogresource_head, [](HWND view, int wflags)
  {
    // Construct a new dialog (HWND view)
    SWELL_MakeSetCurParms(1.8, 1.8, 0, 0, view, false, !(wflags&8));

    SWELL_MakeLabel(-1, "Proxy:", IDC_LABEL, 5, 8, 20, 10, 0);
    SWELL_MakeEditField(IDC_PROXY, 30, 5, 185, 14, ES_AUTOHSCROLL);
    SWELL_MakeLabel(-1, "Example: host:port, [ipv6]:port or scheme://host:port",
      IDC_LABEL2, 30, 22, 190, 10, 0);
    SWELL_MakeCheckBox("&Refresh index cache when older than one week",
      IDC_STALETHRSH, 5, 33, 220, 14, BS_AUTOCHECKBOX | WS_TABSTOP);
    SWELL_MakeCheckBox("&Verify the authenticity of SSL/TLS certificates (advanced)",
      IDC_VERIFYPEER, 5, 45, 220, 14, BS_AUTOCHECKBOX | WS_TABSTOP);
    SWELL_MakeButton(1, "&OK", IDOK, 132, 61, 40, 14, 0);
    SWELL_MakeButton(0, "&Cancel", IDCANCEL, 175, 61, 40, 14, 0);
  },
  IDD_NETCONF_DIALOG, 4|8, "Network settings", 220, 80, 1.8
};

// IDD_NETCONF_DIALOG can now be used

Last edited by cfillion; 10-07-2019 at 02:03 PM.
cfillion is offline   Reply With Quote
Old 10-07-2019, 12:57 PM   #36
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by cfillion View Post
I got your example working with simply displaying a message with the key state to the console.

If you don't mind explaining, how would you go about making an action start a loop that is broken when this detects a key up?
Alkamist is offline   Reply With Quote
Old 10-07-2019, 01:53 PM   #37
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,831
Default

This uses REAPER's global 30Hz timer (most likely the same as reaper.defer in Lua scripts):
Code:
static void loop()
{
  // do something
}

// Start the loop:
//plugin_register("timer", reinterpret_cast<void *>(&loop));

// Stop the loop:
//plugin_register("-timer", reinterpret_cast<void *>(&loop));
cfillion is offline   Reply With Quote
Old 10-07-2019, 01:57 PM   #38
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by cfillion View Post
This uses (most likely) the same 30Hz timer as reaper.defer in Lua scripts:
Code:
static void loop()
{
  // do something
}

// Start the loop:
//plugin_register("timer", reinterpret_cast<void *>(&loop));

// Stop the loop:
//plugin_register("-timer", reinterpret_cast<void *>(&loop));
Thanks for the help. I'll see if I can get it working.

That's a shame if it's stuck on 30 Hz. It's not really worth rewriting my script if that's the case.
Alkamist is offline   Reply With Quote
Old 10-07-2019, 02:13 PM   #39
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 7,962
Default

Quote:
Originally Posted by Alkamist View Post

That's a shame if it's stuck on 30 Hz. It's not really worth rewriting my script if that's the case.
You can use the win32 API SetTimer function directly to get a faster timer on the GUI thread. But of course that doesn't necessarily help anything if you do something expensive in the timer callback function, you would get a sluggish GUI just the same.
__________________
For info on SWS Reaper extension plugin (including Xenakios' previous extension/actions) :
http://www.sws-extension.org/
https://github.com/Jeff0S/sws
--
Xenakios blog (about HourGlass, Paul(X)Stretch and λ) :
http://xenakios.wordpress.com/
Xenakios is online now   Reply With Quote
Old 10-07-2019, 02:40 PM   #40
Alkamist
Human being with feelings
 
Join Date: Dec 2011
Posts: 500
Default

Quote:
Originally Posted by Xenakios View Post
You can use the win32 API SetTimer function directly to get a faster timer on the GUI thread. But of course that doesn't necessarily help anything if you do something expensive in the timer callback function, you would get a sluggish GUI just the same.
So if I use an action to start a loop that persists until a key up is received, it has to be on the GUI thread? Or are all actions on the GUI thread or something?
Alkamist is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 12:39 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.