1616
1717package  org .scalajs .macrotaskexecutor 
1818
19- import  scala .collection .mutable 
2019import  scala .concurrent .{ExecutionContext , ExecutionContextExecutor }
2120import  scala .scalajs .js 
21+ import  scala .scalajs .js .annotation ._ 
2222import  scala .util .Random 
2323import  scala .util .control .NonFatal 
2424
@@ -29,15 +29,23 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
2929  private [this ] final  val  Undefined  =  " undefined" 
3030
3131  def  execute (runnable : Runnable ):  Unit  = 
32-     setImmediate(()  =>   runnable.run() )
32+     setImmediate(runnable)
3333
3434  def  reportFailure (cause : Throwable ):  Unit  = 
3535    cause.printStackTrace()
3636
37-   private [this ] val  setImmediate :  (() =>  Unit ) =>  Unit  =  {
37+   @ js.native
38+   private [this ] trait  TaskMap  extends  js.Object  {
39+     @ JSBracketAccess 
40+     def  apply (handle : Int ):  Runnable 
41+     @ JSBracketAccess 
42+     def  update (handle : Int , task : Runnable ):  Unit 
43+   }
44+ 
45+   private [this ] val  setImmediate :  Runnable  =>  Unit  =  {
3846    if  (js.typeOf(js.Dynamic .global.setImmediate) ==  Undefined ) {
3947      var  nextHandle  =  1 
40-       val  tasksByHandle  =  mutable. Map [ Int , ()  =>   Unit ]() 
48+       val  tasksByHandle  =  ( new  js. Object ). asInstanceOf [ TaskMap ] 
4149      var  currentlyRunningATask  =  false 
4250
4351      def  canUsePostMessage ():  Boolean  =  {
@@ -63,21 +71,17 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
6371        }
6472      }
6573
66-       def  runIfPresent (handle : Int ):  Unit  =  {
74+       def  runTaskForHandle (handle : Int ):  Unit  =  {
6775        if  (currentlyRunningATask) {
68-           js.Dynamic .global.setTimeout(() =>  runIfPresent (handle), 0 )
76+           js.Dynamic .global.setTimeout(() =>  runTaskForHandle (handle), 0 )
6977        } else  {
70-           tasksByHandle.get(handle) match  {
71-             case  Some (task) => 
72-               currentlyRunningATask =  true 
73-               try  {
74-                 task()
75-               } finally  {
76-                 tasksByHandle -=  handle
77-                 currentlyRunningATask =  false 
78-               }
79- 
80-             case  None  => 
78+           val  task  =  tasksByHandle(handle)
79+           currentlyRunningATask =  true 
80+           try  {
81+             task.run()
82+           } finally  {
83+             js.special.delete(tasksByHandle, handle)
84+             currentlyRunningATask =  false 
8185          }
8286        }
8387
@@ -95,7 +99,7 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
9599          js.Dynamic .global.Node .constructor(" return setImmediate" 
96100
97101        { k => 
98-           setImmediate(k )
102+           setImmediate(()  =>  k.run() )
99103          ()
100104        }
101105      } else  if  (canUsePostMessage()) {
@@ -115,7 +119,7 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
115119              .data
116120              .indexOf(messagePrefix)
117121              .asInstanceOf [Int ] ==  0 ) {
118-             runIfPresent (event.data.toString.substring(messagePrefix.length).toInt)
122+             runTaskForHandle (event.data.toString.substring(messagePrefix.length).toInt)
119123          }
120124        }
121125
@@ -129,22 +133,22 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
129133          val  handle  =  nextHandle
130134          nextHandle +=  1 
131135
132-           tasksByHandle  +=   (handle  ->  k) 
136+           tasksByHandle(handle)  =  k 
133137          js.Dynamic .global.postMessage(messagePrefix +  handle, " *" 
134138          ()
135139        }
136140      } else  if  (js.typeOf(js.Dynamic .global.MessageChannel ) !=  Undefined ) {
137141        val  channel  =  js.Dynamic .newInstance(js.Dynamic .global.MessageChannel )()
138142
139143        channel.port1.onmessage =  { (event : js.Dynamic ) => 
140-           runIfPresent (event.data.asInstanceOf [Int ])
144+           runTaskForHandle (event.data.asInstanceOf [Int ])
141145        }
142146
143147        { k => 
144148          val  handle  =  nextHandle
145149          nextHandle +=  1 
146150
147-           tasksByHandle  +=   (handle  ->  k) 
151+           tasksByHandle(handle)  =  k 
148152          channel.port2.postMessage(handle)
149153          ()
150154        }
@@ -153,13 +157,13 @@ object MacrotaskExecutor extends ExecutionContextExecutor {
153157        //  we're also not going to bother fast-pathing for IE6; just fall through
154158
155159        { k => 
156-           js.Dynamic .global.setTimeout(k , 0 )
160+           js.Dynamic .global.setTimeout(()  =>  k.run() , 0 )
157161          ()
158162        }
159163      }
160164    } else  {
161165      { k => 
162-         js.Dynamic .global.setImmediate(k )
166+         js.Dynamic .global.setImmediate(()  =>  k.run() )
163167        ()
164168      }
165169    }
0 commit comments