| 429 | | === Additional user attributes === |
| 430 | | |
| 431 | | TODO |
| | 429 | === State vectors === |
| | 430 | |
| | 431 | The state of a document is completely defined by a so-called state vector specifying how many operations each user did. For example, if user A made 2 requests and user B made 3 requests, the document has a certain state. All users that processed these 5 requests are in the same state. Note that it does not matter in which order the requests are processed (as long as the causal order is kept), which is the key concept behind the adOPTed algorithm. |
| | 432 | |
| | 433 | Each user maintains a state vector for each user that describes in which state that user is. This vector is updated every time a request is received from a particular user. This requires every user to send no-op requests if it has been inactive for some time, so that others know the state of this user. |
| | 434 | |
| | 435 | Also, each user maintains a request log in which all requests the user made are stored. This is required for transforming incoming requests from other users that were made in a different state of the document. Details to the adOPTed algorithm and how these transformations are performed can be found in the papers at http://portal.acm.org/citation.cfm?id=240305 and http://portal.acm.org/citation.cfm?doid=320297.320312. |
| | 436 | |
| | 437 | Some attributes of the following messages describe such a state vector. The state vector has the form "user_id:processed_requests;user_id:processed_requests;[...]" where user_id is the ID of a user and processed_requests describe the number of requests that this user is guaranteed to have already processed. |
| | 438 | |
| | 439 | === User attributes === |
| | 440 | |
| | 441 | The following attributes are used in the <sync-user> and <join-user> requests for text sessions: |
| | 442 | |
| | 443 | * time, StateVector: The current state vector of the user |
| | 444 | * caret: The position of the user's cursor, in characters, from the document beginning |
| | 445 | * selection: The number of characters selected, starting at the character caret. Negative means selection towards the beginning of the document. |
| | 446 | |
| | 447 | TODO: Viewport |
| 435 | | TODO |
| | 451 | These are additional messages sent during synchronization: |
| | 452 | |
| | 453 | {{{ |
| | 454 | <sync-state time="time" /> |
| | 455 | }}} |
| | 456 | |
| | 457 | * time, StateVector: The current state vector. |
| | 458 | |
| | 459 | Tells the state vector of the state the document currently is in. |
| | 460 | |
| | 461 | {{{ |
| | 462 | <sync-request user="user_id" time="time"> |
| | 463 | <operation /> |
| | 464 | </sync-request> |
| | 465 | }}} |
| | 466 | |
| | 467 | * user, Integer: The ID of the user that made the request. |
| | 468 | * time, State Vector: The state at which the request was made. |
| | 469 | * operation: The operation performed by the request, see below. |
| | 470 | |
| | 471 | Tells that at the given time a user made a request. This should be added to the request log and might be necessary to transform incoming operations or to compute Undo operations. |
| | 472 | |
| | 473 | {{{ |
| | 474 | <sync-segment author="user_id">Text</sync-segment> |
| | 475 | }}} |
| | 476 | |
| | 477 | * author, optional: The user ID of the user that wrote the text. |
| | 478 | * Text: The text that user wrote. |
| | 479 | |
| | 480 | Synchronizes a part of the initial document that was written by a single user. The <sync-segment> messages should be sent in-order so the document can be reconstructed. |
| 441 | | TODO |
| | 486 | {{{ |
| | 487 | <request user="user_id" time="time"> |
| | 488 | <operation /> |
| | 489 | </request> |
| | 490 | }}} |
| | 491 | |
| | 492 | * user, Integer: The ID of the user that made the request. |
| | 493 | * time, State Vector: The document state at which the request was made. |
| | 494 | * operation: The operation performed by the request, see below. |
| | 495 | |
| | 496 | Whenever a user issues a request the <request> message is sent. The user must have joined via the connection the request message comes from. <request> is sent to the whole subscription group. |
| | 497 | |
| | 498 | === Operations === |
| | 499 | |
| | 500 | There are two types of operations. Such operations that modify the document and such that do not. For example, inserting a character into the document does modify it, but moving the cursor of a user does not. If the operation of a request does not modify the document, the request is not recorded in the request log. |
| | 501 | |
| | 502 | The following operations are defined |
| | 503 | |
| | 504 | {{{ |
| | 505 | <insert pos="pos">text</insert> |
| | 506 | <insert-caret pos="pos">text</insert-caret> |
| | 507 | }}} |
| | 508 | |
| | 509 | * pos, Integer: The character offset at which to insert text. |
| | 510 | * text, String: The text to insert. |
| | 511 | |
| | 512 | An operation that inserts new text into the document. The <insert-caret> version additionally places the cursor of the user that made the request behind the inserted text. |
| | 513 | |
| | 514 | {{{ |
| | 515 | <delete pos="pos" len="len" /> |
| | 516 | <delete-caret pos="pos" len="len" /> |
| | 517 | }}} |
| | 518 | |
| | 519 | * pos, Integer: The character offset at which to start deleting characters |
| | 520 | * len, Integer: The number of characters to delete. |
| | 521 | |
| | 522 | Deletes text from the buffer. This operation is only used in <request> messages. Again, <delete-caret> additionally places the cursor of the user that made the request to the place where characters have been deleted. |
| | 523 | |
| | 524 | {{{ |
| | 525 | <delete pos="pos"><segment author="user_id">text</segment>[...]</delete> |
| | 526 | }}} |
| | 527 | |
| | 528 | * pos, Integer: The character offset at which to start deleting characters. |
| | 529 | * segments: The text that was deleted, including author information, i.e. which user wrote what text. |
| | 530 | |
| | 531 | Deletes text from the buffer and specifies what text is deleted. This operation is only used in <sync-request> messages. The synchronization client cannot deduce what text was actually deleted, but must be able to compute the reverse operation in case someone undoes the request. In a normal <request> message, other users can deduce what text was deleted by having a look at the document and which transformations were required to transform the request to the current state before the operation is actually executed. |
| | 532 | |
| | 533 | {{{ |
| | 534 | <no-op /> |
| | 535 | }}} |
| | 536 | |
| | 537 | Does nothing, and does especially not modify the document (see above). This is used when a user was inactive for some time to report its current state vector to the other users. |
| | 538 | |
| | 539 | {{{ |
| | 540 | <move caret="pos" selection="len" /> |
| | 541 | }}} |
| | 542 | |
| | 543 | * pos, Integer: The character offset to place the cursor to. |
| | 544 | * len, Integer: The length of the selection area, in characters. Negative values mean selection towards the beginning of the document. |
| | 545 | |
| | 546 | Changes the position of the user's cursor position and selection area. This operation does not modify the document. |
| | 547 | |
| | 548 | {{{ |
| | 549 | <undo /> |
| | 550 | <undo-caret /> |
| | 551 | }}} |
| | 552 | |
| | 553 | Undoes the last request of the user. The <undo-caret> version also places the user's cursor to the position where the operation was performed. |
| | 554 | |
| | 555 | {{{ |
| | 556 | <redo /> |
| | 557 | <redo-caret /> |
| | 558 | }}} |
| | 559 | |
| | 560 | Redoes the last request of the user. The <redo-caret> version also places the user's cursor to the position where the operation was performed. |