update array from JS file

Workarounds and usability notes.

update array from JS file

Postby John Robin Dove » Thu Oct 29, 2015 2:05 pm

Hi Clifton,
Hope you can shed some light on this. I've been trying to solve this problem for about 8 hours now and I'm stuck.
I'm still trying to convert shared actions to functions in b.js because Toolbook cannot contain the number of shared actions I require. The problem concerns an array called triggers [] that I use in the TB HTML. It contains data (strings) used to trigger events while a media file is playing. When the project is saved the array is converted to textlines to be saved in a file and they might look something like this:

1978,1,First message...,2321,
4299,2,5000,,
7029,1,Second message...,1985,
9014,2,5000,,

so triggers [0] would be "1978,1,First message...,2321," and triggers[1] would be "4299,2,5000,," etc. Until now this has functioned perfectly. The problem is that I need to update the array from functions in my custom js file and this is not working.

Here is the action sequence I am trying to replace:
Image

Here is the function I'm using to replace it in the js file:
Code: Select all
function tbfunction_setTrigger(triggerLine, increment) {
tbfunction_pgTBObjSet("limits", "user", triggerLine + ";" + increment);
};


This is the action sequence in field "limits":
Image

setTrigger is always activated from another function in the js file for example:
Code: Select all
function tbfunction_textDisplay2(currentTrigger, currentTriggerLine, MSecs, unit) {
var triggerLine = [];
triggerLine = tbfunction_pgSplitToArray(currentTriggerLine);
var actionStart = triggerLine[0];
actionStart = actionStart * 1;
var lapseS = MSecs - actionStart;
triggerLine[3] = lapseS;
currentTriggerLine =  triggerLine[0] + "," + triggerLine[1] + "," + triggerLine[2] + "," + triggerLine[3];
tbfunction_setTrigger(currentTriggerLine, false);

// -----------------------DEBUG-------------------------------
alert("currentTrigger = " + currentTrigger)
// A click on info activates a loop that shows the contents of triggers[]
tbfunction_pgTBObjSet("info", "click");
//------------------------------------------------------------

currentTrigger = currentTrigger * 1;
currentTrigger = currentTrigger + 1;
tbfunction_pgTBObjSet("info", "user", "currentTrigger," + currentTrigger);

var rightPos = tbfunction_pgTBObjGet("changepos", "left");
rightPos = rightPos + 28;
var leftPos = tbfunction_pgTBObjGet("startMarker", "left");
var myWidth = rightPos - leftPos;
tbfunction_pgTBObjSet("a" + currentTrigger, "left", leftPos);
tbfunction_pgTBObjSet("a" + currentTrigger, "top", 599);
tbfunction_pgTBObjSet("a" + currentTrigger, "width", myWidth);
tbfunction_pgStyleObject("a" + currentTrigger, "backgroundColor", "rgb(255, 255, 64)");
tbfunction_pgTBObjSet("startMarker", "visible", false);
// Update objectInfo collected for file (used by VB version)
var objectInfo = tbfunction_pgTBObjGet("limits","text");
var nextTrigger = currentTrigger + 1;
var objectLine = "R," + currentTrigger + "$" + nextTrigger + "," + leftPos + ",8805," + myWidth + ",755,,,60,62.5625,100";
// This may be the first object (this object may have 2 triggers when completed).   
    if (currentTrigger == 2)
    {
    objectInfo = objectLine; //No crlf required
    }
    else
    {
    objectInfo = objectInfo + "\n" + objectLine;
    }
tbfunction_pgTBObjSet("limits", "text", objectInfo);
};

The strange thing is that if I only use 2 elements in triggers [] there is no problem. If I use 4, 1,2 and 4 are correct but 3 is always undefined. The result is:

2588,1,message 1,3269
5857,1,,,
undefined
13146,1,,,

The missing line would be something like "9252,1,second message,3894". The array seems to be updated momentarily but then the data immediately becomes undefined It seems that it is not possible to reliably update an array in the TB HTML from b.js. Why not? I suppose I could use an object property like text of field instead but this would mean rewriting all the code that uses triggers[] if I can find it. I can't search in the TB project because it's too full which makes life difficult. BTW I've posted this 3 times. The Forum keeps eating it!
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: update array from JS file

Postby Clifton » Thu Oct 29, 2015 2:44 pm

I think the problem here is that your AE array is being assumed to be a true JavaScript array in your js file. But an AE array and a JavaScript array are two very different data types even though they may at times behave similarly.

For starters, please see this PowerPac API Help document:
http://www.pgsoftwaretools.com/powerpac/help/?acc=1&m=actions_editor&t=1-7

When the AE initializes or creates an array, it creates an OBJECTS with properties. This is really a smart way for the AE to handle all sorts of complex routines. However, when you pass this to a function in a custom file, the result may be very unexpected if the function is trying to set an index of a true JavaScript array when the input is not an array at all. This especially becomes evident when trying to loop through the two different data types and this is probably where the issues are occuring in your AE > custom js function execution.

In your case the solution MAY be to ensure the AE is using the same data type that is expected in the custom js file.
There are two ways to ensure this:
  1. Declare your AE variable as an AE array and use the PowerPac function pgSort_Shuffle() on the AE array and save the result back to the same variable. The PowerPac will convert your AE object to a true JavaScript array.
  2. Declare your AE variable without any value or data type and use the PowerPac function exeJavascriptDirect() to initialize it as a true JavaScript array BEFORE it is ever used in any action sequence.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: update array from JS file

Postby John Robin Dove » Thu Oct 29, 2015 4:49 pm

Thanks Clifton.

Unfortunately that doesn't seem to make any difference. I tried both methods but I still get undefined in triggers[3]. triggers{] is a global variable. I put your suggestions for the conversion in on load page of the first page. I tried this first in a test app and it seemed fine. I could manipulate the contents of triggers with no problem.

In my program this modification had no effect. I should have an array of four strings. What I can't understand is that triggers [3] is updated by the function in b.js in exactly the same way as triggers [1] and the two strings in question are almost the same. For example triggers [1] can be updated to "2588,1,first message,3269" but when I try to update triggers [3] to "9252,1,second message,3894", triggers [3] becomes undefined.

From the js file, I send a user event containing the string to a field which updates the array i.e. set triggers [3] to str in the AE. If I include an alert in the same action sequence alert (triggers [3]) it displays the correct value as if the job's been done. But if I then, from the js file, trigger another object which checks the contents of triggers[] immediately after this . I find that either the job wasn't done or something has occurred which results in triggers [3] being undefined. There is nothing in my code that would account for this as far as I know. The sequence of events is:
1) user presses on the ctrl key to stop the video and indicate where a displayed text should be hidden (the ctrl keydown is detected in an embedded html loaded by pgGotoURL - this has always worked perfectly).
2) a function in b.js carries out a number of tasks including updating the triggers[] array (this used to be done by a shared action action sequence and then it worked perfectly).
3) (for debug purposes) there is an alert to check that the array has been correctly updated and it says it has!?
4) (for debug purposes) the next line in the js file triggers an object which loops through triggers[] and alerts the contents of each element and triggers[3] is now undefined even though a millisecond ago it apparently wasn't.
5} the js function completes its tasks.

I have tried moving the line that handles the array updating to the end of the function in case the subsequent other tasks were causing the problem but this made no difference. I have tried activating the original shared action sequence from the triggered object instead of doing this directly but this makes no difference either. I'm running out of ideas so I'll call it a day. Hope to hear from you tomorrow. Thanks for your help.
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: update array from JS file

Postby Clifton » Thu Oct 29, 2015 6:04 pm

Your actions may be suffering from double triggers and more likely double user events. This can sometimes happen when objects are grouped together and events are being handled on more than one object in the group. PowerPac functions are pretty good at catching these things, but depending on your AE code, there may be other things going on ... which seems to also include running media which may be sending notification events as well.

The point is that you may need to add some data integrity checking to your js code. This is good practice when writing JavaScript functions to prevent unexpected results when functions are executed.
     
    Try changing this ...
    Code: Select all
    function tbfunction_textDisplay2(currentTrigger, currentTriggerLine, MSecs, unit) {
        var triggerLine = [];
        triggerLine = tbfunction_pgSplitToArray(currentTriggerLine);
        var actionStart = triggerLine[0];
    . . . (rest of code)
    }

    To this ...
    Code: Select all
    function tbfunction_textDisplay2(currentTrigger, currentTriggerLine, MSecs, unit) {
        if (!!currentTriggerLine == false) return;    //Check for invalid parameter which could be sent from a double user event
        var triggerLine = tbfunction_pgSplitToArray(currentTriggerLine);    //Function returns array if valid data is submitted
        if (!!triggerLine == false || !!triggerLine[0] == false) return;    //Catch invalid data by checking array integrity
        var actionStart = triggerLine[0];
    . . . (rest of code)
    }

Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: update array from JS file

Postby John Robin Dove » Fri Oct 30, 2015 4:48 am

:cry: I thought you'd cracked it. A double execution would explain the disappearance of the correct data. But your solution didn't work. I still think the idea is probably right though. I'll try to test it again.

UPDATE: No there doesn't seem to be any double execution involved. I put alerts at the beginning of functions textDisplay2 and setTrigger. They only fire once. So :?:
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: update array from JS file

Postby Clifton » Fri Oct 30, 2015 6:49 am

Well, your test just means that the function we patched with data integrity isn't where the problem is creeping in. The next thing is to examine other places where the variable is manipulated to see if the data submitted at some point is invalid and causes the array indice to become unset. Not sure I can be of much help.

The idea of check the integrity of data is that before anything is written into the array variable, the value should be checked first and the routine aborted to protect the values. Somewhere in your actions or in the custom js, this is not happening. You might try using fields to capture your variable values instead of alerts because alerts stop function execution and often change object focus while fields allow functions to run normally. This permits you to see more closely what happens to the values as the code executes.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: update array from JS file

Postby John Robin Dove » Fri Oct 30, 2015 4:07 pm

Hi Clifton,

Complete day wasted. I'm almost certain I have found all the code that manipulates the array. As you suggested I have used a field to check if any functions or shared actions fire when they shouldn't but I haven't found anything like that yet. I've got an old version that works but I don't know why! The part of the code that updates the array is identical to the same part in the current version. There must be something that causes the problem elsewhere. I'll try again tomorrow.
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: update array from JS file

Postby John Robin Dove » Sat Oct 31, 2015 4:13 pm

Hi Clifton,
I'm getting nowhere fast! I'm pretty sure the problem is nothing to do with the external JS file. It occurs with or without this. I've now got a situation that I don't understand at all.

Here is part of an action sequence I am using for debugging.
Image

I have a global array called triggers[] and a variable called currentTrigger. I perform 3 tests: the contents of triggers[currentTrigger] is displayed in 1) field "check[1,2,3 or 4] 2) in field "debug" 3) in an alert.

Image

Image

Each check field uses a timer to display the current contents of triggers[1 - 4]

Image

When currentTrigger = 1 Things are normal:

Image

When currentTrigger = 3 (or 5 or 7 etc.) things are no longer normal! Field "check3" displays triggers[currentTrigger] as undefined (this is probably the case as the text is constantly updated). BUT how can field "debug" and the subsequent alert get a different result?! They are updated AFTER the initial update of field "check3" and they display the contents as it should be. How can different parts of the program get different data???!!! As I mentioned before I have an old version (that has other unresolved issues) but this part functions 100%. I cannot see the difference between the 2 versions. I must be missing something. Hope you can see what it is.

Image
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: update array from JS file

Postby Clifton » Sat Oct 31, 2015 8:14 pm

You may want to take a look at what is happening with your media notification when htmlVideoLoader() is running. If you are notifying an object and that user event is manipulating the value of currentTrigger, etc. then this may be where issues are coming into the picture. It could also be that video monitoring may be sending user events that cause your variable values to get lost.
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: update array from JS file

Postby John Robin Dove » Sun Nov 01, 2015 5:44 am

Hi Clifton,
Thanks very much for your efforts. The good news is I have found a solution! The bad news: I don't understand why it works! I suppose it could be worse. I know what I have done so if necessary I can do it again if I hit similar snags in the future.

The 'event' in my program being created by the teacher here is a simple text display that appears without pausing the video and then disappears later at a point chosen by the teacher. It can be accompanied by one of 2 tasks to be done by the student: recording an oral response or typing a written reply but in the case causing the problem no task was required. To create this event the teacher presses on the ctrl key. This stops the video and the teacher is asked what type of event he/she wishes to create. In this case: display a text. A start marker object appears. This is used to set the left position of an object that represents the event. The teacher is prompted to type the message required. The video restarts and the teacher presses on ctrl again to indicate the point at which the message should be hidden and a yellow rectangle representing the display time appears. Why create an object like this? Because when the program is finished (if it ever is!) the teacher can move this object backwards, forwards and/or change its length in order to fine tune his exercise with great precision.

In this version of my program the value of currentTrigger is set BEFORE the creation of an event begins. Each text display corresponds to 2 triggers (start and finish). The trigger causing the problem was trigger number 3 (I don't know why number 1 didn't have the same problem). The only difference I could see between the old version that worked and the current version was that currentTrigger was incremented DURING the creation of the event, just after the text had been entered. For complex reasons I can't explain briefly I need to have currentTrigger incremented BEFORE the creation process. So the solution I have found is to simply decrement currentTrigger at the start. In this way I can use the old code which increments the value of currentTrigger as soon as the text has been typed. This works! Why??? The only difference in the code is one line that re-increments currentTrigger!

Another unrelated problem. When I go to the PG forum the display I see is out of date. My last post is dated June 02, 2015! To see my most recent post I have to use my browser history. Maybe I've posted too often? :D
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 4 guests

cron