How do I set individual return value from 2+ function calls?

  • I have a project with quite a lot of multitasking inside, with each task might call for specific function, or 2 tasks call for 1 function with different parameter(s), either manually called or automatically scheduled.

    From what I have experienced, return value applies globally, meaning that whichever condition at the same tick request a return value, all will read the same value returned.

    On my project, I have a "synchronize" group that call for a sync function at every set duration. The sync will send an AJAX request to a remote server so the syncing process took several ticks to complete (~10 ticks). At the same time, I have a "user interface" group that will call for a function whenever a user calls them (~5 ticks).

    Short illustration of the sync group:

    every 300 tick {
    	value = get_sync();
    	[some actions...]
    	end
    }
    get_sync() {
    	var x;
    	[some actions...]
    	set return value to x;
    }
    [/code:30024806]
    Short illustration of the UI group:
    [code:30024806]if ( button_a pressed ) {
    	pin = get_auth(user_a);
    	[some actions...]
    	end
    }
    get_auth(var user) {
    	var y;
    	[some actions...]
    	set return value to y;
    }
    [/code:30024806]
    The problem will occur if:
    [code:30024806]
    @ 1670 tick: get_sync (supposed to end at 1680)
    @ 1675: get_auth()
    @ 1680: value = pin = [returned value from one of the function above]
    [/code:30024806]
    Is there a way to differentiate a return value, to identify which function calls for it? Maybe like Function.ReturnValue("my_function")?
  • Rather than set a return value, can you set a variable (or push to array) directly? I was under the impression that return values in construct were mostly for interfacing with JavaScript directly, I've never really needed them.

    After you have your values saved to data structure of choice, you have more control to schedule what the function object returns on any given tick.

  • The var value and pin is a sort of global object (in json form). Generally speaking, I'm trying to avoid setting the value directly within the function as this will makes it harder for me to manage the modules (I've use that method before but now I'm trying to do it more object oriented).

  • With other asynchronous objects, there is always a trigger condition to use the returned value immediately. On the other hand, those usually support tags. I don't know if you'd be able to apply something like that for your own system. Maybe someone else more familiar with the topic can help, sorry.

  • If i read you the right way, then the function is not the problem.

    It should not be too. Because functions act as they are 'in place'. Replace the 'function call' with the contents of the 'on function' and nothing is changing. Read 'as in place'.

    The problem is the way you use Ajax (educated gamble).

    If this is what happens .....

    On function (sync group)

    ____ Get ajax data

    ____ Set something to last Ajax data

    ____ Bunch of actions dealing with the data

    On function (UI group)

    ____ Get ajax data

    ____ Set something to last Ajax data

    ____ Bunch of actions dealing with the data

    Then... As you stated, getting Ajax data is not instantly. It takes time.

    So, the last Ajax data are for sure not ready to use in the scope of this function call.

    At some time, one of those functions is called again, and there will be data from some previous request data action.

    From which request action is totally not known, and cant be known, that way.

    It is obvious not the way to use Ajax. To avoid asynchronous blending, the Ajax requests are paired up with a tag.

    To know which data are in the last data, and to know when the data are ready to use, you have the condition 'On completed (tag)'.

    Or 'On any completed' , and the expression Ajax.tag is returning the tag.

    I suggest to call the function, request data in the 'on function' with a tag "sync" or "UI".

    Have a root event 'On any completed'

    Have a sub with a compare 2 values. Compare Ajax.tag to "sync"

    Set something to last data and do the stuff that belongs to "sync"

    Use 'else' or a compare for "UI"

    Set something to last data and do the stuff that belongs to "UI"

    That would be the basic stuff. But now, those darn users could be multitasking. And you dont know which "UI" stuff belongs to which 'user call'.

    Well, user needs to be identified. By example. Give each user an array. Give the array a instance variable with a value that is unique for that user, so you can pick it easy.

    Now call the "UI" function with a parameter holding that user id.

    Request Ajax data with a tag "UI"&"/"&user id

    If you now use the 'On any completed' as a root.

    then compare 2 values ... tokenat(Ajax.tag,0,"/") = "UI"

    then pick array with instance variable 'id' = tokenat(Ajax.tag,1,"/")

    ____ store the last data in that array

    ____ do stuff with the data all you want

    ____ update the information to the user straight a head, or 'signal' the postponed action by a 'wait for signal' right after the function call made by the user

    Hope that makes sense to you.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • That 'signal thing' works this way.

    User pressed button <--- root event

    _____ request Ajax data with tag "user id"

    _____ Wait for signal tag "user id" <----- actions that come after are postponed until the signal (WITH THE RIGHT TAG) is given

    _____ display result to user

    _____ delete dictionary key

    Ajax > On any completed <----- root event

    _____ do stuff with the last data, store the result in a dictionary with key "user id" and value result

    _____ signal with tag "user id" <---- run the postponed actions

  • Thank you for your suggestion but the problem is not on the AJAX. I use AJAX a lot too and all already using its own on 'tag' completed. I never use AJAX on any completed. I've also been using a lot of signaling, so far so good.

    I've boiled down my problem and I think the problem is because the return value is only available after some ticks, so the caller already "expired", thus the return value is not returned to the right caller. So this probably is because of my method, not what I originally thought that return value applies to all functions globally.

    I run some test with 2 methods, a main body which call for 2 functions, and the function A and B itself, each wait for 1 second before returning the value (simulating this function requires some ticks to complete). Here's what I tried:

    -----FUNCTION A (NOT WORKING)-----
    function run_A {
    	wait 1.0 second
    	set return value to "result of A"
    }
    
    -----FUNCTION B (WORKING)-----
    function run_B {
    	set return value to "result of B"
    }
    
    void main() {
    	on button clicked {
    		set var A to Function.Call("run_A");
    		set var B to Function.Call("run_B");
    	}
    }
    [/code:33fw5n67]
    
    Result:
    [code:33fw5n67]A = 0
    B = "result of B"[/code:33fw5n67]
    
    I'm guessing that on my project, because both functions takes some ticks to complete, the return value isn't received by the caller. So my question is, how can I return a value that is not available at an instant or should I use other method than return value (static var and signaling perhaps)?
  • Out of scope it cant return a value. The wait brings things out of scope.

    If its not a Ajax request, then what else would take time to complete inside the function ?

  • There are a couple of calculations and draw calls which need to be run sequentially. It use either wait for signal or wait 0 second (next tick) before running. Let's say it is possible to run things without waiting at all, but this will require whole lots of sub-events and it's going to be hard to manage (calling sub functions etc). Any suggestion to workaround this?

    Another thing that I want is to make a function, for example, to request a user input a pin number, then return the result 1/0 (success/failed) to the caller. Surely waiting for user input require a lot of ticks. Can this be done?

  • Wait 0 = happens at the end of the tick that ran that wait.

    Any wait/delay escapes the scope of the function. Cant start a start time consuming task and return the result of it inside the same function. Unless you prolong the tick.

    A time consuming loop stays in the function. The tick just gets longer.

    But you can not use triggers inside a loop.

    And when the loop is running it will not (multitask) do anything else.

    So pretty useless for you. I think (but i am not the smartest) that you need another way.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)