pattrstorage autorestore and standalones

Dan Nigrin's icon

I'm building a cross-platform standalone, and would like to use the autorestore attribute of pattrstorage to automatically load a .json file that is named the same as the pattrstorage is named.

It works fine when developing my app to have the .json file in the same directory as the .maxpat file, however I haven't figured out where to put the file when the app is built as a standalone. On the Mac so far, I've tried right next to the app itself, as well as within the applications bundle, at /Contents/support/ - neither worked.

Thanks in advance,
Dan

Rob Ramirez's icon

fwiw, for my x-platform standalone max apps, i was never successful in getting things to load with just file names consistently. i found it much easier to just construct an absolute path to my app at initialization, and send that path to all the places in the patch that needed to load files from different folders.

if you are curious, i can try and dig up the patch.

Dan Nigrin's icon

Thanks - I have no problem constructing the absolute path to the app or any of its subfolders. But how does one tell pattrstorage that that path is where the autoload file is??

Dan

Michael Edwards's icon

bump...any info on this problem? I too would like to have pattrstorage data restored in a standalone app. At the moment, the maxpatch saves and restores automatically just fine using a .json file. I've included that file in the app build but it makes no difference at all: the app does not restore data when it's reloaded :/

It would be really nice to be able to give performers an app they can run, instead of them having to download max runtime and then all your patches, setting paths etc. (they hate that in my experience).

Cheers, Michael

Ben Bracken's icon

I would avoid including the .json in the build script and just add it manually to the application's package. As a test, I threw a preset file in /Contents and it works fine here.

-Ben

Michael Edwards's icon

Hi Ben, thanks for this. Just threw the .json file in /Contents but that gave me no joy I'm afraid :/ Maybe there's something in the way I'm using pattrstorage...as I say though, auto-save/restore works fine in Max.

Any chance you could post the patch that works for you?

Best,

Michael

willyc's icon

Hi,

Here is a solution for doing this that I have used. It uses a bit of javascript to work out the absolute path to the /contents/support folder (if running as a standlaone), then explicitly reads/writes the named json file there.

As noted in another thread on this topic, this only works if the pattrstorage object has no reference to the json file when app is built (i.e. do not 'read' the json file before building) My patch only automatically reads when the javascript detects that the patch is running in Max Runtime (i.e. as a standalone) to avoid creating this reference.

(Trying to write to a json file which is 'included' in the application currently doesn't seem to work, throwing a '-1 write error' in the Max window)

Max Patch
Copy patch and select New From Clipboard in Max.

The max patch will require changing a few messages to match your application name in the 'writeSettings' patcher

The javascript (save as getPathToPattrstorageDefaults.js)

// Platform independent initialisation of default file path (for pattrstorage)
// Differentiates between runtime (i.e. standalone) or full Max environment
// Will Crossland

outlets = 2;
setoutletassist(0, "Bang (if standalone)")
setoutletassist(1, "filepath");

function bang()
{
if (0 == max.isruntime) {
outlet (1, jsarguments[2]);
return;
}

if (max.os == "windows") {
outlet (1, max.apppath + "/support/" + jsarguments[2]);
}

if (max.os == "macintosh") {
outlet (1, max.apppath + "/" + jsarguments[1] + ".app/Contents/support/" + jsarguments[2]);
}
outlet(0, "bang");
}

Michael Edwards's icon

nice, thanks willyc

best, michael

tommi's icon

hello,
I have always worked this out with some message to max ("sendapppath"), a [sprintf] and a [prepend "read"].

and it always worked... until today, when it broke down inside one of my applications (while it kept working fine inside another one!).

as I start the standalone the path is sent correctly to [pattrstorage] but the object ignores it.
If the same path symbol is routed also to the right inlet of a message box and I click on it forwarding the message to [pattrstorage], I finally get all my data inside [pattrstorage].

after trying out every kind of priority combination with [deferlow]'s and [delay]'s I realize that I didn't need any of them if I just had a [metro] started and stopped after all the initial settings (including the "read" message to [pattrstorage]) were done.
and the output of [metro] does not even need to be connected to any other object...

does this make any sense to anyone?
I would really appreciate an explanation!

thanks to everyone in advance

cheers

gbravetti's icon

1) Set "fileusagemode" = 1, for patternstorage.
(also choose a proper "savemode", start with 1 for testing purpouses)

2) If you have already created a .json just move it to another place then reload the .maxpat, it has to load with all pressets blank.

3) Compile your standalone to an empty folder and put the previously moved .json file to that folder

Now your pressets changes will be persistent.

Best!

roger.carruthers's icon

I've just been struggling with this problem, and found gbravetti's solution only worked if I dropped the .json file into the app's package/contents, but not if I dropped it into a folder at the same level as the app.
Btw, in the process of finding this out, I uncovered what appears to be a bug in pattrstorage - if I set the fileusagemode attribute to 1 using the inspector, it reverted to 0 when I saved/reopened the patch - and I'm guessing, when building a standalone.
Only by adding it as an argument (i.e. @fileusagemode 1) was I able to save with this intact. Max 6.0.8., Mac OS10.6.8,
Cheers
Roger

Ben Bracken's icon

Hi Roger,

This is not a bug, but it is a little confusing.

You either need to type '@fileusagemode 1' into the object box, or set it to '1' in the inspector, and then 'freeze' the attribute by selecting it, then clicking on 'freeze attribute' in the inspector toolbar.

Thanks,
-Ben

himstregims's icon

@willy

this line in your js:

setoutletassist(0, “Bang (if standalone)”)

it's giving me an illegal character error, and i don't quite understand how that's supposed to work also? i mean, what does the word "standalone" mean in this context ? doesn't it have to have a reference to max somehow - like, max.standalone? and don't you need to do if statements like this:
"if(standalone)" ... sorry, it just really doesn't make any sense to me, but i must be missing something obvious.

søren

nnimar's icon

Rewrite the inverted commas, they are curly in the forum but should be straight in JS ! I don't remember having this issue in the past, is this a forum issue ?

George N.'s icon

Hi,
I have the same problem with Roger regarding attributes in pattrstorage.
If i set for example savemode 2 from inspector, it will be set back to 1 after reopening the patch.
Meanwhile i will have lost any preset.
If i freeze the attributes, then the values won't be set back.However, my presets won't be stored after reopening the patch. Is this not a bug?Anyone else has the same problem?
I use windows 8.1 64 bit, Max 6.1.9.
Thanks.

George N.'s icon

Sorry, i have to make clear something important.
Everything happens only at the FIRST time when i create a .json file.

I finally figured out that the preset object(i use it together with pattrstorage) doesn't show ANYTHING to be saved the FIRST TIME but when i reopen the patch i will be able to see my presets.

Except of that, there is a chance of Max-crash when i create a new json file with savemode 2, after i've saved several presets.

If anyone has a clue whats going on...would be appreciated...thanks