#What's the preferred method for performing ReST API calls through ISystems?

1 messages · Page 1 of 1 (latest)

hexed jasper
#

DISCLAIMER: This is not a Netcode question afaik since this isn't dealing with multiplayer.

The classic way to work with MonoBehaviour-based code would be to use UnityWebRequest with YieldInstructions/IEnumerators. What's the preferred way to do this in DOTS? Should I rely on the older coroutine system or use the .NET APIs which support async/await?

novel dove
#

allthough, manual iteration wouldn't support all helper yields like waiting for specific time and etc

#

otherwise it's perfect if you only need to skip frame

magic glen
#

I would say async/await is more in the spirit of dots, but I don't think it matters a whole lot as long as performance is OK and you're comfortable with it

slate stream
# hexed jasper DISCLAIMER: This is not a Netcode question afaik since this isn't dealing with m...

I was thinking I'd have a GameManager/GameController that lives above the ecs world, at the top of the control flow.
It would call the ecs world update manually
It would keep the Entity reference of the player and feed player input to it as well
I'd freely go around and mutate my components in the GameManager however I see fit

I was thinking it would be the GameManager calling such requests and then mutating the entities and components based on the response of the request

novel dove
slate stream
#

I'd like to hear more

novel dove
#

it's also not going to be compatible with built in system profiler

slate stream
#

Taking over the update call you mean?

novel dove
#

yeah, it works mostly because world is updated by player loop directly

slate stream
#

Well I won't take over the update calls then

novel dove
#

besides, world is created before scene is loaded

#

(at least that's when default bootstraps run)

slate stream
#

I was actually thinking I would create a new world as well to really keep the gamemanager on the top of the control flow but I don't want to have trouble with debugging and profiling

#

Also, why do you think its not good to have a Monobehaviour gameobject to control the game if that's what you mean as well? @novel dove

#

You meant that as well right?

novel dove
#

you can have some sort of controller above ecs, sure. But if you want clean code, it will only be responsible for creation of worlds

#

while everything else is managed by systems inside worlds

#

by default that controller - bootstrap

#

either default one, or custom

#

but if you want mono behaviour bootstrap - well, you are going to have to override pretty much everything built in

#

and what you get out of it is quite questionable

slate stream
#

all right thanks @novel dove , I'll think about it

hexed jasper
#

What's the preferred method for performing ReST API calls through ISystems?

#

I guess the question was not interpreted correctly.

#

I wanted to ask what the way to do ReST API calls would be in an ECS ecosystem

still fog
#

we haven't really thought much about it, but you could just make a static function that you call from wherever, either a system or monobehaviour or whatever else

hexed jasper
#

From what I am seeing maybe System.Net.Http looks like an okay way to do this as we're no longer restricted to Unity's older yield-style coroutines.

still fog
#

i would think unity's webrequest would be more well-tested on platforms

#

but that's not related to ecs

hexed jasper
#

That's true. In my specific case though I am building for UWP.

#

I guess another way to do this would be to use some wrapping library like UniRx with UnityWebRequests (if performance wasn't a concern).

still fog
#

¯_(ツ)_/¯

#

in any case, using ecs doesn't change it one way or another

hexed jasper
still fog
#

i guess if you used too many tasks or other threading things, you could hurt job performance by causing too many context switches

#

make a static method and call your things from it?

hexed jasper
#

ELI5: this means just using yield-coroutines inside a static method?

still fog
#

i had thought webrequest had a way of avoiding both coroutines and threads

#

and would just give you an object that you could check periodically

novel dove
#

why not just do

IEnumerator MyCustomRoutine(){
var request = MakeWebRequest();
while (!request.isDone) {
yield return null;
}
WebRequestDone();
}
#

store it in a field and call it from within system?

still fog
#

because coroutines have a crapload of overhead

#

on the main thread, no less

novel dove
hexed jasper
#

Essentially just poll for the result, yes?

novel dove
#

kind of

#

you can manually write state machine if you want

#

I just find using C# yield codegen convinient

#

that would be pretty much async function, but fully managed by system that calls it

#

and which stops as soon as world disposed (but you definitely would need to dispose any temporary data if there is any manually)

hexed jasper
#

What I am reading is that there isn't a clean way to do this with ECS yet.

novel dove
hexed jasper
#

I tried using System.Net.Http but could not get it to work:

  1. The ISystem methods inherently can't be async as they have a ref parameter.
  2. Running it in a MonoBehaviour works if I use async/await (bare tasks somehow doesn't work)
  3. For whatever reason, bare tasks also don't work in OnUpdate.
novel dove
#

Just use SystemBase, ISystem is no use with managed stuff

hexed jasper
#

That still doesn't work. I use the new overridden protected method which doesn't take any parameters, but it doesn't work.

novel dove
#

YOu haven't provided any information what doesn't work though

hexed jasper
#
protected override async void OnUpdate()
{
    /*
     if (
        !performUpdate 
        || !SystemAPI.TryGetSingletonRW(out RefRW<AeroApiCallerData> faDataRef)
        || faDataRef.ValueRO.SecondsUntilNextApiCall is <= -0.01f or >= 0f
      ) return;
       */

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
      new MediaTypeWithQualityHeaderValue("application/json"));
    // client.DefaultRequestHeaders.Add("x-apikey", faDataRef.ValueRO.ApiKey.ToString());

    var query = new AeroApiQuery(
      AeroApiQuery.RelQueryAirportsIdFlightsFmt,
      AeroApiQuery.IcaoShanghaiHongqiao);
    var response = await client.GetAsync("https://eop6py8atbxb71t.m.pipedream.net");
    // task.ContinueWith(OnAirportQueryResponseReceived, (faDataRef, query.CostUsd));

    // TODO check flights

    // faDataRef.ValueRW.SecondsUntilNextApiCall -= SystemAPI.Time.DeltaTime;
}
#

What doesn't work is the .GetAsync call to the RequestBin link (https://eop6py8atbxb71t.m.pipedream.net)

novel dove
#

that gets called every frame unless you specified update requirments to system

#

also, how do you know it doesn't work

#

Don't see any checking for response

hexed jasper
#

Through RequestBin not receiving any requests

#

This is an externally hosted service

novel dove
#

ah, you mean you track requests on that site?

#

well anyway, that doesn't seem to be related to DOTS at all

hexed jasper
#

ye, it appears like this

#

when there are requests, they appear where it says Waiting for events...

hexed jasper
novel dove
#

🤷‍♂️

jade mango
#

I need to make code that executes over time, iterators are a great feature however they don't function in ecs dots as far as i am aware. Is there any feature that allows me to produce this type of code for my entities without writing garbage if checks for state, time ?

novel dove
#

otherwise - feel free to store in a system field. YOu have OnDestroy callback for disposal

jade mango
#

Thanks for the answer, but like for feature like yield return or pausing a function execution, there is no way around in dots ? i must write if checks to determine the code to execute

jade mango
#

thanks for the help it is really helpful 🖐️