Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Control Page Load Order

Is there a way to ensure that your api pages are loaded in a certain order? I have a potential race condition in a series of scripts I am using. Page A: General Commands General = General || {}; General.CreateCharacter = function(characterName){ return createObj('character', { name : characterName }); } Page B: Initializer Initializer = Initializer || {}; Initializer.ToDoList = Initializer.ToDoList || []; Initializer.Installer = Initializer.Installer || {}; Initializer.Installer.ToDoList = Initializer.Installer.ToDoList || []; Initializer.Initialize = function(){ var LoadItems = []; var installedListHandout = General.GetOrCreateHandout('Installed Modules'); installedListHandout.get('notes',function(installedTable){ var installedArray = []; if(installedTable != ''){ installedArray = General.TableToJSONArray(installedTable); } _.each(Initializer.Installer.ToDoList,function(pendingModule){ var triggerAction = "Install"; _.each(installedArray,function(installedModule){ if(installedModule.Name == pendingModule.Name && installedModule.Version == pendingModule.Version){ triggerAction = "None"; } else if(installedModule.Name == pendingModule.Name && installedModule.Version > pendingModule.Version){ triggerAction = "Version Rollback"; } else if(installedModule.Name == pendingModule.Name && installedModule.Version < pendingModule.Version){ triggerAction = "Version Update"; } }); if(triggerAction == "Install"){ LoadItems.push(pendingModule); } }); }); _.each(Initializer.ToDoList,function(pendingModule){ pendingModule.LoadOrder = parseFloat(pendingModule.LoadOrder) + parseFloat(0.1); LoadItems.push(pendingModule); }); LoadItems = LoadItems.sort(function(a,b){ return parseFloat(a.LoadOrder) - parseFloat(b.LoadOrder)}); _.each(LoadItems,function(loadItem){ loadItem.Execute(); }); } on('ready',function(){ Initializer.Initialize(); sendChat('API','/desc The API is ready.'}); Page C: DataStore DataStore = DataStore || {}; DataStore.Key = 'DataStore'; DataStore.Version = 1; DataStore.LoadOrder = 1; DataStore.Repository = {}; DataStore.Initializer = function(){ DataStore.Repository = findObjs({ type: 'character', name: 'Data Store'})[0]; } DataStore.Installer = function(){ General.CreateCharacter('Data Store'); } Initializer.ToDoList = Initializer.ToDoList || []; Initializer.Installer = Initializer.Installer || {}; Initializer.Installer.ToDoList = Initializer.Installer.ToDoList || []; Initializer.Installer.ToDoList.push({ 'Name' : DataStore.Key, 'Version' : DataStore.Version, 'LoadOrder' : DataStore.LoadOrder, 'Execute' : DataStore.Installer }); Initializer.ToDoList.push({ 'Name' : DataStore.Key, 'Version' : DataStore.Version, 'LoadOrder' : DataStore.LoadOrder, 'Execute' : DataStore.Initializer }); The problem arises if Page C somehow gets loaded before Page A. The General.CreateCharacter function will not be declared when the DataStore.Installer function is declared, and may not even be declared when the DataStore.Installer function is pushed to the Initializer.Installer.ToDoList. Normally, I would add the script tags to an HTML page in the order I wish them to be loaded, but I don't have that option with Roll20. Do pages run in the order they are tabbed? Is there some other way to ensure they load in a specific order?
1431612319
The Aaron
Pro
API Scripter
You can't guarantee load order, but there are a few thinks you can do to make it not a problem: 1) You can put all your scripts in a single tab in the order you want them loaded. Not ideal and a pain for maintaining, but very easy to do. 2) You can put all your functionality that depends on other systems in a function and make sure that function isn't called until on('ready',...). Just be sure that what you are wanting to call is loaded outside on('ready',...) and you should be fine. 3) You could potentially rewrite your code to check if a function exists, and delay execution by some amount (setTimeout(....)) before attempting to call it again. Sort of a pipeline approach. I use 2) personally. Writing scripts in the style I do, it ends up just naturally occurring.
I thought about the first two options. Option 2 I'm not sure it will work, unless there's some way to guarantee that the Initializer.Initialize function in the on('ready') handler fires after everything else in the on('ready') handler. I suppose setTimeout(Initializer.Initialize(),2000) would work, but that's assuming the API can do all of the previous work in under two seconds.
1431614226
The Aaron
Pro
API Scripter
If you're firing that setTimeout() in an on('ready',...), it should be plenty of time. There are other things you could try, but they are all going to start cluttering up your code, where as reorganizing it so you can start dependent actions during an on('ready',...) will clean it up and make it easier to understand and maintain.
I appreciate your help. I'll try moving the Initializer array populations into on('ready') and Initializer.Initialize into a setTimeout() in the on('ready').
1431615969
The Aaron
Pro
API Scripter
Yup, definitely post back if you you hit a snag. =D