From da107ab17c8c71645a448265a1f7b79c16212c57 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Mon, 13 Apr 2015 17:20:54 -0700 Subject: [PATCH] share.coffee lib/sole implementation --- main/app/talk/core.hook | 8 +++- main/lib/base.css | 2 +- main/lib/sole/core.hook | 5 +-- main/mar/sole-action/door.hook | 5 +-- main/mar/sole-effect/door.hook | 6 +-- main/pub/sole/fab/hymn.hook | 45 ++++++++++++------- main/pub/sole/src/share.coffee | 79 ++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 main/pub/sole/src/share.coffee diff --git a/main/app/talk/core.hook b/main/app/talk/core.hook index a91015faf..45e47820e 100644 --- a/main/app/talk/core.hook +++ b/main/app/talk/core.hook @@ -1737,7 +1737,13 @@ |= oug=? ^- tape ?+ -.sep "" - %url (weld ": " (scag 62 (earn p.sep))) + %url + =+ txt=(earn p.sep) + %+ weld "/ " + ?: (gte 62 (lent txt)) + txt + (weld (scag 61 (earn p.sep)) "…") + :: %lin =+ txt=(trip q.sep) ?: p.sep diff --git a/main/lib/base.css b/main/lib/base.css index a22b9065b..69c5bb780 100644 --- a/main/lib/base.css +++ b/main/lib/base.css @@ -144,4 +144,4 @@ input { #ship:focus, input:focus { background-color: #eee; -} \ No newline at end of file +} diff --git a/main/lib/sole/core.hook b/main/lib/sole/core.hook index f7a54b233..41f499103 100644 --- a/main/lib/sole/core.hook +++ b/main/lib/sole/core.hook @@ -32,8 +32,8 @@ :: for any sole state +>, obeys :: :: =+ [x=(transmute a b) y=(transmute b a)] - :: .= (apply:(apply b) x) - :: (apply:(apply a) y) + :: .= (apply:(apply a) x) + :: (apply:(apply b) y) :: ++ transmute :: dex as after sin |= [sin=sole-edit dex=sole-edit] @@ -103,7 +103,6 @@ |= sole-change ^- [sole-edit sole-share] ?> &(=(his.ler his.ven) (lte own.ler own.ven)) - ?> &(=(his.ler his.ven) (lte own.ler own.ven)) ?> |(!=(own.ler own.ven) =(haw (sham buf)) =(haw 0)) :: trust the clock =. leg (scag (sub own.ven own.ler) leg) :: ~? !=(own.ler own.ven) [%miss-leg leg] diff --git a/main/mar/sole-action/door.hook b/main/mar/sole-action/door.hook index 286d33ffb..4325e2a04 100644 --- a/main/mar/sole-action/door.hook +++ b/main/mar/sole-action/door.hook @@ -14,8 +14,7 @@ |= jon=^json ^- sole-action %- need %. jon => [jo ..sole-action] - |^ =- ~! (-) - - (fo %ret (of det/change ~)) + |^ (fo %ret (of det/change ~)) ++ fo |* [a=term b=fist] |=(c=json ?.(=([%s a] c) (b c) (some [a ~]))) @@ -30,7 +29,7 @@ ++ edit %+ fo %nop %+ ra mor/|=(json (edit +<)) - (of del/ni set/(cu tuba sa) ins/(ot at/ni new/char ~) ~) + (of del/ni set/(cu tuba sa) ins/(ot at/ni cha/char ~) ~) -- :: ++ noun sole-action :: clam from %noun diff --git a/main/mar/sole-effect/door.hook b/main/mar/sole-effect/door.hook index 36c706836..3e80b24a0 100644 --- a/main/mar/sole-effect/door.hook +++ b/main/mar/sole-effect/door.hook @@ -20,7 +20,7 @@ %mor [%a (turn p.ted ..$)] %del (joba %del (jone p.ted)) %set (joba %set (jape (tufa p.ted))) - %ins (joba %ins (jobe at/(jone p.ted) new/s/(tuft q.ted) ~)) + %ins (joba %ins (jobe at/(jone p.ted) cha/s/(tuft q.ted) ~)) == -- -- @@ -47,8 +47,8 @@ %err (joba %hop (jone p.sef)) %txt (joba %txt (jape p.sef)) %tan (joba %tan (jape (wush 160 p.sef))) - %det json:~(grow mar-sole-change +.sef) - %pro (jobe vis/b/vis.sef tag/s/tag.sef cad/(jape cad.sef) ~) + %det (joba %det json:~(grow mar-sole-change +.sef)) + %pro (joba %pro (jobe vis/b/vis.sef tag/s/tag.sef cad/(jape cad.sef) ~)) ?(%bel %clr %nex) (joba %act %s -.sef) == -- diff --git a/main/pub/sole/fab/hymn.hook b/main/pub/sole/fab/hymn.hook index 7de72abd8..c46d67534 100644 --- a/main/pub/sole/fab/hymn.hook +++ b/main/pub/sole/fab/hymn.hook @@ -32,21 +32,23 @@ ;body ;div#err; ;div#term:"" + ;script@"src/share.coffee"(type "text/coffeescript"); ;script(type "text/coffeescript") ;- %- trip ''' [DOM,recl,rend] = [React.DOM, React.createClass, React.renderComponent] [div, pre] = [DOM.div, DOM.pre] + str = JSON.stringify Matr = recl render: -> [pro,cur] = [@props.prompt + " ", @props.cursor + 1] prompt = "#{pro.slice(0,cur)}\u0332#{pro.slice(cur)}" lines = [prompt, @props.rows...] div {}, lines.slice().reverse().map (lin)-> pre {}, lin - + $ -> termRev = 0 pressed = [] - deltim = null + deltim = null met = $('
').text('m').css(display: 'none').appendTo(term).width()
         subs = ""
@@ -56,7 +58,7 @@
         #   if path is subs
         #     return
         #   if subs
-        #     urb.unsubscribe {path:subs}
+        #     urb.unsubscribe path: subs
         #   subs = path
         #   urb.subscribe {path}, (err,dat)->
         #       if err or dat.data.ok
@@ -68,28 +70,39 @@
         #         document.title = "Matrix"  # XX  debug
         # $(window).resize()
 
-        matr = rend (Matr rows:[], prompt:"", cursor:1), term
         flash = ($el, background)->
           $el.css {background}
           if background
             setTimeout (()-> flash $el,''), 50
+            
+        matr = rend (Matr rows:[], prompt:"", input:"", history:[], cursor:1), term
+        update = (a) -> matr.setProps a
+        buffer = new Share ""
+        
         
         peer = (ruh) ->
-          switch false
-            when !ruh.map then ruh.map peer
-            # when !ruh.pro then matr.setProps prompt: ruh.pro
-            # when !ruh.hop then matr.setProps cursor: ruh.hop
-            # when !ruh.out 
-            #   matr.setProps rows: [ruh.out, matr.props.rows...]
-            # when !ruh.act then switch ruh.act
-            #   when 'clr' then matr.setProps rows:[]
-            #   when 'bel' then flash ($ 'body'), 'black'
+          switch
+            when ruh.map then ruh.map peer
+            when ruh.hop then update cursor: buffer.transpose ruh.hop
+            when ruh.pro then update prompt: ruh.pro.cad
+            when ruh.txt then update rows: [ruh.txt, matr.props.rows...]
+            when ruh.blk then console.log "Stub #{str ruh}"
+            when ruh.act then switch ruh.act
+              when 'clr' then update rows:[]
+              when 'bel' then flash ($ 'body'), 'black'
+              when 'nex' then update
+                input: ""
+                cursor: 1
+                history: [matr.props.input, matr.props.history...]
             #   else throw "Unknown "+(JSON.stringify ruh)
-            else console.log ruh
+            else v = Object.keys(ruh); console.log v, ruh[v[0]]
         
         urb.bind "/sole", {wire:"/"}, (err,d)->
           if d.data then peer d.data
 
+        sendAction = (data)->
+          urb.send {mark: 'sole-action', data}, (n,err)->
+            if err.data then $('#err')[0].innerText = err.data.mess
         #later = (data)->
         #  if data
         #    pressed.push data
@@ -120,7 +133,9 @@
               act: 'uncap'
           if key
             e.preventDefault()
-            urb.send mark: 'dill-belt', data: {mod,key}
+            if key.str
+              det = buffer.transmit ins: cha: str, at: matr.props.cursor
+              sendAction {det}
             
             # amod = (arr)->
             #   for i in arr
diff --git a/main/pub/sole/src/share.coffee b/main/pub/sole/src/share.coffee
new file mode 100644
index 000000000..ecb3be12f
--- /dev/null
+++ b/main/pub/sole/src/share.coffee
@@ -0,0 +1,79 @@
+# See /hook/core/sole/lib
+str = JSON.stringify
+class window.Share
+  constructor: (@buf = "", @ven = [0, 0], @leg = []) ->
+  #
+  abet: ()-> buf:@buf, leg:@leg.slice(), ven:@ven.slice()
+  apply: (ted)->
+    if 'nop' == ted then return
+    if ted.map then ted.map @apply
+    switch Object.keys(ted)[0]
+      when 'set' then @buf = ted.set
+      when 'del' then @buf = @buf.slice(0,ted.del) + @buf.slice(ted.del + 1)
+      when 'ins'
+        {at,cha} = ted.ins
+        @buf = @buf.slice(0,at) + cha + @buf.slice(at)
+      else throw "%sole-edit -lost.#{str ted}"
+  #
+  transmute: (sin,dex)->
+    $this = `this`
+    switch
+      when sin == 'nop' or dex == 'nop' then dex
+      when sin.reduce
+        sin.reduce ((dex,syn) -> $this.transmute(syn,dex)), dex
+      when dex.map then dex.map (dax) -> $this.transmute(sin,dax)
+      when dex.set != undefined then dex
+      else switch Object.keys(sin)[0]
+        when 'set' then 'nop'
+        when 'del'
+          if sin.del is dex.del then return 'nop'
+          dex = $.extend true, {}, dex  # clone
+          switch Object.keys(dex)[0]
+            when 'del' then if sin.del < dex.del    then dex.del--
+            when 'ins' then if sin.del < dex.ins.at then dex.ins.at--
+          return dex
+        when 'ins'
+          dex = $.extend true, {}, dex  # clone
+          {at,cha} = sin.ins
+          switch Object.keys(dex)[0]
+            when 'del' then if at < dex.del then dex.del++
+            when 'ins' then if at < dex.ins.at or
+                              (at == dex.ins.at and cha < dex.ins.cha)
+                dex.ins.at++
+          return dex
+        else throw "%sole-edit -lost.#{str sin}"
+  #
+  commit: (ted)->
+    @ven[0]++
+    @leg.push ted
+    @apply ted
+    return @abet()
+  #
+  inverse: (ted)->
+    switch true
+      when 'nop' == ted then ted
+      when undefined != ted.map
+        ted.map( (tad)-> res=@inverse(tad); @apply(tad); res).reverse()
+      when undefined != ted.set then set: @buf
+      when undefined != ted.ins then del: ted.ins
+      when undefined != ted.del then ins: at: ted.del, cha: @buf[ted.del]
+      else throw 'bad sole-edit'
+  #
+  receive: ({ler,ted})->
+    if !(ler[1] is @ven[1]) 
+      throw "-out-of-sync.[#{str ler} #{str @ven}]"
+    @leg = @leg[0 ... (@ven[0] - ler[0])]
+    dat = @transmute @leg, ted
+    @ven[1]++; @apply dat; dat
+  #
+  remit: ()-> throw 'stub'
+  transmit: (ted)->
+    @commit ted
+    {ted, ler:[@ven[1], @ven[0]]}
+  #
+  transceive: ({ler,ted})->
+    old = new Share @buf
+    dat = @receive {ler, ted}
+    old.inverse dat
+  #
+  transpose: (pos)-> (@transmute @leg, ins: at: pos).ins.at