author | wenzelm |
Thu, 12 Aug 2010 17:55:23 +0200 | |
changeset 38367 | f7d2574dc3a6 |
parent 38366 | fea82d1add74 |
child 38370 | 8b15d0f98962 |
permissions | -rw-r--r-- |
36676 | 1 |
/* Title: Pure/PIDE/document.scala |
2 |
Author: Makarius |
|
3 |
||
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
4 |
Document as collection of named nodes, each consisting of an editable |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
5 |
list of commands. |
36676 | 6 |
*/ |
34407 | 7 |
|
34871
e596a0b71f3c
incorporate "proofdocument" part into main Isabelle/Pure.jar -- except for html_panel.scala, which depends on external library (Lobo/Cobra browser);
wenzelm
parents:
34868
diff
changeset
|
8 |
package isabelle |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
9 |
|
34760 | 10 |
|
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
11 |
import scala.collection.mutable |
37073 | 12 |
import scala.annotation.tailrec |
13 |
||
14 |
||
34823 | 15 |
object Document |
34483 | 16 |
{ |
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
17 |
/* formal identifiers */ |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
18 |
|
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
19 |
type ID = Long |
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
20 |
type Exec_ID = ID |
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
21 |
type Command_ID = ID |
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
22 |
type Version_ID = ID |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
23 |
|
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
24 |
val NO_ID: ID = 0 |
38355
8cb265fb12fe
represent document ids by (long) int, to benefit from the somewhat faster Inttab in ML (LinearSet in Scala is invariably indexed by native object ids);
wenzelm
parents:
38227
diff
changeset
|
25 |
|
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
26 |
def parse_id(s: String): ID = java.lang.Long.parseLong(s) |
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
27 |
def print_id(id: ID): String = id.toString |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
28 |
|
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
29 |
|
34818
7df68a8f0e3e
register Proof_Document instances as session entities -- handle Markup.EDIT messages locally;
wenzelm
parents:
34815
diff
changeset
|
30 |
|
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
31 |
/** named document nodes **/ |
38151 | 32 |
|
33 |
object Node |
|
34 |
{ |
|
35 |
val empty: Node = new Node(Linear_Set()) |
|
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
36 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
37 |
def command_starts(commands: Iterator[Command], offset: Int = 0): Iterator[(Command, Int)] = |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
38 |
{ |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
39 |
var i = offset |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
40 |
for (command <- commands) yield { |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
41 |
val start = i |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
42 |
i += command.length |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
43 |
(command, start) |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
44 |
} |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
45 |
} |
38151 | 46 |
} |
47 |
||
48 |
class Node(val commands: Linear_Set[Command]) |
|
49 |
{ |
|
50 |
/* command ranges */ |
|
51 |
||
52 |
def command_starts: Iterator[(Command, Int)] = |
|
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
53 |
Node.command_starts(commands.iterator) |
38151 | 54 |
|
55 |
def command_start(cmd: Command): Option[Int] = |
|
56 |
command_starts.find(_._1 == cmd).map(_._2) |
|
57 |
||
58 |
def command_range(i: Int): Iterator[(Command, Int)] = |
|
59 |
command_starts dropWhile { case (cmd, start) => start + cmd.length <= i } |
|
60 |
||
61 |
def command_range(i: Int, j: Int): Iterator[(Command, Int)] = |
|
62 |
command_range(i) takeWhile { case (_, start) => start < j } |
|
63 |
||
64 |
def command_at(i: Int): Option[(Command, Int)] = |
|
65 |
{ |
|
66 |
val range = command_range(i) |
|
67 |
if (range.hasNext) Some(range.next) else None |
|
68 |
} |
|
69 |
||
70 |
def proper_command_at(i: Int): Option[Command] = |
|
71 |
command_at(i) match { |
|
72 |
case Some((command, _)) => |
|
73 |
commands.reverse_iterator(command).find(cmd => !cmd.is_ignored) |
|
74 |
case None => None |
|
75 |
} |
|
76 |
} |
|
77 |
||
78 |
||
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
79 |
/* initial document */ |
34485 | 80 |
|
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
81 |
val init: Document = |
34835
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
wenzelm
parents:
34832
diff
changeset
|
82 |
{ |
38151 | 83 |
val doc = new Document(NO_ID, Map().withDefaultValue(Node.empty), Map()) |
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
84 |
doc.assign_execs(Nil) |
34835
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
wenzelm
parents:
34832
diff
changeset
|
85 |
doc |
67733fd0e3fa
back to explicit management of documents -- not as generic Session.Entity -- to avoid ill-defined referencing of new states;
wenzelm
parents:
34832
diff
changeset
|
86 |
} |
34660 | 87 |
|
34859 | 88 |
|
89 |
||
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
90 |
/** changes of plain text, eventually resulting in document edits **/ |
38151 | 91 |
|
92 |
type Node_Text_Edit = (String, List[Text_Edit]) // FIXME None: remove |
|
93 |
||
94 |
type Edit[C] = |
|
95 |
(String, // node name |
|
96 |
Option[List[(Option[C], Option[C])]]) // None: remove, Some: insert/remove commands |
|
34859 | 97 |
|
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
98 |
abstract class Snapshot |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
99 |
{ |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
100 |
val document: Document |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
101 |
val node: Document.Node |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
102 |
val is_outdated: Boolean |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
103 |
def convert(offset: Int): Int |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
104 |
def revert(offset: Int): Int |
38361 | 105 |
def state(command: Command): Command.State |
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
106 |
} |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
107 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
108 |
object Change |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
109 |
{ |
38366
fea82d1add74
simplified/clarified Change: transition prev --edits--> result, based on futures;
wenzelm
parents:
38365
diff
changeset
|
110 |
val init = new Change(Future.value(Document.init), Nil, Future.value(Nil, Document.init)) |
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
111 |
} |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
112 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
113 |
class Change( |
38366
fea82d1add74
simplified/clarified Change: transition prev --edits--> result, based on futures;
wenzelm
parents:
38365
diff
changeset
|
114 |
val prev: Future[Document], |
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
115 |
val edits: List[Node_Text_Edit], |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
116 |
val result: Future[(List[Edit[Command]], Document)]) |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
117 |
{ |
38366
fea82d1add74
simplified/clarified Change: transition prev --edits--> result, based on futures;
wenzelm
parents:
38365
diff
changeset
|
118 |
val document: Future[Document] = result.map(_._2) |
fea82d1add74
simplified/clarified Change: transition prev --edits--> result, based on futures;
wenzelm
parents:
38365
diff
changeset
|
119 |
def is_finished: Boolean = prev.is_finished && document.is_finished |
fea82d1add74
simplified/clarified Change: transition prev --edits--> result, based on futures;
wenzelm
parents:
38365
diff
changeset
|
120 |
def is_assigned: Boolean = is_finished && document.join.assignment.is_finished |
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
121 |
} |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
122 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
123 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
124 |
|
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
125 |
/** editing **/ |
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
126 |
|
38364
827b90f18ff4
Change: eliminated id, which is merely the resulting document id and is only required in joined state anyway;
wenzelm
parents:
38363
diff
changeset
|
127 |
def text_edits(session: Session, old_doc: Document, edits: List[Node_Text_Edit]) |
827b90f18ff4
Change: eliminated id, which is merely the resulting document id and is only required in joined state anyway;
wenzelm
parents:
38363
diff
changeset
|
128 |
: (List[Edit[Command]], Document) = |
34824
ac35eee85f5c
renamed current_document to recent_document (might be a bit older than current_change);
wenzelm
parents:
34823
diff
changeset
|
129 |
{ |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
130 |
require(old_doc.assignment.is_finished) |
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
131 |
|
34859 | 132 |
|
133 |
/* phase 1: edit individual command source */ |
|
134 |
||
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
135 |
@tailrec def edit_text(eds: List[Text_Edit], |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
136 |
commands: Linear_Set[Command]): Linear_Set[Command] = |
34859 | 137 |
{ |
138 |
eds match { |
|
139 |
case e :: es => |
|
38227
6bbb42843b6e
concentrate structural document notions in document.scala;
wenzelm
parents:
38220
diff
changeset
|
140 |
Node.command_starts(commands.iterator).find { |
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
141 |
case (cmd, cmd_start) => |
37685
305c326db33b
more efficient document model/view -- avoid repeated iteration over commands from start, prefer bulk operations;
wenzelm
parents:
37186
diff
changeset
|
142 |
e.can_edit(cmd.source, cmd_start) || |
305c326db33b
more efficient document model/view -- avoid repeated iteration over commands from start, prefer bulk operations;
wenzelm
parents:
37186
diff
changeset
|
143 |
e.is_insert && e.start == cmd_start + cmd.length |
34863 | 144 |
} match { |
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
145 |
case Some((cmd, cmd_start)) if e.can_edit(cmd.source, cmd_start) => |
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
146 |
val (rest, text) = e.edit(cmd.source, cmd_start) |
38367 | 147 |
val new_commands = commands.insert_after(Some(cmd), Command.unparsed(text)) - cmd |
34863 | 148 |
edit_text(rest.toList ::: es, new_commands) |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
149 |
|
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
150 |
case Some((cmd, cmd_start)) => |
38367 | 151 |
edit_text(es, commands.insert_after(Some(cmd), Command.unparsed(e.text))) |
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
152 |
|
34859 | 153 |
case None => |
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
154 |
require(e.is_insert && e.start == 0) |
38367 | 155 |
edit_text(es, commands.insert_after(None, Command.unparsed(e.text))) |
34859 | 156 |
} |
34863 | 157 |
case Nil => commands |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
158 |
} |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
159 |
} |
34582 | 160 |
|
34818
7df68a8f0e3e
register Proof_Document instances as session entities -- handle Markup.EDIT messages locally;
wenzelm
parents:
34815
diff
changeset
|
161 |
|
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
162 |
/* phase 2: recover command spans */ |
34859 | 163 |
|
37073 | 164 |
@tailrec def parse_spans(commands: Linear_Set[Command]): Linear_Set[Command] = |
34859 | 165 |
{ |
38367 | 166 |
commands.iterator.find(_.is_unparsed) match { |
34859 | 167 |
case Some(first_unparsed) => |
37071
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
168 |
val first = |
37072
9105c8237c7a
renamed "rev" to "reverse" following usual Scala conventions;
wenzelm
parents:
37071
diff
changeset
|
169 |
commands.reverse_iterator(first_unparsed).find(_.is_command) getOrElse commands.head |
37071
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
170 |
val last = |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
171 |
commands.iterator(first_unparsed).find(_.is_command) getOrElse commands.last |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
172 |
val range = |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
173 |
commands.iterator(first).takeWhile(_ != last).toList ::: List(last) |
34859 | 174 |
|
37071
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
175 |
val sources = range.flatMap(_.span.map(_.source)) |
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
176 |
val spans0 = Thy_Syntax.parse_spans(session.current_syntax.scan(sources.mkString)) |
34485 | 177 |
|
34859 | 178 |
val (before_edit, spans1) = |
37071
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
179 |
if (!spans0.isEmpty && first.is_command && first.span == spans0.head) |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
180 |
(Some(first), spans0.tail) |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
181 |
else (commands.prev(first), spans0) |
34544
56217d219e27
proofdocument-versions get id from changes
immler@in.tum.de
parents:
34541
diff
changeset
|
182 |
|
34859 | 183 |
val (after_edit, spans2) = |
37071
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
184 |
if (!spans1.isEmpty && last.is_command && last.span == spans1.last) |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
185 |
(Some(last), spans1.take(spans1.length - 1)) |
dd3540a489f7
parse_spans: cover full range including adjacent well-formed commands -- intermediate ignored and malformed commands are reparsed as well;
wenzelm
parents:
37059
diff
changeset
|
186 |
else (commands.next(last), spans1) |
34859 | 187 |
|
34863 | 188 |
val inserted = spans2.map(span => new Command(session.create_id(), span)) |
189 |
val new_commands = |
|
190 |
commands.delete_between(before_edit, after_edit).append_after(before_edit, inserted) |
|
34866
a4fe43df58b3
new unparsed span for text right after existing command;
wenzelm
parents:
34863
diff
changeset
|
191 |
parse_spans(new_commands) |
34485 | 192 |
|
34863 | 193 |
case None => commands |
34485 | 194 |
} |
195 |
} |
|
34739 | 196 |
|
34554
7dc6c231da40
abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents:
34551
diff
changeset
|
197 |
|
34859 | 198 |
/* phase 3: resulting document edits */ |
199 |
||
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
200 |
{ |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
201 |
val doc_edits = new mutable.ListBuffer[Edit[Command]] |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
202 |
var nodes = old_doc.nodes |
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
203 |
var former_assignment = old_doc.assignment.join |
34660 | 204 |
|
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
205 |
for ((name, text_edits) <- edits) { |
38151 | 206 |
val commands0 = nodes(name).commands |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
207 |
val commands1 = edit_text(text_edits, commands0) |
38220 | 208 |
val commands2 = parse_spans(commands1) // FIXME somewhat slow |
34863 | 209 |
|
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
210 |
val removed_commands = commands0.iterator.filter(!commands2.contains(_)).toList |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
211 |
val inserted_commands = commands2.iterator.filter(!commands0.contains(_)).toList |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
212 |
|
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
213 |
val cmd_edits = |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
214 |
removed_commands.reverse.map(cmd => (commands0.prev(cmd), None)) ::: |
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
215 |
inserted_commands.map(cmd => (commands2.prev(cmd), Some(cmd))) |
34660 | 216 |
|
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
217 |
doc_edits += (name -> Some(cmd_edits)) |
38151 | 218 |
nodes += (name -> new Node(commands2)) |
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
219 |
former_assignment --= removed_commands |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
220 |
} |
38364
827b90f18ff4
Change: eliminated id, which is merely the resulting document id and is only required in joined state anyway;
wenzelm
parents:
38363
diff
changeset
|
221 |
(doc_edits.toList, new Document(session.create_id(), nodes, former_assignment)) |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
222 |
} |
34485 | 223 |
} |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
224 |
} |
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
225 |
|
34855
81d0410dc3ac
iterators for ranges of commands/starts -- avoid extra array per document;
wenzelm
parents:
34853
diff
changeset
|
226 |
|
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
227 |
class Document( |
38150
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
wenzelm
parents:
37849
diff
changeset
|
228 |
val id: Document.Version_ID, |
38151 | 229 |
val nodes: Map[String, Document.Node], |
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
230 |
former_assignment: Map[Command, Command]) // FIXME !? |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
231 |
{ |
34855
81d0410dc3ac
iterators for ranges of commands/starts -- avoid extra array per document;
wenzelm
parents:
34853
diff
changeset
|
232 |
/* command state assignment */ |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
233 |
|
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
234 |
val assignment = Future.promise[Map[Command, Command]] |
34853
32b49207ca20
misc tuning and clarification of Document/Change;
wenzelm
parents:
34840
diff
changeset
|
235 |
def await_assignment { assignment.join } |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
236 |
|
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
237 |
@volatile private var tmp_assignment = former_assignment |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
238 |
|
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
239 |
def assign_execs(execs: List[(Command, Command)]) |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
240 |
{ |
38363
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
241 |
assignment.fulfill(tmp_assignment ++ execs) |
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
wenzelm
parents:
38361
diff
changeset
|
242 |
tmp_assignment = Map() |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
243 |
} |
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
244 |
|
38361 | 245 |
def current_state(cmd: Command): Command.State = |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
246 |
{ |
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
247 |
require(assignment.is_finished) |
36990
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
wenzelm
parents:
36956
diff
changeset
|
248 |
(assignment.join).get(cmd) match { |
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
wenzelm
parents:
36956
diff
changeset
|
249 |
case Some(cmd_state) => cmd_state.current_state |
38361 | 250 |
case None => new Command.State(cmd, Command.Status.UNDEFINED, 0, Nil, cmd.empty_markup) |
36990
449628c148cf
explicit Command.Status.UNDEFINED -- avoid fragile/cumbersome treatment of Option[State];
wenzelm
parents:
36956
diff
changeset
|
251 |
} |
34840
6c5560d48561
more precise treatment of document/state assigment;
wenzelm
parents:
34838
diff
changeset
|
252 |
} |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
253 |
} |