gale client

root / Status.hs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{-# LANGUAGE OverlappingInstances #-}

module Status(
    set,
    setS,
    clear,
    Status.get,
    setF,
    setFS,
    getStatus,
    Status.log,
    getLog
    ) where


import Data.Char(chr)
import CircularBuffer as CB
import Data.IORef
import Data.Tree
import Doc.Chars
import GenUtil
import Data.List(intersperse,groupBy)
import qualified Data.Map as Map
import System.IO.Unsafe


{-# NOINLINE status_var #-}
status_var :: IORef (Map.Map String (IO String))
status_var  = unsafePerformIO $ newIORef Map.empty

{-# NOINLINE log_var #-}
log_var :: CB.CircularBuffer String
log_var = unsafePerformIO $ CB.new 10

log :: String -> IO ()
log s = CB.append log_var [s]

getLog :: IO [String]
getLog = CB.toList log_var



modify r f = atomicModifyIORef r (\x -> (f x,()))

setS :: Show a => String -> a -> IO ()
setS w v = set w (show v)

set :: String -> String -> IO ()
set w v = modify status_var (\fm -> Map.insert w (return v) fm)

setF :: String -> IO String -> IO ()
setF w v = modify status_var (\fm -> Map.insert w v fm)

setFS :: Show a => String -> IO a -> IO ()
setFS w v = modify status_var (\fm -> Map.insert w (fmap show v) fm)


get :: String -> IO (IO String)
get k = do
    fm <- readIORef status_var
    case Map.lookup k fm of
        Just x -> return x
        Nothing -> return (return "")



clear :: String -> IO ()
clear k =  modify status_var (\fm -> Map.delete k fm)


getall = do
    fm <- readIORef status_var
    return $ Map.toList fm

getTree :: IO (Forest (String,String))
getTree = do
    xs <- getall
    let f (a,b) = do b <- b; return (split (== '.') a,b)
    xs <- mapM f xs
    return $ createForest  xs

createForest  xs = map f gs where
    --[Node (concat $ intersperse "." (xs),y) [] | (xs,y) <- xs]
    f [(xs,ys)] =  Node (concat $ intersperse "." (xs),ys) []
    f xs@((x:_,_):_) = Node (x,"") (createForest [ (xs,ys) | (_:xs,ys)<- xs])
    f _ = error "createForest: should not happen."
    gs = groupBy (\(x:_,_) (y:_,_) -> x == y) xs
--createForest  xs = Node ("","") [ createTree [(xs,y)] | (xs,y) <- xs]

draw :: Tree String -> [String]
draw (Node x ts0) = x : drawSubTrees ts0
  where drawSubTrees [] = []
        drawSubTrees [t] =
                {-[vLine] :-} shift [chr 0x2570, chr 0x2574] "  " (draw t)
        drawSubTrees (t:ts) =
                {-[vLine] :-} shift (lTee ++ [chr 0x2574]) (vLine ++  " ") (draw t) ++ drawSubTrees ts

        shift first other = zipWith (++) (first : repeat other)
        --vLine = chr 0x254F

getStatus :: IO String
getStatus = do
    t <- getTree
    let f (xs,"") = xs
        f (xs,ys) = xs ++ ": "  ++ ys
    return $ unlines (concatMap (draw . fmap f) t)