In this script, the line just before the saveToFile() line gets printed, but the method stops there, and the file doesn't get written. I can't figure out why the method just stops executing. The call is in the SaveBank() method, which gets called from processIdle() after the flag 'gReadyToWrite' is set via the save input button in the callback. It's the third-to-last method, before callback() and processIdle().
Interestingly, if I reset the flag AFTER calling the saveBank() method, it saves continously!! It either doesn't save, or saves continously, I can't get it to happen just once. Also, if I skip the flag, and call it directly from callback instead of processIdle, it also doesn't save.
This is with the latest version (I updated because there was mention of a file issue in the release notes. But this happens the same way with both versions....)
I have several similar scripts that are reading and writing fine via the same methods, and I can't figure out what's different with this one. But this behaves the same way in an empty WKP, so it's something with the script.
Here is the whole script:
Code: Select all
const DBUG_ON = TRUE;
const CHAN = 'TEST';
const PRESET_FOLDER = 'PRESETS';
const TEXT_TAGS = ['details'];
const INT_TAGS = ['midi-in-ch','transpose','audio-in','cc-to-pitch','mw-midi','at-midi','params-on']; //+ param nums + param channels, 8 buttons, 4 encoder button pairs, 8 encoders
const FLOAT_TAGS = ['input-trim','output-trim','hue','saturation'];
const TYP_STR = 0; const TYP_INT = 1; const TYP_FLT = 2;
//subpatches
const TAGS = ['param','text','param','step','param','range.maxpos','range.minpos'];
const SUBS = ['renaming','renaming','macros','macros','controls','controls','controls'];
const TYPES = [TYP_INT, TYP_STR, TYP_INT, TYP_INT, TYP_INT, TYP_FLT, TYP_FLT];
const POLYS = [6,6,4,4,4,4,4];
//added to address of subpatches above
const SUBPATCH = 'instparamctl.1.';
//added to all addresses
const PREFIX = 'patch.sidepanel.1.bankdata.1.';
const EXTENSION = '.bank';
const DTAG = 'bankManager_';
const DELIMITER = '=';
const DOT = '.';
const NADA = '';
var dataPathIN,recallIN,saveIN,channelIN,bankIN, instIN, bankLoadedOUT: tParameter;
var gDataString, gTags, gAddresses, gTypes: tStringlist;
var i,j: integer;
var gReadyToWrite, gReadyToLoad, gListsCreated : boolean;
procedure init;
var i: integer;
begin
SetModuleColor($808080+496999);
dataPathIN := CreateParam('data path',ptTextField,pioInput);
recallIN := CreateParam('recall',ptButton,pioInput);
saveIN := CreateParam('save',ptButton,pioInput);
instIN := CreateParam('inst name',ptTextField, pioInput);
bankIN := CreateParam('bank name',ptTextField, pioInput);
bankLoadedOUT := CreateParam('bank loaded', ptDataField, pioOutput);
gDataString.create;
gTags.create;
gAddresses.create;
gTypes.create;
end;
procedure destroy; begin gDataString.free; gTags.free; gAddresses.free; gTypes.free; end;
procedure debug(s: string); begin if DBUG_ON then strace(DTAG + CHAN + ': ' +s); end;
procedure iDebug(s: string; num : integer) begin debug(s + ' ' + intToStr(num)); end;
procedure tsDebug(ts: tStringlist; note: string);
var i: integer;
begin
Debug(note);
for i := 0 to ts.count - 1 do debug(intToStr(i) + ': ' + ts.getStrings(i));
end;
function stringsMatch(string1:string;string2:string) : boolean;
begin
//debug('matching strings:' + string1 + ', '+string2);
result := (upperCase(trim(string1)) = uppercase(trim(string2)));
end;
function getBankPath() : string;
var path: string;
begin
path := dataPathIN.asString + instIN.asString + PathDelim() + bankIN.asString + EXTENSION;
//debug('bank path = ' + path);
result := path;
end;
function getDataForLine(s: string) : string;
var data: string;
begin
data := copy(s,pos(Delimiter,s) + 1,length(s));
//debug('got data for line: ' + data);
result := data;
end;
function getTagForLine(s: string) : string;
var tag: string;
begin
tag := copy(s, 1, pos(DELIMITER,s) - 1);
//debug('got line: ' + s);
//debug('got tag for line: ' + tag);
result := tag;
end;
function extractData(data : tStringlist; tag: string) : string;
var line: string;
var i: integer;
begin
for i := 0 to data.count - 1 do
begin
if stringsMatch(tag, getTagForLine(data.getStrings(i))) then
result := getDataForLine(data.getStrings(i));
end;
end;
procedure updateLists(tag: string; discard: string; subpatch: string; dtype: integer);
begin
gTags.add(subpatch + tag);
gAddresses.add(PREFIX + discard + subpatch + tag);
gTypes.add(intToStr(dtype));
end;
procedure createLists();
var name, paramName: string;
paramNum: integer;
begin
gTags.clear;
gAddresses.clear;
gTypes.clear;
for i := 0 to (length(INT_TAGS) - 1) do updateLists(INT_TAGS[i], NADA, NADA, TYP_INT);
for i := 0 to (length(FLOAT_TAGS) - 1) do updateLists(FLOAT_TAGS[i], NADA, NADA, TYP_FLT);
for i := 0 to (length(TEXT_TAGS) - 1) do updateLists(TEXT_TAGS[i], NADA, NADA, TYP_STR);
//for subpatches
for i := 0 to (length(TAGS) - 1) do
for j := 1 to (POLYS[i]) do updateLists(TAGS[i],SUBPATCH, SUBS[i] + DOT + intToStr(j) + DOT, TYPES[i]);
//for i := 0 to (gAddresses.count - 1) do begin debug(gAddresses.getStrings(i)); debug(gTags.getStrings(i)); end;
end;
procedure sendData(idx: integer; data: string);
begin
//debug(gAddresses.getStrings(idx));
//debug( data );
if StrToInt(gTypes.getStrings(idx)) = TYP_INT then
setObjectInteger(gAddresses.getStrings(idx), strToInt(data))
else if strToInt(gTypes.getStrings(idx)) = TYP_FLT then
setObjectFloat(gAddresses.getStrings(idx), strToFloat(data))
else if strToInt(gTypes.getStrings(idx)) = TYP_STR then
setObject(gAddresses.getStrings(idx), data);
end;
procedure recall();
begin
gReadyToLoad := TRUE;
end
procedure saveBank();
var int: integer;
var fl: single;
var st: string;
begin
debug('saving:' + getBankPath());
gDataString.clear;
for i := 0 to (gTags.count - 1) do
if StrToInt(gTypes.getStrings(i)) = TYP_INT then
begin
int := getObjectInteger(gAddresses.getStrings(i));
gDataString.add(gTags.getStrings(i) + DELIMITER + intToStr(int));
end
else if strToInt(gTypes.getStrings(i)) = TYP_FLT then
begin
fl := getObjectFloat(gAddresses.getStrings(i));
gDataString.add(gTags.getStrings(i) + DELIMITER + floatToStr(fl));
end
else if strToInt(gTypes.getStrings(i)) = TYP_STR then
begin
st := getObject(gAddresses.getStrings(i));
gDataString.add(gTags.getStrings(i) + DELIMITER + st);
end
//tsDebug(gDataString, 'data: ');
debug('string created'); //Prints out fine.
gDataString.SaveToFile(getBankPath()); // This is a valid path, in my case, from trace: [68790] bankManager_1: saving:D:\HH 5\RIG\PRESETS\Keyscape\Pianos.bank
debug('file saved'); //THIS LINE IS NEVER REACHED
end
procedure Callback(n:integer);
begin
iDebug('callback input: ',n);
//set the lists up first thing
if not gListsCreated then
begin
createLists;
gListsCreated := TRUE;
debug('created lists');
bankLoadedOUT.asInteger(1); //we turn this off during loading, and back on when done
end;
CASE n of
saveIN: if (saveIN.asInteger() > 0) then
gReadyToWrite := TRUE;
recallIN: if (recallIN.asInteger > 0) and FileExists(getBankPath()) then
begin
gReadyToLoad := TRUE;
bankLoadedOUT.asInteger(0);
end;
end;
end;
Procedure processidle;
var i,j: integer;
var line, tag: string;
BEGIN
if gReadyToWrite then
begin
gReadyToWrite := FALSE; //if I put this AFTER saveBank() it saves the bank continuously!!!
saveBank();
end;
if gReadyToLoad then
begin
debug('recalling: ' + getBankPath());
gDataString.clear;
gDataString.loadfromFile(getBankPath());
for i := 0 to (gDataString.count - 1) do
begin
line := gDataString.getStrings(i);
//debug('line = ' + line);
//check each tag in our list to match with the dataStringIn line
for j := 0 to (gTags.count - 1) do
begin
tag := gTags.getStrings(j);
//debug('tag found: ' + tag);
if stringsMatch(tag,getTagForLine(line)) then
sendData(j, getDataForLine(line));
end;
end;
gReadyToLoad := FALSE;
bankLoadedOUT.asInteger(1);
end
END