Use of futures for async loading

2019-07-01 18:10发布

I decided to learn Dart and my project for doing so will be a small webgl game.

The use of a single thread with aysnc operations and futures are new to me though and while I understand the concepts I'm finding it a little hard to know how to use them.

In my game I want to load a webgl GLSL program. To create this program I first have to load a vertex shader and a fragment shader from files. So I've written this which seems to work ok for loading and compiling the shaders.

The problem I have is how do I then know when both shaders are loaded so that I can then create the "program" object from the two loaded shaders. In the same way that I can use .then on the future retruned from HttpRequest.getString I need to somehow do the same and have a .then that runs when both the fragment and the vertex shader are loaded.

I'm sure i'm missing something major and easy here, but this is new to me and I'm struggling a bit to know how to use it. (Which is good, it's good to learn new things!)

  //
  // Start the process of loading the shaders. 
  //
  void initShaders()
  {
    Shader vs = gl.createShader(VERTEX_SHADER);
    Shader fs = gl.createShader(FRAGMENT_SHADER);

    var vsFuture = HttpRequest.getString('basic.vert');
    var fsFuture = HttpRequest.getString('basic.frag');

    //
    // When we have the vertex shader source, compile it
    //
    vsFuture.then((src) {
      gl.shaderSource(vs, src);
      gl.compileShader(vs);
      if (!gl.getShaderParameter(vs, COMPILE_STATUS)) {
        throw new Exception(gl.getShaderInfoLog(vs));
      }
      print ('Vertex shader compiled');
    });

    //
    // When we have the fragment shader source, compile it
    //
    fsFuture.then((src) {
      gl.shaderSource(fs, src);
      gl.compileShader(fs);
      if (!gl.getShaderParameter(fs, COMPILE_STATUS)) {
        throw new Exception(gl.getShaderInfoLog(fs));
      }
      print ('Fragment shader compiled');
    });


    //
    // When both the fragment shader and the vertex shader are 
    // compiled, we need to link them. But how do we know??
    //

    ***something... to make this be called when both the vertex and
    fragment shaders are compiled...***
    {
      program = gl.createProgram();
      gl.attachShader(program, fs);
      gl.attachShader(program, ps);
      gl.linkProgram(program);

    }

标签: webgl dart
1条回答
倾城 Initia
2楼-- · 2019-07-01 18:30

All call to then returns a Future that is triggered after the then callback is executed. So you have two futures from the compile step. After that you can use Future.wait to wait for a list of futures. The wait function returns a Future that is triggered after all input futures are completed.

Someting like this (not complete but for an idea how it works):

   var vsCompiledFuture = vsFuture.then((src) {
     // Compile
   });

   var fsCompiledFuture = fsFuture.then((src) {
     // Compile
   });

   Future.wait([vsCompiledFuture, fsCompiledFuture]).then((_) {
     // Link here...
   });

If you return the compiled shaders from you future callback, the Future.wait callback receives a list with all results from all futures.

查看更多
登录 后发表回答