src/Pure/PIDE/document.ML
changeset 59193 59f1591a11cb
parent 59086 94b2690ad494
child 59198 c73933e07c03
equal deleted inserted replaced
59192:a1d6d6db781b 59193:59f1591a11cb
    35 val timing = Unsynchronized.ref false;
    35 val timing = Unsynchronized.ref false;
    36 fun timeit msg e = cond_timeit (! timing) msg e;
    36 fun timeit msg e = cond_timeit (! timing) msg e;
    37 
    37 
    38 
    38 
    39 
    39 
    40 
       
    41 
       
    42 
       
    43 (** document structure **)
    40 (** document structure **)
    44 
    41 
    45 fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ Document_ID.print id);
    42 fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ Document_ID.print id);
    46 fun err_undef kind id = error ("Undefined " ^ kind ^ ": " ^ Document_ID.print id);
    43 fun err_undef kind id = error ("Undefined " ^ kind ^ ": " ^ Document_ID.print id);
    47 
    44 
   283 type blob_digest = (string * string option) Exn.result;  (*file node name, raw digest*)
   280 type blob_digest = (string * string option) Exn.result;  (*file node name, raw digest*)
   284 
   281 
   285 type execution =
   282 type execution =
   286  {version_id: Document_ID.version,  (*static version id*)
   283  {version_id: Document_ID.version,  (*static version id*)
   287   execution_id: Document_ID.execution,  (*dynamic execution id*)
   284   execution_id: Document_ID.execution,  (*dynamic execution id*)
   288   delay_request: unit future,  (*pending event timer request*)
   285   delay_request: unit future};  (*pending event timer request*)
   289   frontier: Future.task Symtab.table};  (*node name -> running execution task*)
       
   290 
   286 
   291 val no_execution: execution =
   287 val no_execution: execution =
   292   {version_id = Document_ID.none, execution_id = Document_ID.none,
   288   {version_id = Document_ID.none,
   293    delay_request = Future.value (), frontier = Symtab.empty};
   289    execution_id = Document_ID.none,
   294 
   290    delay_request = Future.value ()};
   295 fun new_execution version_id delay_request frontier : execution =
   291 
   296   {version_id = version_id, execution_id = Execution.start (),
   292 fun new_execution version_id delay_request : execution =
   297    delay_request = delay_request, frontier = frontier};
   293   {version_id = version_id,
       
   294    execution_id = Execution.start (),
       
   295    delay_request = delay_request};
   298 
   296 
   299 abstype state = State of
   297 abstype state = State of
   300  {versions: version Inttab.table,  (*version id -> document content*)
   298  {versions: version Inttab.table,  (*version id -> document content*)
   301   blobs: (SHA1.digest * string list) Symtab.table,  (*raw digest -> digest, lines*)
   299   blobs: (SHA1.digest * string list) Symtab.table,  (*raw digest -> digest, lines*)
   302   commands: (string * blob_digest list * Token.T list lazy) Inttab.table,
   300   commands: (string * blob_digest list * Token.T list lazy) Inttab.table,
   316 
   314 
   317 
   315 
   318 (* document versions *)
   316 (* document versions *)
   319 
   317 
   320 fun define_version version_id version =
   318 fun define_version version_id version =
   321   map_state (fn (versions, blobs, commands, {delay_request, frontier, ...}) =>
   319   map_state (fn (versions, blobs, commands, {delay_request, ...}) =>
   322     let
   320     let
   323       val versions' = Inttab.update_new (version_id, version) versions
   321       val versions' = Inttab.update_new (version_id, version) versions
   324         handle Inttab.DUP dup => err_dup "document version" dup;
   322         handle Inttab.DUP dup => err_dup "document version" dup;
   325       val execution' = new_execution version_id delay_request frontier;
   323       val execution' = new_execution version_id delay_request;
   326     in (versions', blobs, commands, execution') end);
   324     in (versions', blobs, commands, execution') end);
   327 
   325 
   328 fun the_version (State {versions, ...}) version_id =
   326 fun the_version (State {versions, ...}) version_id =
   329   (case Inttab.lookup versions version_id of
   327   (case Inttab.lookup versions version_id of
   330     NONE => err_undef "document version" version_id
   328     NONE => err_undef "document version" version_id
   406 (* document execution *)
   404 (* document execution *)
   407 
   405 
   408 fun start_execution state = state |> map_state (fn (versions, blobs, commands, execution) =>
   406 fun start_execution state = state |> map_state (fn (versions, blobs, commands, execution) =>
   409   timeit "Document.start_execution" (fn () =>
   407   timeit "Document.start_execution" (fn () =>
   410     let
   408     let
   411       val {version_id, execution_id, delay_request, frontier} = execution;
   409       val {version_id, execution_id, delay_request} = execution;
   412 
   410 
   413       val delay = seconds (Options.default_real "editor_execution_delay");
   411       val delay = seconds (Options.default_real "editor_execution_delay");
   414 
   412 
   415       val _ = Future.cancel delay_request;
   413       val _ = Future.cancel delay_request;
   416       val delay_request' = Event_Timer.future (Time.+ (Time.now (), delay));
   414       val delay_request' = Event_Timer.future (Time.+ (Time.now (), delay));
   417 
   415 
   418       val new_tasks =
   416       val _ =
   419         nodes_of (the_version state version_id) |> String_Graph.schedule
   417         nodes_of (the_version state version_id) |> String_Graph.schedule
   420           (fn deps => fn (name, node) =>
   418           (fn deps => fn (name, node) =>
   421             if visible_node node orelse pending_result node then
   419             if visible_node node orelse pending_result node then
   422               let
   420               let
   423                 val more_deps =
       
   424                   Future.task_of delay_request' :: the_list (Symtab.lookup frontier name);
       
   425                 fun body () =
   421                 fun body () =
   426                   iterate_entries (fn (_, opt_exec) => fn () =>
   422                   iterate_entries (fn (_, opt_exec) => fn () =>
   427                     (case opt_exec of
   423                     (case opt_exec of
   428                       SOME exec =>
   424                       SOME exec =>
   429                         if Execution.is_running execution_id
   425                         if Execution.is_running execution_id
   431                         else NONE
   427                         else NONE
   432                     | NONE => NONE)) node ()
   428                     | NONE => NONE)) node ()
   433                   handle exn => if Exn.is_interrupt exn then () (*sic!*) else reraise exn;
   429                   handle exn => if Exn.is_interrupt exn then () (*sic!*) else reraise exn;
   434                 val future =
   430                 val future =
   435                   (singleton o Future.forks)
   431                   (singleton o Future.forks)
   436                     {name = "theory:" ^ name, group = SOME (Future.new_group NONE),
   432                    {name = "theory:" ^ name,
   437                       deps = more_deps @ map #2 (maps #2 deps),
   433                     group = SOME (Future.new_group NONE),
   438                       pri = 0, interrupts = false} body;
   434                     deps = Future.task_of delay_request' :: maps #2 deps,
   439               in [(name, Future.task_of future)] end
   435                     pri = 0, interrupts = false} body;
       
   436               in [Future.task_of future] end
   440             else []);
   437             else []);
   441       val frontier' = (fold o fold) Symtab.update new_tasks frontier;
       
   442       val execution' =
   438       val execution' =
   443         {version_id = version_id, execution_id = execution_id,
   439         {version_id = version_id, execution_id = execution_id, delay_request = delay_request'};
   444          delay_request = delay_request', frontier = frontier'};
       
   445     in (versions, blobs, commands, execution') end));
   440     in (versions, blobs, commands, execution') end));
   446 
   441 
   447 
   442 
   448 
   443 
   449 (** document update **)
   444 (** document update **)