Delay Node not worked?

Delay Node not worked?

Anonymous
Not applicable
1,242 Views
13 Replies
Message 1 of 14

Delay Node not worked?

Anonymous
Not applicable

Hi, I want to spawn some units via Level Flow. I make a for loop and add a Delay Node (1.2 seconds as you could see), but when I test the level, it seems all the units are created at once (I also verified this by looking at the console log), there is no delay at all !

 

Does the Delay Node actually works with the For Loop Node or I misunderstood something ?

 

20151115000552.png

Reply
Reply
0 Likes
Accepted solutions (1)
1,243 Views
13 Replies
Replies (13)
Message 2 of 14

ADSK.JasonChin
Alumni
Alumni
Accepted solution

Hi lostyzd,

 

Welcome to the forums!  The For Loop can go through its iterations very very fast.  You can test this if you make a For Loop that loops 10 times and on each Loop Body you have it Debug Print something.  You should see all the Debug Prints happen almost at the exact same time even though they are happening sequentially.  This is exactly what is happening in your example but each Spawn Unit attempt simply has a 1.2 delay but all those delays are starting at the same time.

 

In order to fix this, you will need to have the Delay node's Time value increase every loop so each subsequent Spawn Unit call has a higher delay.  So this way the first Spawn Unit has a 0 second delay, the next has 1.2, then 2.4, etc.  See my attached Flow sample on how you might do this.  I hope that clears things up!

 

delay_node_issue.png

Reply
Reply
Message 3 of 14

Anonymous
Not applicable

Thanks for your reply, I understand the reason now, the For Loop executes the loop body all at once.

 

Just one another question, how is the Delay Node actually implemented ?

 

Based on the documentation(Creating custom flow nodes), it should return an result immediately, so it be should like

 

function ProjectFlowCallbacks.delay(t)
    while true:
       if now - start > t.time:
           t.Out = true
           return t
end

But such code will block the entire thread, so I guess it should be async, maybe it setup a timer then let the Engine re-execute it self later.

 

function ProjectFlowCallbacks.delay(t)
   if (t.firstTime == false)
t.firstTime = true
t.Out = false

Application.execute_this_function_some_time_later_with_parameter(t.time, t)

return t
else
t.Out = true
return t
end end

 

Besides, how should I implement a async operation in flow node, e.g. Wait for an HTTP request, wait for async disk write ?

Reply
Reply
0 Likes
Message 4 of 14

Anonymous
Not applicable

dup post.

Reply
Reply
0 Likes
Message 5 of 14

ADSK.JasonChin
Alumni
Alumni

The Delay node is implemented over on the C++ side of the engine.  The rough gist of it is that Flow events are added to a queue and each update we iterate through for any Flow events that should trigger and trigger them.

 

As for the async stuff, let me do some digging and get back to you.

Reply
Reply
Message 6 of 14

ADSK.JasonChin
Alumni
Alumni

There are a few ways to handle the async stuff.  For example:

 

  1. Use an external event. e.g. in lua, when the async thing finishes, call trigger_event("disk_write_complete") and then set up an incoming external event node in the level flow.
  2. Poll a custom flow node on a delay loop, e.g. call a custom “Is Write Finished” node that is implemented in lua.

 

Reply
Reply
Message 7 of 14

Anonymous
Not applicable

Thanks for your solution. But how should I implement a node looks like 'Delay Node', as you could see, there is no extra event for Delay Node and it is just one simple node. There might be multiple async operations, assign a named event for each one doesn't look like a nice solution.

 

I searched in the documention, but I didn't find a api which could trigger certain node (assume that I could get the flow nodeID).

 

Also, according to the documentation, there should be two arguments for the callback, but I only find one argument which named 't' in most examples, so now I don't know how to get the flow node ID. 

 

When the game engine calls your Lua function, it always passes two arguments:
A table, whose entries are defined by the args setting of your Flow node configuration. See below.
A value that uniquely identifies this Flow node instance. If your Lua code needs to maintain some state data about the Flow node across multiple evaluations, you can use this value as a key for storing and retrieving the state data from a table that you maintain in a custom variable.
Reply
Reply
0 Likes
Message 8 of 14

ADSK.JasonChin
Alumni
Alumni

Could you give me a bit more info about what you are trying to do with the async stuff?

 

As for triggering a specific Flow node, perhaps this will be helpful: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/ENU/Stingray-Help/stingray-hel...

Reply
Reply
0 Likes
Message 9 of 14

Anonymous
Not applicable

Okay, here is an example.

 

 

{
        name = "ASYNC HTTP GET"
        args = {
            Url = "string"
        }
        returns = {
            Data = "string"
            Success = "event"
            Fail = "event"
        }
        
        function = "ProjectFlowCallbacks.async_http_get"
        category = "WWW"
}

 

 

image_20151118095150.png

 

I want to make a Async HTTP GET Node, but how could I implement it in a single node like the 'Delay Node'?  Please check the comments below.

 

 

-- This is an asynchronous function, so I could only know the operation will success or fail some time later.
-- But I have to return something to the engine, so the first time it executes, it just send the request to a queue and returns.
-- The two API I need but I could not find anywhere are:
1. get the current flow node ID
2. let the engine execute that node ID with certain parameters

function ProjectFlowCallbacks.async_http_get(t)
if t._done == true
t.Success = true
else
-- Well, I don't know how to get the current flow node ID
thisNode = GetCurrentFlowNodeID()
MyOwnHTTPModule.async_get(t.URL, thisNode)
end

return t; end

function MyOwnHTTPModule.async_get(url, someFlowNode)
-- do the actual work, might call some c++ module or setup a timer to check wheter it finishes, implementation detail doesn't matter

function callback()
-- the job is done, let the engine execute someFlowNode with `t._done` set to `true`
end

MyOwnHTTPModule.add_request_to_queue(url, callback)
end


-- this is the main loop
function update(dt)
-- check whether some request is done and execute the callback
MyOwnHTTPModule.poll()

stingray.World.update(world, dt)
end

 

 

Reply
Reply
0 Likes
Message 10 of 14

Anonymous
Not applicable

Hi Lostyzd,

 

Just to interject, hopefully you will solve your delay node problem, but looking at your example code, currently to my knowledge there is no way to do a HTTP request without access to the source code of the engine.

 

I asked how I can do a HTTP request a few weeks ago, and was told that there will be a public plugin API sometime soon and HTTP will have to be done with a plugin.

 

Without HTTP access Stingray limits the use of many of the backend tools developers use.

 

Brian

Reply
Reply
0 Likes
Message 11 of 14

dan.matlack
Alumni
Alumni
I will reach out to the engine team for a bit more clarification on this for you all. Thanks!
______________________________________
Dan Matlack
Senior Content Manager || Games Solutions
Autodesk, Inc.
Reply
Reply
0 Likes
Message 12 of 14

niklas.frykholm
Alumni
Alumni

Yes, with the latest Stingray code you can write a plugin to download web content. You can also use the LuaJIT FFI interface to directly load a DLL such as libcurl and use it to fetch web pages.

 

Here is a sample project that does just that:

 https://github.com/niklasfrykholm/stingray-curl

 

// Niklas

Reply
Reply
0 Likes
Message 13 of 14

dan.matlack
Alumni
Alumni
Thanks Niklas!
______________________________________
Dan Matlack
Senior Content Manager || Games Solutions
Autodesk, Inc.
Reply
Reply
0 Likes
Message 14 of 14

Anonymous
Not applicable

Well, thanks for your reply.

 

I checked out your code, but the main problem remains. It is still uncertain how to write a Flow Node that could handle async operation.

 

I think this may due to the lack of some Flow API in the Lua layer.

 

Reply
Reply
0 Likes