Using Max SDK in MIN Devkit Projects: A How To Guide
Hi all,
If you've worked with Min Devkit enough to recognize how awesome it is, you might also have run into a few of its limitations when working with Max's more advanced features such as dictionaries, notifications, UI objects, etc.
Min Devkit is a wrapper around Max SDK, and in fact, the entire Max SDK Base is included in the min-api folder. Mixing and matching Min Devkit and Max SDK takes some care. There are also there are a few essential, undocumented, setup components that need to be addressed before you're able to do anything substantial here. The notes below are assembled from my learnings across several threads in this forum. Thanks especially to 11OLSEN and Rob Ramirez for all the support.
Two Methods for Using Max SDK in Min Devkit Projects
1) Call Max SDK Functions in Min Devkit Source Code
If you want to use a feature of the Max SDK that isn't fully implement in Min, you can call any Max SDK function by prefixing it with c74::max. For example: c74::max::object_notify().
A couple of caveats here:
Be sure to call Max SDK functions in the equivalent section of the Min Object. For if the function needs to be called in the constructor, or message function a Max SDK object, be sure to call it in the constructor or message function of your Min Object.
maxobj() will return a t_object pointer to the present min object. You can use it where a Max SDK function requires a t_object* for the present object.
max-sdk uses common-symbols (e.g. _sym_dictionary, etc) all over the place, but this is not something min exposes or wraps. One solution is to use c74::max::gensym() wherever these symbols are present. But it is also possible to give Min access to these symbols. I prefer this solution because then max-sdk functions will work in Min out of the box without additional tweaking. Two things are required to do this:
first include common_syms.c into your project. This can be achieved by modifying your project's cmakelists to include the file as shown below. Make the change to the cmakelists in the same folder as your source code file, not the cmakelists in the package root. Don't forget to regenerate your solution after modifying any cmakelists file.
set( SOURCE_FILES
${PROJECT_NAME}.cpp
${MAX_SDK_INCLUDES}/common/common_syms.c
)second you must call c74::max::common_symbols_init(); in your object constructor (or at some other initialization point, prior to when the symbols are referenced).
Follow these suggestions and you should be able to leverage most of the Max features supported by MaxSDK inside MinDevkit.
2) Create a Max SDK Object in a Min Devkit Solution
Sometimes calling a few Max SDK functions inside a Min object is not sufficient. Min's support for UI Objects is either incomplete, incompletely documented, or both. You might run into something that can be done in Max SDK that is very difficult to achieve in Min (textfields are a good example). In this case it can be easier just to build a Min SDK object and include it in your MinDevkit package.
There are probably a few ways to do this. Below is my preferred solution:
1) Create a new Min Object the way you normally would.
2) Delete the contents of the source file.
3) Replace the contents of the source file with well-formed Max SDK source code. Ideally, paste in an entire example from the Max-SDK.
4) Somewhere early in the ext_main function you will find the line where class_new() creates the class.
In the simplemax example from Max SDK it looks like this:
c = class_new("simplemax", (method)simplemax_new, (method)simplemax_free, ....
The first argument, the string in quotes, needs to match the name of your file. So if your source file is "MyNewObject.cpp" then the first argument of class_new() should be "MyPatch". eg:
c = class_new("MyNewObject", (method)simplemax_new, (method)simplemax_free, ...
You can replace the name of your template (in this case, simplemax) throughout the code, but the only one that matter is the first argument of class_new(). If you don't do this, your object will appear red in Max and there will be no indicator as to why.
5) You could stop here, but it's possible to go a step further. Delete all the includes from the top of the file. Replace them with:
#include "c74_min.h"
using namespace c74::max;
Now we are literally running Max SDK inside of Min. We could even call Min functions inside it using the c74::min:: prefix. (Very cool in theory, use in practice at your own risk)
Most importantly, the new Max SDK object is running entirely on modern C++ which means you get access to the C++ standard libraries and any third party C++ libs you want to use.
IMPORTANT:
The same concern about common symbols applies. Be sure to include common_syms.c in your cmakelists.txt as described above.
IMPORTANT FOR UI OBJECTS:
UI Objects in Max SDK also require jpatcher_syms.c. Include this as well using the same method.
Your cmakelists.txt for a Min object that uses Max SDK to create a UI Object should have the following:set( SOURCE_FILES
${PROJECT_NAME}.cpp
${MAX_SDK_INCLUDES}/common/commonsyms.c
${MAX_SDK_INCLUDES}/common/jpatcher_syms.c
)
Armed with this, you should be able achieve anything Max SDK is capable of inside a Min Devkit Package.
I hope this is helpful to someone. I offer it as gratitude to the folks who helped me figure this stuff out.