src/Pure/System/session.scala
changeset 45635 d9cf3520083c
parent 45633 2cb7e34f6096
child 45666 d83797ef0d2d
equal deleted inserted replaced
45634:b3dce535960f 45635:d9cf3520083c
    21   /* events */
    21   /* events */
    22 
    22 
    23   //{{{
    23   //{{{
    24   case object Global_Settings
    24   case object Global_Settings
    25   case object Caret_Focus
    25   case object Caret_Focus
    26   case object Assignment
       
    27   case class Commands_Changed(nodes: Set[Document.Node.Name], commands: Set[Command])
    26   case class Commands_Changed(nodes: Set[Document.Node.Name], commands: Set[Command])
    28 
    27 
    29   sealed abstract class Phase
    28   sealed abstract class Phase
    30   case object Inactive extends Phase
    29   case object Inactive extends Phase
    31   case object Startup extends Phase  // transient
    30   case object Startup extends Phase  // transient
    51 
    50 
    52   /* pervasive event buses */
    51   /* pervasive event buses */
    53 
    52 
    54   val global_settings = new Event_Bus[Session.Global_Settings.type]
    53   val global_settings = new Event_Bus[Session.Global_Settings.type]
    55   val caret_focus = new Event_Bus[Session.Caret_Focus.type]
    54   val caret_focus = new Event_Bus[Session.Caret_Focus.type]
    56   val assignments = new Event_Bus[Session.Assignment.type]
       
    57   val commands_changed = new Event_Bus[Session.Commands_Changed]
    55   val commands_changed = new Event_Bus[Session.Commands_Changed]
    58   val phase_changed = new Event_Bus[Session.Phase]
    56   val phase_changed = new Event_Bus[Session.Phase]
    59   val syslog_messages = new Event_Bus[Isabelle_Process.Result]
    57   val syslog_messages = new Event_Bus[Isabelle_Process.Result]
    60   val raw_output_messages = new Event_Bus[Isabelle_Process.Result]
    58   val raw_output_messages = new Event_Bus[Isabelle_Process.Result]
    61   val raw_messages = new Event_Bus[Isabelle_Process.Message]  // potential bottle-neck
    59   val raw_messages = new Event_Bus[Isabelle_Process.Message]  // potential bottle-neck
    79       }
    77       }
    80     }
    78     }
    81   }
    79   }
    82   //}}}
    80   //}}}
    83 
    81 
       
    82 
       
    83   /** pipelined change parsing **/
       
    84 
       
    85   //{{{
       
    86   private case class Text_Edits(
       
    87     syntax: Outer_Syntax,
       
    88     name: Document.Node.Name,
       
    89     previous: Future[Document.Version],
       
    90     text_edits: List[Document.Edit_Text],
       
    91     version_result: Promise[Document.Version])
       
    92 
       
    93   private val (_, change_parser) = Simple_Thread.actor("change_parser", daemon = true)
       
    94   {
       
    95     var finished = false
       
    96     while (!finished) {
       
    97       receive {
       
    98         case Stop => finished = true; reply(())
       
    99 
       
   100         case Text_Edits(syntax, name, previous, text_edits, version_result) =>
       
   101           val prev = previous.get_finished
       
   102           val (doc_edits, version) = Thy_Syntax.text_edits(syntax, prev, text_edits)
       
   103           version_result.fulfill(version)
       
   104           sender ! Change_Node(name, doc_edits, prev, version)
       
   105 
       
   106         case bad => System.err.println("change_parser: ignoring bad message " + bad)
       
   107       }
       
   108     }
       
   109   }
       
   110   //}}}
    84 
   111 
    85 
   112 
    86   /** main protocol actor **/
   113   /** main protocol actor **/
    87 
   114 
    88   /* global state */
   115   /* global state */
   256       val previous = global_state().history.tip.version
   283       val previous = global_state().history.tip.version
   257 
   284 
   258       prover.get.cancel_execution()
   285       prover.get.cancel_execution()
   259 
   286 
   260       val text_edits = header_edit(name, header) :: edits.map(edit => (name, edit))
   287       val text_edits = header_edit(name, header) :: edits.map(edit => (name, edit))
   261       val result = Future.fork { Thy_Syntax.text_edits(syntax, previous.join, text_edits) }
   288       val version = Future.promise[Document.Version]
   262       val change =
   289       val change = global_state.change_yield(_.continue_history(previous, text_edits, version))
   263         global_state.change_yield(_.continue_history(previous, text_edits, result.map(_._2)))
   290 
   264 
   291       change_parser ! Text_Edits(syntax, name, previous, text_edits, version)
   265       result.map {
       
   266         case (doc_edits, _) =>
       
   267           assignments.await { global_state().is_assigned(previous.get_finished) }
       
   268           this_actor ! Change_Node(name, doc_edits, previous.join, change.version.join)
       
   269       }
       
   270     }
   292     }
   271     //}}}
   293     //}}}
   272 
   294 
   273 
   295 
   274     /* exec state assignment */
   296     /* exec state assignment */
   276     def handle_assign(id: Document.Version_ID, assign: Document.Assign)
   298     def handle_assign(id: Document.Version_ID, assign: Document.Assign)
   277     //{{{
   299     //{{{
   278     {
   300     {
   279       val cmds = global_state.change_yield(_.assign(id, assign))
   301       val cmds = global_state.change_yield(_.assign(id, assign))
   280       for (cmd <- cmds) commands_changed_delay.invoke(cmd)
   302       for (cmd <- cmds) commands_changed_delay.invoke(cmd)
   281       assignments.event(Session.Assignment)
       
   282     }
   303     }
   283     //}}}
   304     //}}}
   284 
   305 
   285 
   306 
   286     /* removed versions */
   307     /* removed versions */
   442           else
   463           else
   443             handle_edits(name, header,
   464             handle_edits(name, header,
   444               List(Document.Node.Edits(text_edits), Document.Node.Perspective(perspective)))
   465               List(Document.Node.Edits(text_edits), Document.Node.Perspective(perspective)))
   445           reply(())
   466           reply(())
   446 
   467 
   447         case change: Change_Node if prover.isDefined =>
       
   448           handle_change(change)
       
   449 
       
   450         case Messages(msgs) =>
   468         case Messages(msgs) =>
   451           msgs foreach {
   469           msgs foreach {
   452             case input: Isabelle_Process.Input =>
   470             case input: Isabelle_Process.Input =>
   453               raw_messages.event(input)
   471               raw_messages.event(input)
   454 
   472 
   457               if (result.is_syslog) syslog_messages.event(result)
   475               if (result.is_syslog) syslog_messages.event(result)
   458               if (result.is_stdout || result.is_stderr) raw_output_messages.event(result)
   476               if (result.is_stdout || result.is_stderr) raw_output_messages.event(result)
   459               raw_messages.event(result)
   477               raw_messages.event(result)
   460           }
   478           }
   461 
   479 
   462         case bad => System.err.println("session_actor: ignoring bad message " + bad)
   480         case change: Change_Node
       
   481         if prover.isDefined && global_state().is_assigned(change.previous) =>
       
   482           handle_change(change)
       
   483 
       
   484         case bad if !bad.isInstanceOf[Change_Node] =>
       
   485           System.err.println("session_actor: ignoring bad message " + bad)
   463       }
   486       }
   464     }
   487     }
   465     //}}}
   488     //}}}
   466   }
   489   }
   467 
   490 
   471   def start(timeout: Time, args: List[String])
   494   def start(timeout: Time, args: List[String])
   472   { session_actor ! Start(timeout, args) }
   495   { session_actor ! Start(timeout, args) }
   473 
   496 
   474   def start(args: List[String]) { start (Time.seconds(25), args) }
   497   def start(args: List[String]) { start (Time.seconds(25), args) }
   475 
   498 
   476   def stop() { commands_changed_buffer !? Stop; session_actor !? Stop }
   499   def stop() { commands_changed_buffer !? Stop; change_parser !? Stop; session_actor !? Stop }
   477 
   500 
   478   def cancel_execution() { session_actor ! Cancel_Execution }
   501   def cancel_execution() { session_actor ! Cancel_Execution }
   479 
   502 
   480   def init_node(name: Document.Node.Name,
   503   def init_node(name: Document.Node.Name,
   481     header: Document.Node_Header, perspective: Text.Perspective, text: String)
   504     header: Document.Node_Header, perspective: Text.Perspective, text: String)