Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Commit

Permalink
refactor: moved the State of the Editor component in a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
prescientmoon committed Apr 21, 2020
1 parent b4c0bc9 commit ea93387
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 103 deletions.
116 changes: 13 additions & 103 deletions src/Component/Editor.purs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Lunarbox.Component.Editor (component, State, Action(..), Query, Tab) where
module Lunarbox.Component.Editor (component, Action(..), Query) where

import Prelude
import Control.Monad.Reader (class MonadReader)
Expand All @@ -8,18 +8,14 @@ import Data.Array (foldr, (..))
import Data.Default (def)
import Data.Either (Either(..))
import Data.Foldable (for_, sequence_)
import Data.Lens (Lens', Traversal', _Just, over, preview, set, view)
import Data.Lens.At (at)
import Data.Lens.Record (prop)
import Data.Lens (over, preview, set, view)
import Data.List.Lazy as List
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Set as Set
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..), uncurry)
import Data.Unfoldable (replicate)
import Debug.Trace (trace)
import Effect.Class (class MonadEffect)
import Halogen (ClassName(..), Component, HalogenM, Slot, defaultEval, mkComponent, mkEval, query, tell)
import Halogen.HTML as HH
Expand All @@ -35,107 +31,22 @@ import Lunarbox.Config (Config)
import Lunarbox.Control.Monad.Dataflow.Solve.SolveExpression (printTypeMap, solveExpression)
import Lunarbox.Control.Monad.Effect (print, printString)
import Lunarbox.Data.Dataflow.Class.Expressible (nullExpr)
import Lunarbox.Data.Dataflow.Expression (Expression)
import Lunarbox.Data.Dataflow.Native.Prelude (loadPrelude)
import Lunarbox.Data.Dataflow.Type (Type, numberOfInputs)
import Lunarbox.Data.Editor.DataflowFunction (DataflowFunction)
import Lunarbox.Data.Dataflow.Type (numberOfInputs)
import Lunarbox.Data.Editor.ExtendedLocation (ExtendedLocation(..))
import Lunarbox.Data.Editor.FunctionData (FunctionData)
import Lunarbox.Data.Editor.FunctionName (FunctionName(..))
import Lunarbox.Data.Editor.Location (Location)
import Lunarbox.Data.Editor.Node (Node(..))
import Lunarbox.Data.Editor.Node.NodeData (NodeData(..), _NodeDataPosition, _NodeDataSelected)
import Lunarbox.Data.Editor.Node.NodeDescriptor (onlyEditable)
import Lunarbox.Data.Editor.Node.NodeId (NodeId(..))
import Lunarbox.Data.Editor.Node.PinLocation (Pin(..))
import Lunarbox.Data.Editor.NodeGroup (NodeGroup)
import Lunarbox.Data.Editor.Project (Project, _ProjectFunctions, _atProjectFunction, _atProjectNode, _projectNodeGroup, compileProject, createFunction, emptyProject)
import Lunarbox.Data.Editor.Project (_projectNodeGroup, compileProject, createFunction, emptyProject)
import Lunarbox.Data.Editor.State (State, Tab(..), _atColorMap, _atNode, _atNodeData, _currentFunction, _currentTab, _function, _functions, _isSelected, _lastMousePosition, _nextId, _nodeData, _panelIsOpen, _project, _typeMap, tabIcon)
import Lunarbox.Data.Graph as G
import Lunarbox.Data.Vector (Vec2)
import Lunarbox.Page.Editor.EmptyEditor (emptyEditor)
import Lunarbox.Svg.Attributes (transparent)
import Record as Record
import Svg.Attributes (Color)

data Tab
= Settings
| Add
| Tree
| Problems

derive instance eqTab :: Eq Tab

tabIcon :: Tab -> String
tabIcon = case _ of
Settings -> "settings"
Add -> "add"
Tree -> "account_tree"
Problems -> "error"

type State
= { currentTab :: Tab
, panelIsOpen :: Boolean
, project :: Project
, nextId :: Int
, currentFunction :: Maybe FunctionName
, typeMap :: Map Location Type
, colorMap :: Map Location Color
, expression :: Expression Location
, lastMousePosition :: Maybe (Vec2 Number)
, nodeData :: Map (Tuple FunctionName NodeId) NodeData
, functionData :: Map FunctionName FunctionData
}

_nodeData :: Lens' State (Map (Tuple FunctionName NodeId) NodeData)
_nodeData = prop (SProxy :: _ "nodeData")

_atNodeData :: FunctionName -> NodeId -> Lens' State (Maybe NodeData)
_atNodeData name id = _nodeData <<< at (Tuple name id)

_project :: Lens' State Project
_project = prop (SProxy :: _ "project")

_colorMap :: Lens' State (Map Location Color)
_colorMap = prop (SProxy :: _ "colorMap")

_atColorMap :: Location -> Traversal' State (Maybe Color)
_atColorMap location = _colorMap <<< at location

_lastMousePosition :: Lens' State (Maybe (Vec2 Number))
_lastMousePosition = prop (SProxy :: _ "lastMousePosition")

_expression :: Lens' State (Expression Location)
_expression = prop (SProxy :: _ "expression")

_typeMap :: Lens' State (Map Location Type)
_typeMap = prop (SProxy :: _ "typeMap")

_nextId :: Lens' State Int
_nextId = prop (SProxy :: _ "nextId")

_StateProjectFunctions :: Lens' State (G.Graph FunctionName DataflowFunction)
_StateProjectFunctions = _project <<< _ProjectFunctions

_stateProjectNodeGroup :: FunctionName -> Traversal' State NodeGroup
_stateProjectNodeGroup name = _project <<< _projectNodeGroup name

_stateAtProjectNode :: FunctionName -> NodeId -> Traversal' State (Maybe Node)
_stateAtProjectNode name id = _project <<< _atProjectNode name id

_nodeIsSelected :: FunctionName -> NodeId -> Traversal' State Boolean
_nodeIsSelected name id = _atNodeData name id <<< _Just <<< _NodeDataSelected

_StateAtProjectFunction :: FunctionName -> Traversal' State (Maybe DataflowFunction)
_StateAtProjectFunction name = _project <<< _atProjectFunction name

_StateCurrentFunction :: Lens' State (Maybe FunctionName)
_StateCurrentFunction = prop (SProxy :: _ "currentFunction")

_panelIsOpen :: Lens' State Boolean
_panelIsOpen = prop (SProxy :: _ "panelIsOpen")

_currentTab :: Lens' State Tab
_currentTab = prop (SProxy :: _ "currentTab")

data Action
= ChangeTab Tab
Expand Down Expand Up @@ -208,8 +119,8 @@ component =
print "here:)"
Tuple id setId <- createId
typeMap <- gets $ view _typeMap
maybeCurrentFunction <- gets $ view _StateCurrentFunction
maybeNodeFunction <- gets $ preview $ _StateAtProjectFunction name
maybeCurrentFunction <- gets $ view _currentFunction
maybeNodeFunction <- gets $ preview $ _function name
for_ (join maybeNodeFunction) \function -> do
state <- get
let
Expand All @@ -234,12 +145,11 @@ component =
for_ maybeCurrentFunction
$ \currentFunction -> do
let
state'' = set (_stateAtProjectNode currentFunction id) (Just node) state'
state'' = set (_atNode currentFunction id) (Just node) state'

state''' = set (_atNodeData currentFunction id) (Just def) state''
void $ put $ setId state'''
handleAction Compile
trace (Map.lookup (Tuple currentFunction id) state'''.nodeData) \_ -> pure unit
ChangeTab newTab -> do
oldTab <- gets $ view _currentTab
modify_
Expand All @@ -256,8 +166,8 @@ component =
void $ query (SProxy :: _ "tree") unit $ tell TreeC.StartCreation
SelectFunction name -> do
-- we need the current function to lookup the function in the function graph
oldName <- gets $ view _StateCurrentFunction
functions <- gets $ view _StateProjectFunctions
oldName <- gets $ view _currentFunction
functions <- gets $ view _functions
-- this is here to update the function the Scene component renders
when (name /= oldName)
$ sequence_ do
Expand All @@ -267,7 +177,7 @@ component =
pure do
handleAction Compile
-- And finally, save the selected function in the state
modify_ $ set _StateCurrentFunction name
modify_ $ set _currentFunction name
SceneMouseDown position -> do
modify_ $ set _lastMousePosition $ Just position
SceneMouseMove position -> do
Expand All @@ -289,9 +199,9 @@ component =
SceneMouseUp -> do
modify_ $ over _nodeData $ map $ set _NodeDataSelected false
SelectNode id -> do
maybeCurrentFunction <- gets $ view _StateCurrentFunction
maybeCurrentFunction <- gets $ view _currentFunction
for_ maybeCurrentFunction \currentFunction -> do
modify_ $ set (_nodeIsSelected currentFunction id) true
modify_ $ set (_isSelected currentFunction id) true

handleTreeOutput :: TreeC.Output -> Maybe Action
handleTreeOutput = case _ of
Expand Down
129 changes: 129 additions & 0 deletions src/Data/Editor/State.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
module Lunarbox.Data.Editor.State
( State
, Tab(..)
, tabIcon
, _nodeData
, _atNodeData
, _project
, _colorMap
, _atColorMap
, _lastMousePosition
, _expression
, _typeMap
, _nextId
, _function
, _functions
, _nodeGroup
, _atNode
, _isSelected
, _panelIsOpen
, _currentFunction
, _currentTab
) where

import Prelude
import Data.Lens (Lens', Traversal', _Just)
import Data.Lens.At (at)
import Data.Lens.Record (prop)
import Data.Map (Map)
import Data.Maybe (Maybe)
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..))
import Lunarbox.Data.Dataflow.Expression (Expression)
import Lunarbox.Data.Dataflow.Type (Type)
import Lunarbox.Data.Editor.DataflowFunction (DataflowFunction)
import Lunarbox.Data.Editor.FunctionData (FunctionData)
import Lunarbox.Data.Editor.FunctionName (FunctionName)
import Lunarbox.Data.Editor.Location (Location)
import Lunarbox.Data.Editor.Node (Node)
import Lunarbox.Data.Editor.Node.NodeData (NodeData, _NodeDataSelected)
import Lunarbox.Data.Editor.Node.NodeId (NodeId)
import Lunarbox.Data.Editor.NodeGroup (NodeGroup)
import Lunarbox.Data.Editor.Project (Project, _ProjectFunctions, _atProjectFunction, _atProjectNode, _projectNodeGroup)
import Lunarbox.Data.Graph as G
import Lunarbox.Data.Vector (Vec2)
import Svg.Attributes (Color)

data Tab
= Settings
| Add
| Tree
| Problems

derive instance eqTab :: Eq Tab

-- Return the icon for a Tab
-- I could use a show instance
-- but this is more explicit I think
tabIcon :: Tab -> String
tabIcon = case _ of
Settings -> "settings"
Add -> "add"
Tree -> "account_tree"
Problems -> "error"

type State
= { currentTab :: Tab
, panelIsOpen :: Boolean
, project :: Project
, nextId :: Int
, currentFunction :: Maybe FunctionName
, typeMap :: Map Location Type
, colorMap :: Map Location Color
, expression :: Expression Location
, lastMousePosition :: Maybe (Vec2 Number)
, nodeData :: Map (Tuple FunctionName NodeId) NodeData
, functionData :: Map FunctionName FunctionData
}

-- Lenses
_nodeData :: Lens' State (Map (Tuple FunctionName NodeId) NodeData)
_nodeData = prop (SProxy :: _ "nodeData")

_atNodeData :: FunctionName -> NodeId -> Lens' State (Maybe NodeData)
_atNodeData name id = _nodeData <<< at (Tuple name id)

_project :: Lens' State Project
_project = prop (SProxy :: _ "project")

_colorMap :: Lens' State (Map Location Color)
_colorMap = prop (SProxy :: _ "colorMap")

_atColorMap :: Location -> Traversal' State (Maybe Color)
_atColorMap location = _colorMap <<< at location

_lastMousePosition :: Lens' State (Maybe (Vec2 Number))
_lastMousePosition = prop (SProxy :: _ "lastMousePosition")

_expression :: Lens' State (Expression Location)
_expression = prop (SProxy :: _ "expression")

_typeMap :: Lens' State (Map Location Type)
_typeMap = prop (SProxy :: _ "typeMap")

_nextId :: Lens' State Int
_nextId = prop (SProxy :: _ "nextId")

_functions :: Lens' State (G.Graph FunctionName DataflowFunction)
_functions = _project <<< _ProjectFunctions

_nodeGroup :: FunctionName -> Traversal' State NodeGroup
_nodeGroup name = _project <<< _projectNodeGroup name

_atNode :: FunctionName -> NodeId -> Traversal' State (Maybe Node)
_atNode name id = _project <<< _atProjectNode name id

_isSelected :: FunctionName -> NodeId -> Traversal' State Boolean
_isSelected name id = _atNodeData name id <<< _Just <<< _NodeDataSelected

_function :: FunctionName -> Traversal' State (Maybe DataflowFunction)
_function name = _project <<< _atProjectFunction name

_currentFunction :: Lens' State (Maybe FunctionName)
_currentFunction = prop (SProxy :: _ "currentFunction")

_panelIsOpen :: Lens' State Boolean
_panelIsOpen = prop (SProxy :: _ "panelIsOpen")

_currentTab :: Lens' State Tab
_currentTab = prop (SProxy :: _ "currentTab")

0 comments on commit ea93387

Please sign in to comment.