equal
deleted
inserted
replaced
23 type Entity_ID = String |
23 type Entity_ID = String |
24 |
24 |
25 trait Entity |
25 trait Entity |
26 { |
26 { |
27 val id: Entity_ID |
27 val id: Entity_ID |
28 def consume(session: Session, message: XML.Tree): Unit |
28 def consume(message: XML.Tree, forward: Command => Unit): Unit |
29 } |
29 } |
30 } |
30 } |
31 |
31 |
32 |
32 |
33 class Session(system: Isabelle_System) |
33 class Session(system: Isabelle_System) |
35 /* pervasive event buses */ |
35 /* pervasive event buses */ |
36 |
36 |
37 val global_settings = new Event_Bus[Session.Global_Settings.type] |
37 val global_settings = new Event_Bus[Session.Global_Settings.type] |
38 val raw_results = new Event_Bus[Isabelle_Process.Result] |
38 val raw_results = new Event_Bus[Isabelle_Process.Result] |
39 val raw_output = new Event_Bus[Isabelle_Process.Result] |
39 val raw_output = new Event_Bus[Isabelle_Process.Result] |
40 val results = new Event_Bus[Command] |
40 val commands_changed = new Event_Bus[Command_Set] |
41 |
|
42 val command_change = new Event_Bus[Command] |
|
43 |
41 |
44 |
42 |
45 /* unique ids */ |
43 /* unique ids */ |
46 |
44 |
47 private var id_count: BigInt = 0 |
45 private var id_count: BigInt = 0 |
64 |
62 |
65 private case class Start(timeout: Int, args: List[String]) |
63 private case class Start(timeout: Int, args: List[String]) |
66 private case object Stop |
64 private case object Stop |
67 private case class Begin_Document(path: String) |
65 private case class Begin_Document(path: String) |
68 |
66 |
69 private val session_actor = actor { |
67 private lazy val session_actor = actor { |
70 |
68 |
71 var prover: Isabelle_Process with Isar_Document = null |
69 var prover: Isabelle_Process with Isar_Document = null |
72 |
70 |
73 def register(entity: Session.Entity) { entities += (entity.id -> entity) } |
71 def register(entity: Session.Entity) { entities += (entity.id -> entity) } |
74 |
72 |
116 val target: Option[Session.Entity] = |
114 val target: Option[Session.Entity] = |
117 target_id match { |
115 target_id match { |
118 case None => None |
116 case None => None |
119 case Some(id) => lookup_entity(id) |
117 case Some(id) => lookup_entity(id) |
120 } |
118 } |
121 if (target.isDefined) target.get.consume(this, result.message) |
119 if (target.isDefined) target.get.consume(result.message, indicate_command_change) |
122 else if (result.kind == Isabelle_Process.Kind.STATUS) { |
120 else if (result.kind == Isabelle_Process.Kind.STATUS) { |
123 // global status message |
121 // global status message |
124 result.body match { |
122 result.body match { |
125 |
123 |
126 // document state assignment |
124 // document state assignment |
237 } |
235 } |
238 } |
236 } |
239 } |
237 } |
240 |
238 |
241 |
239 |
|
240 |
|
241 /** buffered command changes -- delay_first discipline **/ |
|
242 |
|
243 private lazy val command_change_buffer = actor { |
|
244 import scala.compat.Platform.currentTime |
|
245 |
|
246 var changed: Set[Command] = Set() |
|
247 var flush_time: Option[Long] = None |
|
248 |
|
249 def flush_timeout: Long = |
|
250 flush_time match { |
|
251 case None => 5000L |
|
252 case Some(time) => (time - currentTime) max 0 |
|
253 } |
|
254 |
|
255 def flush() |
|
256 { |
|
257 if (!changed.isEmpty) commands_changed.event(Command_Set(changed)) |
|
258 changed = Set() |
|
259 flush_time = None |
|
260 } |
|
261 |
|
262 def invoke() |
|
263 { |
|
264 val now = currentTime |
|
265 flush_time match { |
|
266 case None => flush_time = Some(now + 100) |
|
267 case Some(time) => if (now >= time) flush() |
|
268 } |
|
269 } |
|
270 |
|
271 loop { |
|
272 reactWithin(flush_timeout) { |
|
273 case command: Command => changed += command; invoke() |
|
274 case TIMEOUT => flush() |
|
275 case bad => System.err.println("command_change_buffer: ignoring bad message " + bad) |
|
276 } |
|
277 } |
|
278 } |
|
279 |
|
280 def indicate_command_change(command: Command) |
|
281 { |
|
282 command_change_buffer ! command |
|
283 } |
|
284 |
|
285 |
242 /* main methods */ |
286 /* main methods */ |
243 |
287 |
244 def start(timeout: Int, args: List[String]): Option[String] = |
288 def start(timeout: Int, args: List[String]): Option[String] = |
245 (session_actor !? Start(timeout, args)).asInstanceOf[Option[String]] |
289 (session_actor !? Start(timeout, args)).asInstanceOf[Option[String]] |
246 |
290 |