<html window-icon="https://cdn2.iconfinder.com/data/icons/arts-crafts-sewing/24/sewing_thread_handcraft_craft_1-32.png">
  <head>
    <title>Threads demo</title>
    <style>
      div#content { flow:horizontal; size:*; }
      div#explanation { size:*; padding:20px; overflow:auto; }
      div#explanation > pre { padding:10px; border:1px dotted #999; background:#ffffef; }

      div#tasks { width:300px; height:*; }
      div#tasks > select { size:*; display:block; }
      div#tasks > select progress { margin-left: 5px; }
    </style>
    <script type="text/tiscript">

      var taskNo = 0;

      $(#start-task).onClick = function()
      {
        ++taskNo;

        var taskElem = $(div#tasks > select).$append(<option>Task { taskNo }<progress max=100 /> <span.result /></option>);

        function onProgress(p100) { taskElem.$(progress).value = p100; }
        function onDone(taskId) {
          taskElem.$(span.result).text = "Done!";
          taskElem.$(progress).remove();
        }

        view.exec_task(taskNo, onProgress, onDone);
      }
    </script>
  </head>
<body>
  <h2>Sciter UI, threads demo</h2>
  <div id="content">
    <div id="tasks">
       <button id="start-task">Start Task</button>
       <select type="select"></select>
    </div>
    <div id="explanation">
      <p>The Start Task onClick handler is defined as</p>
      <pre>
$(#start-task).onClick = function()
{
  var taskElem = $(div#tasks > select)
      .$append(&lt;option>Task { ++taskNo }
               &lt;progress max=100 />
               &lt;span.result />&lt;/option>);
  function onProgress(p100) {
    taskElem.$(progress).value = p100;
  }
  function onDone(taskId) {
    taskElem.$(span.result).text = "Done!";
    taskElem.$(progress).remove();
  }
  view.exec_task(taskId, onProgress, onDone);
}
      </pre>

      <p>It defines couple of callback functions and calls <code>view.exec_task()</code> with them.</p>
      <p>The <code>view.exec_task()</code> native method is implemented in <code>EventHandler::exec_task()</code>.</p>
      <p>The <code>EventHandler::exec_task()</code> starts worker thread passing <em>taskNo</em>, <em>onProgress</em> and
         <em>onDone</em> parameters to it.</p>
      <p>Worker thread body is defined in Rust code as:</p>
      <pre>
// worker thread body, simulate time consuming task
fn thread_body(task_no: i32, progress: Value, done: Value)
{
  for i in 1..100 {
    std::thread::sleep(std::time::Duration::from_millis(100));
    progress.call(None, &amp;make_args!(i), None).unwrap(); // report task progress
  }
  // report task completion,
  // we can pass some result data here, for now just taskId
  done.call(None, &amp;make_args!(task_no), None).unwrap();
}
      </pre>
      <p>As you see it calls passed callback functions.</p>
    </div>
  </div>
</body>
</html>