When a component is incorporated in a system it becomes an Actor. The actor module implements the connections to the other components in the system. In practice that means mapping and sending the component's out messages to other actors in the system.
Here is an example of wrapping a login form component to an actor in a system.
This is the global model for the System:
module AppModel exposing (..)
type AppModel
= LoginFormModel LoginForm.Model
| OtherComponent ...
This is the global appMsg type for the System:
module AppMsg exposing (..)
type AppMsg
= FormMsg LoginForm.MsgIn
| AuthServiceMsg AuthService.MsgIn
| OtherComponent ...
This is the login form actor:
module Actor.LoginForm exposing (..)
import Webbhuset.ActorSystem as System
import Webbhuset.Actor as Actor exposing (Actor)
import Component.LoginForm as LoginForm
import Component.AuthService as AuthService
import AppMsg exposing (AppMsg)
import AppModel exposing (AppModel)
actor : Actor LoginForm.Model AppModel AppMsg
actor =
Actor.fromUI
{ wrapModel = AppModel.LoginFormModel
, wrapMsg = AppMsg.FormMsg
, mapIn = mapFormIn
, mapOut = mapFormOut
}
LoginForm.component
mapFormIn : AppMsg -> Maybe LoginForm.MsgIn
mapFormIn appMsg =
case appMsg of
AppMsg.FormMsg formMsg ->
Just formMsg
_ ->
Nothing
mapFormOut : PID -> LoginForm.MsgOut -> System.SysMsg name AppMsg
mapFormOut self formMsg =
case formMsg of
LoginForm.Submit user password ->
AuthService.Login user password self
|> AppMsg.AuthServiceMsg
|> System.toAppMsg
|> System.sendToSingleton AuthService
Webbhuset.PID.PID
A PID is an identifier for a Process.
fromUI : { wrapModel : compModel -> appModel, wrapMsg : msgIn -> appMsg, mapIn : appMsg -> Maybe msgIn, mapOut : PID -> msgOut -> SysMsg name appMsg } -> Webbhuset.Component.UI compModel msgIn msgOut -> Actor compModel appModel (SysMsg name appMsg)
Create an actor from a UI Component
fromService : { wrapModel : compModel -> appModel, wrapMsg : msgIn -> appMsg, mapIn : appMsg -> Maybe msgIn, mapOut : PID -> msgOut -> SysMsg name appMsg } -> Webbhuset.Component.Service compModel msgIn msgOut -> Actor compModel appModel (SysMsg name appMsg)
Create an actor from a Service Component
fromLayout : { wrapModel : compModel -> appModel, wrapMsg : msgIn -> appMsg, mapIn : appMsg -> Maybe msgIn, mapOut : PID -> msgOut -> SysMsg name appMsg } -> Webbhuset.Component.Layout compModel msgIn msgOut (SysMsg name appMsg) -> Actor compModel appModel (SysMsg name appMsg)
Create an actor from a Layout Component
You probably don't need this when you are using the actor model. These are useful if you need to create support for a different output type.
Webbhuset.ActorSystem.Actor compModel appModel (Html msg) msg
An actor is acomponent where the types are wrapped to fit the System types.
{ wrapModel : compModel -> appModel
, wrapMsg : msgIn -> appMsg
, mapIn : appMsg -> Maybe msgIn
, mapOut : PID -> msgOut -> SysMsg name appMsg
}
Args
wrapSystem : (msgIn -> appMsg) -> (Webbhuset.Component.SystemEvent.SystemEvent -> Webbhuset.Component.SystemEvent.Handling msgIn) -> Webbhuset.Component.SystemEvent.SystemEvent -> PID -> Webbhuset.Component.SystemEvent.Handling (SysMsg name appMsg)
Convert a component onSystem
field to an actor onSystem
field
wrapSub : (msgIn -> appMsg) -> (compModel -> Platform.Sub.Sub msgIn) -> compModel -> PID -> Platform.Sub.Sub (SysMsg name appMsg)
Convert a component subs
field to an actor subs
field
wrapInit : Args name compModel appModel msgIn msgOut appMsg -> (PID -> ( compModel, List msgOut, Platform.Cmd.Cmd msgIn )) -> PID -> ( appModel, SysMsg name appMsg )
Convert a component init
field to an actor init
field
wrapUpdate : Args name compModel appModel msgIn msgOut msg -> (msgIn -> compModel -> ( compModel, List msgOut, Platform.Cmd.Cmd msgIn )) -> compModel -> SysMsg name msg -> PID -> ( appModel, SysMsg name msg )
Convert a component update
field to an actor update
field
sendTo : (msgIn -> appMsg) -> PID -> msgIn -> SysMsg name appMsg
Send to pid.