Display custom node in ConstModule

Also wrote a short introductory node explaining node permissions.
This commit is contained in:
Joscha 2020-02-11 11:43:25 +00:00
parent 29e19ec1b2
commit 4c24430c07
5 changed files with 66 additions and 66 deletions

View file

@ -192,9 +192,9 @@ receiveUpdates eventChan node conn = handle (sendCloseEvent eventChan) $ do
packet <- receivePacket conn packet <- receivePacket conn
case packet of case packet of
ServerUpdate path subnode -> do ServerUpdate path subnode -> do
let newNode = replaceAt subnode path node let node' = replaceAt subnode path node
writeBChan eventChan $ EventNode newNode writeBChan eventChan $ EventNode node'
receiveUpdates eventChan newNode conn -- Aaand close the loop :D receiveUpdates eventChan node' conn -- Aaand close the loop :D
_ -> closeWithErrorMessage conn "Invalid packet: Expected update" _ -> closeWithErrorMessage conn "Invalid packet: Expected update"
runCorrectClient :: ClientOptions -> WS.ClientApp a -> IO a runCorrectClient :: ClientOptions -> WS.ClientApp a -> IO a

View file

@ -19,4 +19,4 @@ options = WS.defaultServerOptions
main :: IO () main :: IO ()
main = do main = do
putStrLn "Starting server" putStrLn "Starting server"
WS.runServerWithOptions options $ serverApp pingDelay constModule WS.runServerWithOptions options $ serverApp pingDelay $ constModule projectDescriptionNode

View file

@ -1,12 +1,12 @@
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Forest.Node module Forest.Node
( (
-- * Node -- * Node
NodeId NodeId
, Node(..) , Node(..)
, newNode
, emptyNode , emptyNode
, hasChildren , hasChildren
, mapChildren , mapChildren
@ -20,8 +20,6 @@ module Forest.Node
, isValidPath , isValidPath
, narrowPath , narrowPath
, narrowSet , narrowSet
-- * Example values
, exampleNode
) where ) where
import Control.Monad import Control.Monad
@ -39,10 +37,10 @@ type NodeId = T.Text
data Node = Node data Node = Node
{ nodeText :: !T.Text { nodeText :: !T.Text
, nodeAct :: !Bool
, nodeEdit :: !Bool , nodeEdit :: !Bool
, nodeDelete :: !Bool , nodeDelete :: !Bool
, nodeReply :: !Bool , nodeReply :: !Bool
, nodeAct :: !Bool
, nodeChildren :: !(Map.Map NodeId Node) , nodeChildren :: !(Map.Map NodeId Node)
} deriving (Show, Generic) } deriving (Show, Generic)
@ -56,8 +54,17 @@ instance ToJSON Node where
instance FromJSON Node where instance FromJSON Node where
parseJSON = genericParseJSON nodeOptions parseJSON = genericParseJSON nodeOptions
emptyNode :: T.Text -> Bool -> Bool -> Bool -> Bool -> Node newNode :: String -> T.Text -> [Node] -> Node
emptyNode text edit delete reply act = Node text edit delete reply act Map.empty newNode flags text children =
let edit = 'e' `elem` flags
delete = 'd' `elem` flags
reply = 'r' `elem` flags
act = 'a' `elem` flags
pairedChildren = zip (map (T.pack . show) [(0::Integer)..]) children
in Node text edit delete reply act $ Map.fromList pairedChildren
emptyNode :: String -> T.Text -> Node
emptyNode flags text = newNode flags text []
hasChildren :: Node -> Bool hasChildren :: Node -> Bool
hasChildren = not . Map.null . nodeChildren hasChildren = not . Map.null . nodeChildren
@ -99,46 +106,3 @@ narrowPath _ _ = Nothing
narrowSet :: NodeId -> Set.Set Path -> Set.Set Path narrowSet :: NodeId -> Set.Set Path -> Set.Set Path
narrowSet x s = Set.fromList [Path ys | Path (y:ys) <- Set.toList s, x == y] narrowSet x s = Set.fromList [Path ys | Path (y:ys) <- Set.toList s, x == y]
{- For testing -}
exampleNode :: Node
exampleNode =
Node "forest" False False True True (Map.fromList
[("0", Node "CHANGELOG.md" True True False False (Map.fromList []))
, ("1", Node "LICENSE" False False False True (Map.fromList []))
, ("2", Node "README.md" False False False True (Map.fromList []))
, ("3", Node "Setup.hs" True True False False (Map.fromList []))
, ("4", Node "client" True False True False (Map.fromList
[("0", Node "Main.hs" False True True False (Map.fromList []))
]))
, ("5", Node "forest.cabal" True True True False (Map.fromList []))
, ("6", Node "gen_file_node.py" True False False True (Map.fromList []))
, ("7", Node "package.yaml" True False True False (Map.fromList []))
, ("8", Node "server" True True True False (Map.fromList
[("0", Node "Main.hs" False False True True (Map.fromList []))
]))
, ("9", Node "src" False False False True (Map.fromList
[("0", Node "Forest" False True True False (Map.fromList
[("0", Node "Api.hs" True True True False (Map.fromList []))
, ("1", Node "Broadcast.hs" False False False False (Map.fromList []))
, ("2", Node "Client" True True True False (Map.fromList
[("0", Node "Node.hs" True True True True (Map.fromList []))
, ("1", Node "NodeEditor.hs" True False False True (Map.fromList []))
, ("2", Node "ResourceName.hs" True False False False (Map.fromList []))
, ("3", Node "Tree.hs" False True True True (Map.fromList []))
, ("4", Node "WidgetTree.hs" True False True False (Map.fromList []))
]))
, ("3", Node "Node.hs" True False False False (Map.fromList []))
, ("4", Node "Server.hs" False False False False (Map.fromList []))
, ("5", Node "TreeModule" False True False True (Map.fromList
[("0", Node "ConstModule.hs" True False False False (Map.fromList []))
]))
, ("6", Node "TreeModule.hs" True True False False (Map.fromList []))
, ("7", Node "Util.hs" False True False True (Map.fromList []))
]))
, ("1", Node "Forest.hs" False True False False (Map.fromList []))
]))
, ("10", Node "stack.yaml" True False False True (Map.fromList []))
, ("11", Node "stack.yaml.lock" False False False True (Map.fromList []))
])

View file

@ -18,11 +18,11 @@ import Forest.Util
sendUpdatesThread :: WS.Connection -> Chan Node -> Node -> IO () sendUpdatesThread :: WS.Connection -> Chan Node -> Node -> IO ()
sendUpdatesThread conn nodeChan _ = do sendUpdatesThread conn nodeChan _ = do
newNode <- readChan nodeChan node' <- readChan nodeChan
-- TODO Don't send the whole node every time -- TODO Don't send the whole node every time
putStrLn $ "Sending full node update with " ++ show newNode putStrLn $ "Sending full node update with " ++ show node'
sendPacket conn $ ServerUpdate (Path []) newNode sendPacket conn $ ServerUpdate (Path []) node'
sendUpdatesThread conn nodeChan newNode sendUpdatesThread conn nodeChan node'
{- Main server application that receives and processes client packets -} {- Main server application that receives and processes client packets -}
@ -58,4 +58,4 @@ serverApp pingDelay constructor pendingConnection = do
constructor (writeChan chan) $ receivePackets conn constructor (writeChan chan) $ receivePackets conn
_ -> closeWithErrorMessage conn "Invalid packet: Expected a hello packet" _ -> closeWithErrorMessage conn "Invalid packet: Expected a hello packet"
where where
initialNode = emptyNode "Loading ..." False False False False initialNode = emptyNode "" "Loading ..."

View file

@ -2,11 +2,9 @@
module Forest.TreeModule.ConstModule module Forest.TreeModule.ConstModule
( constModule ( constModule
, projectDescriptionNode
) where ) where
import Control.Concurrent
import Control.Monad
import Forest.Node import Forest.Node
import Forest.TreeModule import Forest.TreeModule
@ -18,9 +16,47 @@ instance TreeModule ConstModule where
reply _ _ _ = pure () reply _ _ _ = pure ()
act _ _ = pure () act _ _ = pure ()
constModule :: ModuleConstructor ConstModule constModule :: Node -> ModuleConstructor ConstModule
constModule sendNode continue = do constModule node sendNode continue = do
void $ forkIO $ do sendNode node
threadDelay $ 1000 * 1000 -- One second
sendNode (emptyNode "Loaded ConstModule" True True True True)
continue ConstModule continue ConstModule
projectDescriptionNode :: Node
projectDescriptionNode =
newNode "" "Hello."
[ newNode "" "This project is an experiment in tree-based interaction." []
, newNode "" "Its basic unit is the node (you're looking at one right now)." []
, newNode "" "A node mostly contains text\nthat is not constrained\nto a\nsingle\nline." []
, newNode "" "In addition to that, a node can have any number of child nodes."
[ newNode "" "This node is an example child node." []
, newNode "" "Of course, children can have children too."
[ newNode "" "It's nodes all the way down."
[ newNode "" "Just kidding, it's turtles of course." []
]
]
]
, newNode "" "But that's not all there is to nodes." []
, newNode "" "Each node also has a set of four different permissions."
[ newNode "" "Those permissions describe how you can interact with a node (besides folding and unfolding it)." []
, newNode "" "Here are the four permissions, by name:"
[ newNode "e" "edit"
[ newNode "" "If a node has the 'edit' permission, its text can be edited." []
]
, newNode "d" "delete"
[ newNode "" "If a node has the 'delete' permission, it can be deleted." []
]
, newNode "r" "reply"
[ newNode "" "If a node has the 'reply' permission, a child node with custom text can be created." []
]
, newNode "a" "act"
[ newNode "" "If a node has the 'act' permission, a node-specific action can be performed with it." []
]
, newNode "" "The above nodes have their respective permission set, but the server will ignore any actions." []
, newNode "" "Feel free to try out all the permissions, but don't be surprised if you try to delete a node and nothing happens." []
]
, newNode "" "Of course, a single node can have any combination of permissions."
[ newNode "er" "For example, this node has both the 'edit' and 'reply' permissions." []
, newNode "eda" "And this node has all permissions except the 'reply' permission." []
]
]
]