Skip to content
Snippets Groups Projects
Commit 2e5423f9 authored by Giovanni Caruso's avatar Giovanni Caruso
Browse files

Merge branch 'master' into avatar

parents 4b24261c c7259a8f
Branches
No related tags found
1 merge request!55Avatar
Pipeline #105673 failed
import uuidv4 from "uuid/v4"
import yArray from "y-array"
import yMap from "y-map"
import yUnion, { Union } from "./y-union.js"
import yMemory from "y-memory"
import Y from "yjs"
......@@ -8,15 +9,13 @@ import yP2PMesh from "./y-p2p-mesh.js"
import WebRTCConnection from "./connection/WebRTC.js"
yMemory(Y)
Y.Struct.Union = Union
yUnion(Y)
yMap(Y)
yArray(Y)
yP2PMesh(Y)
import {
combineErasureIntervals,
spreadErasureIntervals,
flattenErasureIntervals,
} from "./erasure.js"
import { spreadErasureIntervals, flattenErasureIntervals } from "./erasure.js"
class Room extends EventTarget {
constructor(name) {
......@@ -33,7 +32,10 @@ class Room extends EventTarget {
addPath([x, y, w, colour]) {
const id = uuidv4()
this.shared.strokePoints.set(id, Y.Array).push([[x, y, w, colour]])
this.shared.eraseIntervals.set(id, Y.Union)
return id
}
......@@ -42,25 +44,9 @@ class Room extends EventTarget {
}
extendErasureIntervals(pathID, pointID, newIntervals) {
const self = this
// eslint-disable-next-line require-yield
this._y.db.requestTransaction(function* requestTransaction() {
const prevJSON = self.shared.eraseIntervals.get(pathID) || "[]"
const pathIntervals = JSON.parse(prevJSON)
const combinedIntervals = combineErasureIntervals(
[pathIntervals],
[flattenErasureIntervals({ [pointID]: newIntervals })],
)[0]
const postJSON = JSON.stringify(combinedIntervals)
if (prevJSON == postJSON) {
return
}
self.shared.eraseIntervals.set(pathID, postJSON)
})
this.shared.eraseIntervals
.get(pathID)
.merge(flattenErasureIntervals({ [pointID]: newIntervals }))
}
getPaths() {
......@@ -90,7 +76,7 @@ class Room extends EventTarget {
if (!intervals) return []
return spreadErasureIntervals(JSON.parse(intervals))
return spreadErasureIntervals(intervals.get())
}
inviteUser(id) {
......@@ -191,7 +177,13 @@ class Room extends EventTarget {
}
})
this.shared.eraseIntervals.observe((lineEvent) => {
dispatchRemovedIntervalsEvent(lineEvent)
if (lineEvent.type == "add") {
dispatchRemovedIntervalsEvent(lineEvent)
lineEvent.value.observe(() => {
dispatchRemovedIntervalsEvent(lineEvent)
})
}
})
}
}
......
/* global Y */
import { combineErasureIntervals } from "./erasure.js"
export const Union = {
create: function(id) {
return {
id: id,
union: null,
struct: "Union",
}
},
encode: function(op) {
const e = {
struct: "Union",
type: op.type,
id: op.id,
union: null,
}
if (op.requires != null) {
e.requires = op.requires
}
if (op.info != null) {
e.info = op.info
}
return e
},
requiredOps: function() {
return []
},
execute: function*() {},
}
export default function extendYUnion(Y) {
class YUnion extends Y.utils.CustomType {
constructor(os, model, contents) {
super()
this._model = model.id
this._parent = null
this._deepEventHandler = new Y.utils.EventListenerHandler()
this.os = os
this.union = model.union ? Y.utils.copyObject(model.union) : null
this.contents = contents
this.eventHandler = new Y.utils.EventHandler((op) => {
// compute op event
if (op.struct === "Insert") {
if (!Y.utils.compareIds(op.id, this.union)) {
const mergedContents = this._merge(JSON.parse(op.content[0]))
this.union = op.id
if (this.contents == mergedContents) {
return
}
this.contents = mergedContents
Y.utils.bubbleEvent(this, {
object: this,
type: "merge",
})
}
} else {
throw new Error("Unexpected Operation!")
}
})
}
_getPathToChild(/*childId*/) {
return undefined
}
_destroy() {
this.eventHandler.destroy()
this.eventHandler = null
this.contents = null
this._model = null
this._parent = null
this.os = null
this.union = null
}
get() {
return JSON.parse(this.contents)
}
_merge(newIntervals) {
const prevIntervals = this.get()
const mergedIntervals = combineErasureIntervals(
[prevIntervals],
[newIntervals],
)[0]
return JSON.stringify(mergedIntervals)
}
merge(newIntervals) {
const mergedContents = this._merge(newIntervals)
if (this.contents == mergedContents) {
return
}
const insert = {
id: this.os.getNextOpId(1),
left: null,
right: this.union,
origin: null,
parent: this._model,
content: [mergedContents],
struct: "Insert",
}
const eventHandler = this.eventHandler
this.os.requestTransaction(function*() {
yield* eventHandler.awaitOps(this, this.applyCreatedOperations, [
[insert],
])
})
// always remember to do that after this.os.requestTransaction
// (otherwise values might contain a undefined reference to type)
eventHandler.awaitAndPrematurelyCall([insert])
}
observe(f) {
this.eventHandler.addEventListener(f)
}
observeDeep(f) {
this._deepEventHandler.addEventListener(f)
}
unobserve(f) {
this.eventHandler.removeEventListener(f)
}
unobserveDeep(f) {
this._deepEventHandler.removeEventListener(f)
}
// eslint-disable-next-line require-yield
*_changed(transaction, op) {
this.eventHandler.receivedOp(op)
}
}
Y.extend(
"Union",
new Y.utils.CustomTypeDefinition({
name: "Union",
class: YUnion,
struct: "Union",
initType: function* YUnionInitializer(os, model) {
const union = model.union
const contents =
union !== null ? yield* this.getOperation(union).content[0] : "[]"
return new YUnion(os, model, contents)
},
createType: function YUnionCreator(os, model) {
const union = new YUnion(os, model, "[]")
return union
},
}),
)
}
if (typeof Y !== "undefined") {
extendYUnion(Y)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment