рдпрд╣ рд╕рдм рдХреНрдпрд╛ рд╣реИ?
рдпрд╣ рд╕рдм рд╕рд╛рдВрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред рд╣рд░ рдХреЛрдИ рдпрд╛рдж рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕рд╛рдВрдк рдХреНрдпрд╛ рд╣реИ: рдПрдХ рдЖрдпрддрд╛рдХрд╛рд░ рдХреНрд╖реЗрддреНрд░ рдкрд░ рдПрдХ рд╕рд╛рдВрдк рдЪрд▓рддрд╛ рд╣реИред рднреЛрдЬрди рдкрд╛рддрд╛ рд╣реИ - рд▓рдВрдмрд╛рдИ рдореЗрдВ рдмрдврд╝рддрд╛ рд╣реИ, рдЦреБрдж рдХреЛ рдпрд╛ рдЦреЗрдд рдХреЗ рдХрд┐рдирд╛рд░реЗ рдХреЛ рдкрд╛рддрд╛ рд╣реИ - рдорд░ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗрд╡рд▓ рдХрдорд╛рдВрдб рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИ: рдмрд╛рдПрдВ, рджрд╛рдПрдВ, рдКрдкрд░, рдиреАрдЪреЗред
рдореИрдВрдиреЗ рдпрд╣рд╛рдБ рдХреБрдЫ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЬреЛрдбрд╝рдиреЗ рдФрд░ рд╕рд╛рдБрдк рдХреЛ рдкреИрдЦрд╛рдиреЗ рд╕реЗ рднрд╛рдЧрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдФрд░ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдкрд░ рдпрд╣ рд╕рдм!
рдЗрд╕рд▓рд┐рдП, рдЖрдЬ рдореИрдВ рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ MailboxProcessor
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдореЙрдбрд▓ рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдВрдк рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЬреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд┐рдВрджреБ рд╣реИрдВ, рдФрд░ рдЖрдк рдХреНрдпрд╛ рдЙрдореНрдореАрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣рд╛рдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдХреЛрдб рд╕рд╣реА рдирд╣реАрдВ рд╣реИ, рдХреБрдЫ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдмреЗрд╣рддрд░ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рд╢реБрд░реБрдЖрддреА рд╣реИрдВ рдФрд░ рдореЗрд▓рдмреЙрдХреНрд╕ рд╕реЗ рдирд┐рдкрдЯрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк рдореЗрд░реЗ рдмрд┐рдирд╛ рдореЗрд▓рдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдм рдХреБрдЫ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдпрд╣рд╛рдБ рдмреЛрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрднрд┐рдиреЗрддрд╛ рдХреНрдпреЛрдВ?
рдЕрднреНрдпрд╛рд╕ рдХреЗ рд▓рд┐рдПред рдореИрдВрдиреЗ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЗ рдореЙрдбрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рд╛, рд╡реАрдбрд┐рдпреЛ рджреЗрдЦрд╛, рдореБрдЭреЗ рд╕рдм рдХреБрдЫ рдкрд╕рдВрдж рдЖрдпрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЦреБрдж рдЗрд╕реЗ рдЖрдЬрдорд╛рдпрд╛ рдирд╣реАрдВред рдЕрдм рдореИрдВрдиреЗ рдЗрд╕реЗ рдЖрдЬрдорд╛рдпрд╛ред
рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореИрдВрдиреЗ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рдХреЗ рд▓рд┐рдП рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рдХреЛ рдЪреБрдирд╛, рдЕрд╡рдзрд╛рд░рдгрд╛ рдмрд╣реБрдд рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЗрд╕ рдХрд╛рд░реНрдп рдкрд░ рдЧрд┐рд░ рдЧрдИред
рдХреНрдпреЛрдВ MailboxProcessor, рдФрд░ рдирд╣реАрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Akka.net?
рдореЗрд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП, MailboxProcessor
рдЧреМрд░реИрдпрд╛ рджреНрд╡рд╛рд░рд╛ рдХрдХреНрд╖реАрдп рд╕реНрдЯреЗрд╢рди рд╕реЗ рд╣реИ, MailboxProcessor
рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдФрд░ рдпрд╣ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рдкреИрдХреЗрдЬ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдореЗрд▓рдмреЙрдХреНрд╕ рдкреНрд░реЛрд╕реЗрд╕рд░ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдмрд╛рдд рд╕рд░рд▓ рд╣реИред рдореЗрд▓рдмреЙрдХреНрд╕ рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╕рдВрджреЗрд╢ рд▓реВрдк рдФрд░ рдХреБрдЫ рд╕реНрдерд┐рддрд┐ рд╣реИред рдЖрдкрдХрд╛ рд╕рдВрджреЗрд╢ рд▓реВрдк рдЖрдиреЗ рд╡рд╛рд▓реЗ рдирдП рд╕рдВрджреЗрд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛ред
let actor = MailboxProcessor.Start(fun inbox -> // , // . inbox -- MailboxProcessor let rec messageLoop oldState = async { // let! msg = inbox.Receive()
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ messageLoop
рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╣реИ, рдФрд░ рдЕрдВрдд рдореЗрдВ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рдХреЗрд╡рд▓ рдПрдХ рд╕рдВрджреЗрд╢ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдпрд╣ рдЕрднрд┐рдиреЗрддрд╛ рдорд░ рдЬрд╛рдПрдЧрд╛ред messageLoop
рднреА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реИ, рдФрд░ рдЬрдм рдирдпрд╛ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдЬрд╛рддреА рд╣реИ: let! msg = inbox.Receive()
let! msg = inbox.Receive()
ред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рдВрдкреВрд░реНрдг рддрд╛рд░реНрдХрд┐рдХ рд▓реЛрдб updateState
рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдореЗрд▓рдмреЙрдХреНрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдирд┐рд░реНрдорд╛рддрд╛ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рд╕реНрдЯреЗрдЯ рдЕрдкрдбреЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдПрдХ рд╢реВрдиреНрдп рд╕реНрдерд┐рддрд┐ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ:
// applyMessage // (fun inbox -> ...) let buildActor applyMessage zeroState = MailboxProcessor.Start(fun inbox -> let rec loop state = async{ let! msg = inbox.Receive() let newState = applyMessage state msg return! loop newState } loop zeroState )
рдХреВрд▓! рдЕрдм рд╣рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рддрд╛рдХрд┐ return! loop newState
рди рднреВрд▓реЗрдВ return! loop newState
return! loop newState
ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рдПрдХ рд░рд╛рдЬреНрдп рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕ рд░рд╛рдЬреНрдп рдХреЛ рдмрд╛рд╣рд░ рд╕реЗ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдореЗрд▓рдмреЙрдХреНрд╕ рдореЗрдВ рдПрдХ PostAndReply
рд╡рд┐рдзрд┐ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдПрдХ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ AsyncReplyChannel<'Reply> -> 'Msg
рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реЗ рдЬрд╛рддреА рд╣реИред рдкрд╣рд▓реЗ рддреЛ рдЗрд╕рдиреЗ рдореБрдЭреЗ рд╕реНрддреВрдк рдореЗрдВ рд▓реЗ рдЬрд╛рдпрд╛ - рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рд░реНрдп рдХрд╣рд╛рдВ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реЛ рдЧрдпрд╛: рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдбреАрдпреВ рдХреЗ рдЖрд╡рд░рдг рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдЕрднрд┐рдиреЗрддрд╛ рдкрд░ 2 рдСрдкрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВ: рд╕рдВрджреЗрд╢ рд╕реНрд╡рдпрдВ рднреЗрдЬреЗрдВ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдкреВрдЫреЗрдВред рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
// . // Mail<_,_> , Post & Get -- . // F# , // compare & equals . // -- . // [<Struct>] . type Mail<'msg, 'state> = | Post of 'msg | Get of AsyncReplyChannel<'state>
рд╣рдорд╛рд░рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд╛рд░реНрдп рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
let buildActor applyMessage zeroState = MailboxProcessor.Start(fun inbox -> let rec loop state = async{ let! msg = inbox.Receive() // , // . -- , // . // -- // . ! match msg with | Post msg -> let newState = applyMessage state msg return! loop newState | Get channel -> channel.Reply state return! loop state } loop zeroState )
рдЕрдм, рдореЗрд▓рдмреЙрдХреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕ Mail.Post
рдореЗрдВ рдЕрдкрдиреЗ рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рд░ рдмрд╛рд░ рдЗрд╕реЗ рди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдЫреЛрдЯреЗ рдРрдк рдореЗрдВ рд▓рдкреЗрдЯрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ:
module Mailbox = let buildAgent applyMessage zeroState = MailboxProcessor.Start(fun inbox -> let rec loop state = async{ let! msg = inbox.Receive() match msg with | Post msg -> let newState = applyMessage state msg return! loop newState | Get channel -> channel.Reply state return! loop state } loop zeroState ) let post (agent: MailboxProcessor<_>) msg = Post msg |> agent.Post let getState (agent: MailboxProcessor<_>) = agent.PostAndReply Get let getStateAsync (agent: MailboxProcessor<_>) = agent.PostAndAsyncReply Get // Single Case Discriminated Union. // MailboxProcessor API. , // - , , // . , // . type MailAgent<'msg, 'state> = MailAgent of address:string * mailbox:MailboxProcessor<Mail<'msg, 'state>> // API with member this.Post msg = // let (MailAgent (address,this)) = this Mailbox.post this msg member this.GetState() = let (MailAgent (address,this)) = this Mailbox.getState this member this.GetStateAsync() = let (MailAgent (address,this)) = this Mailbox.getStateAsync this member this.Address = let (MailAgent (address, _)) = this address member this.Dispose() = let (MailAgent (_, this)) = this (this:>IDisposable).Dispose() interface IDisposable with member this.Dispose() = this.Dispose()
рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ address:string
рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рддреИрдпрд╛рд░ рд╣реИред
рджрд░рдЕрд╕рд▓, рд╕рд╛рдВрдк
рд╕рд╛рдВрдк рдореЗрдВ рдПрдХ рд╕рд╛рдВрдк рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛, рдПрдХ рдХреНрд╖реЗрддреНрд░ рдФрд░ рдЕрдЧрд▓реЗ рдлреНрд░реЗрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдорд┐рдд рд╕рдВрдХреНрд░рдордг рд╣реЛрддрд╛ рд╣реИред
рдпрд╣рд╛рдВ рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдореБрд╕реНрдХреБрд░рд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред
рдореЗрд░рд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд▓реЗрдЖрдЙрдЯ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдерд╛:
- рдПрдХ рдЯрд╛рдЗрдорд░ рдХреЗ рд╕рд╛рде рдЕрднрд┐рдиреЗрддрд╛ред рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рд╛рд░рдВрдн / рд░реЛрдХ / рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ n рдорд┐рд▓реАрд╕реЗрдХрдВрдб,
Flush
рдПрдХреНрдЯрд░ рдХреЛ рдПрдХ Flush
рд╕рдВрджреЗрд╢ рднреЗрдЬрддрд╛ рд╣реИред рднрдВрдбрд╛рд░ рдкреНрд░рдгрд╛рд▓реАред рдПрдХ рд░рд╛рдЬреНрдп рдХреЗ рд░реВрдк рдореЗрдВ - рдЕрднрд┐рдиреЗрддрд╛ рджрд▓ред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
Move Up/Down/Left/Right
, AddPerk Speed/Attack
(рд╣рд╛рдВ, рдореЗрд░рд╛ рд╕рд╛рдВрдк рдЬрд▓реНрджреА рд╕реЗ рдХреНрд░реЙрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЦрд▓рдирд╛рдпрдХ рдкрд░ рд╣рдорд▓рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ) рдФрд░ рдЯрд╛рдЗрдорд░ рд╕реЗ Flush
ред рдпрд╣ рдПрдХ рд░рд╛рдЬреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЖрджреЗрд╢реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдлреНрд▓рд╢ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕реВрдЪреА рд░реАрд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред - рдЕрднрд┐рдиреЗрддрд╛ рдПрдХ рд╕рд╛рдВрдк рд╣реИред рдпрд╣ рд╕рд╛рдВрдк рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ - рднрддреНрддреЛрдВ, рд▓рдВрдмрд╛рдИ, рджрд┐рд╢рд╛, рдЭреБрдХрддрд╛ рд╣реИ рдФрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХред
рдпрд╣ рдХрдорд╛рдВрдбреНрд╕ рдХреЗ рдЕрднрд┐рдиреЗрддрд╛ рдХреА рд╕реВрдЪреА, Tick
рд╕рдВрджреЗрд╢ (рд╕рд╛рдВрдк рдХреЛ 1 рд╕реЗрд▓ рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП) рдФрд░ GrowUp
рдХреЗ рдорд┐рд▓рдиреЗ рдкрд░ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рдЙрддреНрдкрд╛рдж рд╕реЗ рд╕рдВрджреЗрд╢ рдХреЛ GrowUp
рдХрд░рддрд╛ рд╣реИред - рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЕрднрд┐рдиреЗрддрд╛ред рдпрд╣ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХрд╛ рдПрдХ рдирдХреНрд╢рд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдПрдХ рд╕рдВрджреЗрд╢ рдореЗрдВ рд╕рд╛рдВрдк рдХреА рд╕реНрдерд┐рддрд┐ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдореМрдЬреВрджрд╛ рддрд╕реНрд╡реАрд░ рдкрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЦреАрдВрдЪрддрд╛ рд╣реИред рдпрд╣
GrowUp
рд╕реНрдиреЗрдХ рдЕрднрд┐рдиреЗрддрд╛ рдФрд░ Stop
рдХрдорд╛рдВрдб рдХреЛ рдЯрд╛рдЗрдорд░ рднреА рднреЗрдЬрддрд╛ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЗрддрдиреА рдХрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЗ рд╕рд╛рде, рд╕рдВрджреЗрд╢ рдорд╛рдирдЪрд┐рддреНрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧреИрд░-рддреБрдЪреНрдЫ рд╣реИред рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рдЙрддреНрдкрдиреНрди рд╣реБрдИрдВ: рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрдл # рдЪрдХреНрд░реАрдп рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдХреЛрдб рдХреА рд╡рд░реНрддрдорд╛рди рдкрдВрдХреНрддрд┐ рдореЗрдВ, рдЖрдк рдХреЗрд╡рд▓ рдКрдкрд░ рд▓рд┐рдЦреЗ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдлрд╛рдЗрд▓реЛрдВ рдкрд░ рднреА рдпрд╣реА рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдмрдЧ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдЗрд╕реЗ рдмрд╣реБрдд рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреЛрдб рдХреЛ рд╕рд╛рдл рд░рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдбрд┐рдЬрд╛рдЗрди рджреНрд╡рд╛рд░рд╛ рдЪрдХреНрд░реАрдп рд▓рд┐рдВрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рддреЛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдмреЗрд╢рдХ, рдЖрдк rec namespace
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдФрд░ рдлрд┐рд░ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрджрд░ рдЖрдк рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореМрдЬреВрдж рд╣рд░ рдЪреАрдЬ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдореИрдВрдиреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред
рдХреЛрдб рдЧрдбрд╝рдмрдбрд╝ рдХрд░рдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИ, рд▓реЗрдХрд┐рди рддрдм рдпрд╣ рдПрдХрдорд╛рддреНрд░ рд╡рд┐рдХрд▓реНрдк рдХреА рддрд░рд╣ рд▓рдЧ рд░рд╣рд╛ рдерд╛ред рдФрд░ рдЗрд╕рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ред
рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреА рд╕рдорд╕реНрдпрд╛
рдЬрдм рддрдХ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рдкреВрд░реА рдкреНрд░рдгрд╛рд▓реА рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рд╕реЗ рдЕрд▓рдЧ рд╣реЛ рдЬрд╛рддреА рдереА, рддрдм рддрдХ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рдерд╛, рдФрд░ рдореИрдВрдиреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдХреЗрд╡рд▓ рдбрд┐рдмреЗрдЯ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ред рдЬрдм updateUI
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рдЖрдпрд╛, рдЬрд┐рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЯрд┐рдХ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдерд╛, рддреЛ рдореИрдВ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред рди рддреЛ рдмрджрд╕реВрд░рдд рдФрд░ рди рд╣реА рд╕реБрдВрджрд░ - рдХреЛрдИ рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВред рдФрд░ рдлрд┐рд░ рдореБрдЭреЗ рдЕрдХреНрдХреВ рдХреА рдпрд╛рдж рдЖрдИ - рдЖрдЦрд┐рд░рдХрд╛рд░, рдЖрдк рд░рд╛рд╕реНрддреЗ рдореЗрдВ рд╣реА рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдкреИрджрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдореЗрд░реЗ рдкрд╛рд╕ рдореЗрд░реЗ рд╕рднреА рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХрд╛ рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рд╡рд░реНрдгрди рд╣реИред
рд╕рдорд╛рдзрд╛рди рд╕реНрдкрд╖реНрдЯ рд╣реИ - akku рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ! рдирд╣реАрдВ, рдмреЗрд╢рдХ, рдЕрдХреНрдХрд╛ рдЕрднреА рднреА рдУрд╡рд░рдХрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рд╡рд╣рд╛рдВ рд╕реЗ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЪрд╛рдЯрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ - рдЕрд░реНрдерд╛рддреН, рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдирдП рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрддреЗ рдкрд░ рдореМрдЬреВрджрд╛ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЪреВрдВрдХрд┐ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рдЕрдм рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реАрдзреЗ рд▓рд┐рдВрдХ рдХреЗ рдмрдЬрд╛рдп рдкрддреЗ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдПрдХ рдкрд░рд┐рджреГрд╢реНрдп рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд╣рд╛рдВ рдкрддрд╛ рдХрд╣реАрдВ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдЕрднрд┐рдиреЗрддрд╛ рд╡рд╣рд╛рдВ рдирд╣реАрдВ рд╣реИред рдЙрд╕реА acca рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдореГрдд рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреЙрдХреНрд╕ рдЬреЛрдбрд╝рд╛, рдФрд░ рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ DUs рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛:
// Agent<_,_> -- , , // , . // , -- Box (mailagent), // , , , , // Deadbox. MailAgent, . // . // -- . type Agent<'message,'state> = | Box of MailAgent<'message,'state> | DeadBox of string * MailAgent<string * obj, Map<string,obj list>> with member this.Post msg = match this with | Box box -> box.Post msg | DeadBox (address, deadbox) -> (address, box msg) |> deadbox.Post interface IDisposable with member this.Dispose() = match this with | Box agent -> agent.Dispose() | DeadBox (_,agent) -> agent.Dispose()
рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдЦреБрдж рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
// . -- . type MailboxNetwork() as this = // . ! [<DefaultValue>] val mutable agentRegister: ConcurrentDictionary<string, obj> // do this.agentRegister <- ConcurrentDictionary<string, obj>() // , // Map -- let deadLettersFn deadLetters (address:string, msg:obj) = printfn "Deadletter: %s-%A" address msg match Map.tryFind address deadLetters with // | None -> Map.add address [msg] deadLetters // -- | Some letters -> // -- Map.remove address deadLetters |> Map.add address (msg::letters) let deadLettersAgent() = ("deadLetters", Map.empty |> Mailbox.buildAgent deadLettersFn) |> MailAgent member this.DeadLetters = deadLettersAgent() // - , member this.Box<'message,'state>(address) = match this.agentRegister.TryGetValue address with | (true, agent) when (agent :? MailAgent<'message,'state>) -> // , , let agent = agent :?> MailAgent<'message, 'state> Box agent | _ -> DeadBox (address, this.DeadLetters) // -- member this.KillBox address = this.agentRegister.TryRemove(address) |> ignore member this.RespawnBox (agent: MailAgent<'a,'b>) = this.KillBox agent.Address this.agentRegister.TryAdd (agent.Address, agent) |> ignore interface IDisposable with member this.Dispose() = for agent in this.agentRegister.Values do match agent with | :? IDisposable as agent -> agent.Dispose() | _ -> ()
рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдПрдХ рд╣реА address:string
, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдКрдкрд░ рд▓рд┐рдЦрд╛ рдерд╛, рдХрд╛рдо рдЖрдпрд╛ред рдФрд░ рдлрд┐рд░ рд╕реЗ рдпрд╣ рдХрд╛рдо рдХрд┐рдпрд╛, рдмрд╛рд╣рд░реА рдирд┐рд░реНрднрд░рддрд╛ рдЕрдм рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рдерд╛ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛рд░реНрдпреЛрдВ рдиреЗ рдЕрдм рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд▓рд┐рдпрд╛ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдкрддреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП:
// - ( ) - let gameAgent (mailboxNetwork: MailboxNetwork) = mailboxNetwork.Box<Command list, GameState>(gameAddress) // message loop let commandAgentFn (mailboxNetwork: MailboxNetwork) commands msg = let gameAgent = gameAgent mailboxNetwork match msg with | Cmd cmd -> cmd::commands | Flush -> commands |> gameAgent.Post []
рдзреАрд░реЗ-рдзреАрд░реЗ
рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди, рдореИрдВрдиреЗ рдЧреЗрдо рдХреЛ рдХрдо рдЧрддрд┐ рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛: рдЯрд┐рдХ рдХреЗ рдмреАрдЪ рдХреА рджреЗрд░реА 500 рдорд┐рд▓реАрд╕реЗрдХрдВрдб рд╕реЗ рдЕрдзрд┐рдХ рдереАред рдпрджрд┐ рдЖрдкрдиреЗ рджреЗрд░реА рдХреЛ 200 рддрдХ рдХрдо рдХрд░ рджрд┐рдпрд╛, рддреЛ рд╕рдВрджреЗрд╢ рджреЗрд░ рд╕реЗ рдЖрдиреЗ рд▓рдЧреЗ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЯреАрдореЛрдВ рдиреЗ рджреЗрд░реА рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛, рдЬрд┐рд╕рдиреЗ рдкреВрд░рд╛ рдЦреЗрд▓ рдмрд┐рдЧрд╛рдбрд╝ рджрд┐рдпрд╛ред рдорд░рд╣рдо рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдордХреНрдЦреА рддрдереНрдп рдпрд╣ рдерд╛ рдХрд┐ рдЯрд╛рдЗрдорд░ рдХреЛ рдХрдИ рдмрд╛рд░ рдиреБрдХрд╕рд╛рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрдЯреЙрдк рдХрдорд╛рдВрдб рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реБрдЖ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдмрдЧ рдерд╛ред
рдЕрдкреНрд░рд┐рдп рд╕рддреНрдп рдпрд╣ рдерд╛ рдХрд┐ рдЕрднрд┐рдиреЗрддрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░реВрдк рд╕реЗ рдорд╣рд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд┐рдзрд┐ рдХреЙрд▓ рдмрд╣реБрдд рддреЗрдЬ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдХреЛрдб рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рд╛рдВрдк рдХреЛ рдПрдХ рдЕрд▓рдЧ рдЕрднрд┐рдиреЗрддрд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛, рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рдЧрддрд┐ рдХреЗ рдирд╛рдо рдкрд░ рдЫреЛрдбрд╝рдирд╛ рдкрдбрд╝рд╛, рдХреНрдпреЛрдВрдХрд┐ рдЦреЗрд▓ рдХреА 1 рдШрдбрд╝реА рдХреЗ рд▓рд┐рдП рд╕рдВрджреЗрд╢ рдмрд╣реБрдд рддреАрд╡реНрд░ рдерд╛:
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реАрдзреЗ рдХрдорд╛рдВрдб рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдПрдХ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рд╕рдВрдЦреНрдпрд╛ рднреЗрдЬрддрд╛ рд╣реИред
- рдЯрд╛рдЗрдорд░ рдЯреАрдо рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдПрдХ рдЯрд┐рдХ рднреЗрдЬрддрд╛ рд╣реИ рдФрд░, рдПрдХ рд╢реБрд░реБрдЖрддреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╕рд╛рдВрдк рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рднреА, рддрд╛рдХрд┐ рд╡рд╣ рд╕рд╛рдВрдк рдХреЛ рдЕрдЧрд▓реЗ рд╕реЗрд▓ рдореЗрдВ рд▓реЗ рдЬрд╛рдП
- рдХрдорд╛рдВрдб рдЕрднрд┐рдиреЗрддрд╛ рд╕рд╛рдВрдк рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рдХреА рдПрдХ рд╕реВрдЪреА рднреЗрдЬрддрд╛ рд╣реИ рдЬрдм рдЯрд╛рдЗрдорд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрджреЗрд╢ рдЖрддрд╛ рд╣реИред
- рд╕рд╛рдБрдк рдЕрднрд┐рдиреЗрддрд╛, 2 рдКрдкрд░реА рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ рдЕрджреНрдпрддрди рдХрд░рддрд╛ рд╣реИ, рд░рд╛рдЬреНрдп рдХреЛ рдХреНрд╖реЗрддреНрд░ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рдкрд╛рд╕ рднреЗрдЬрддрд╛ рд╣реИред
- рдХреНрд╖реЗрддреНрд░ рдЕрднрд┐рдиреЗрддрд╛ рд╕рдм рдХреБрдЫ redrawsред рдЕрдЧрд░ рд╕рд╛рдВрдк рдХреЛ рдЦрд╛рдирд╛ рдорд┐рд▓ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рд╕рд╛рдВрдк рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдПрдХ
GrowUp
рд╕рдВрджреЗрд╢ рднреЗрдЬрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╡рд╣ рдирдП рд░рд╛рдЬреНрдп рдХреЛ рдлрд╝реАрд▓реНрдб рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рднреЗрдЬ рджреЗрддрд╛ рд╣реИред
рдФрд░ рдЗрд╕ рд╕рдм рдХреЗ рд▓рд┐рдП 1 рдШрдбрд╝реА рдХрд╛ рдЪрдХреНрд░ рд╣реИ, рдЬреЛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, MailboxProcessor
рдХреЗ рдЖрдВрддреЛрдВ рдореЗрдВ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдЯрд╛рдЗрдорд░ рдЕрдЧрд▓реЗ рд╕рдВрджреЗрд╢ рдХреЛ рд╣рд░ n рдорд┐рд▓реАрд╕реЗрдХреЗрдВрдб рдкрд░ рднреЗрдЬрддрд╛ рд╣реИ, рдЪрд╛рд╣реЗ рдХреБрдЫ рднреА рд╣реЛ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рд╣рдо 1 рдмрд╛рд░ рдорд╛рдк рдореЗрдВ рдирд╣реАрдВ рдЖрдП, рддреЛ рд╕рдВрджреЗрд╢ рдЬрдорд╛ рд╣реЛрдиреЗ рд▓рдЧрддреЗ рд╣реИрдВ, рдФрд░ рд╕реНрдерд┐рддрд┐ рдмрд┐рдЧрдбрд╝ рдЬрд╛рддреА рд╣реИред рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдЙрдкрд╛рдп рдХреЛ "рд╕реНрдЯреНрд░реЗрдЪ" рдХрд░рдирд╛ рдЬреНрдпрд╛рджрд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛, рдЬреЛ рдХреБрдЫ рднреА рдЬрдорд╛ рд╣реБрдЖ рд╣реИ рдЙрд╕реЗ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░реЗрдВ рдФрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВред
рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╕рдВрджреЗрд╢ рдпреЛрдЬрдирд╛ рдХреЛ рд╕рд░рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬрдмрдХрд┐ рдХреЛрдб рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рдФрд░ рд╕реБрд▓рдн рдЫреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рд╣реА рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ - рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдмреЛрд▓рдирд╛, рдореИрдВ 1 рджреЗрд╡ рдЕрднрд┐рдиреЗрддрд╛ рдореЗрдВ рд╕рдм рдХреБрдЫ рдирд╣реАрдВ рдЫреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдФрд░ рдлрд┐рд░ рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдореЗрдВ рдмрд╣реБрдд рд╕рдордЭрджрд╛рд░реА рдирд╣реАрдВ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреА рдореЗрд░реА рд╕реВрдЪреА рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдкрд╣рд▓реЗ рдПрдХ рд╕рд╛рдБрдк рдЕрднрд┐рдиреЗрддрд╛ рдХрд╛ рдмрд▓рд┐рджрд╛рди рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИред рдПрдХ рдЯрд╛рдЗрдорд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд╕рдВрдЪрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрджреЗрд╢реЛрдВ рдХреЗ рдПрдХ рдмрдлрд░ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдкреНрд░рддрд┐ рдмреАрдЯ рдореЗрдВ рдбрд╛рд▓реЗрдВ, рдФрд░ рд╕рд╛рдВрдк рдХреЛ рдПрдХ рдЕрд▓рдЧ рдЕрднрд┐рдиреЗрддрд╛ рдореЗрдВ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЙрджреНрджреЗрд╢реНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдлреАрд▓реНрдб рдПрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рд░рдЦрдиреЗ рд╕реЗ рдмрд┐рдирд╛ рджреЗрд░реА рдХреЗ GrowUp
рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рд╕рд╛рдВрдк рдХреЗ рд▓рд┐рдП Tick
рд╕рдВрджреЗрд╢ рднреА рдмрд╣реБрдд рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рд╣рдореЗрдВ рдЯреАрдо рдЕрднрд┐рдиреЗрддрд╛ рд╕реЗ рд╕рдВрджреЗрд╢ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИ рдХрд┐ рдПрдХ рдирдпрд╛ рд╣рд░рд╛ рд╣реБрдЖ рд╣реИред рд╡рд┐рд▓рдВрдм рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдмреАрдЯ рдХреЗ рдЦрд┐рдВрдЪрд╛рд╡ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реБрдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрджрд▓рд╛рд╡ рд╣реИрдВ:
- рд╣рдо
Tick
рдФрд░ GrowUp
рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред - рд╣рдо рд╕рд╛рдБрдк рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ - рд╡рд╣ рдЕрдм рдЗрди рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ "рдЯреЗрдкрд▓рд╛" рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдЧрд╛ред
- рд╣рдо рдЯрд╛рдЗрдорд░ рдЕрднрд┐рдиреЗрддрд╛ рд╕реЗ
System.Timers.Timer
рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдХрд╛рд░реНрдп рдХреА рдпреЛрдЬрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧреА: Start
рдХрдорд╛рдВрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ Flush
рдХрдорд╛рдВрдб рдЕрднрд┐рдиреЗрддрд╛ Flush
рднреЗрдЬрддрд╛ рд╣реИред рд╡рд╣ рдлрд╝реАрд▓реНрдб + рд╕реНрдиреЗрдХ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдЖрджреЗрд╢реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рднреЗрдЬрддрд╛ рд╣реИ, рдЕрдВрддрд┐рдо рдЕрднрд┐рдиреЗрддрд╛ рдпрд╣ рд╕рдм рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЯрд╛рдЗрдорд░ рдХреЛ рдПрдХ Next
рд╕рдВрджреЗрд╢ рднреЗрдЬрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЙрд╕рд╕реЗ рдПрдХ рдирдИ рдЯрд┐рдХ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЯрд╛рдЗрдорд░, Next
рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдХреЗ Next
Thread.Sleep(delay)
рдЗрдВрддрдЬрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреВрд░реЗ рд╕рд░реНрдХрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИред
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рджреЗрдирд╛ред
- рдкрд┐рдЫрд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, 500 рдПрдордПрд╕ рдиреНрдпреВрдирддрдо рд╕реНрд╡реАрдХрд╛рд░реНрдп рджреЗрд░реА рдереАред рд╡рд░реНрддрдорд╛рди рджреЗрд░реА рдореЗрдВ, рдЖрдк рдЗрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ - рддреИрдпрд╛рд░ рд╣реЛрдиреЗ рдкрд░ рдлрд╝реАрд▓реНрдб рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдПрдХ рдирдП рдмреАрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдкрд┐рдЫрд▓реЗ рдЙрдкрд╛рдпреЛрдВ рд╕реЗ рдХрдЪреНрдЪреЗ рд╕рдВрджреЗрд╢ рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЕрдм рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред
- рдореИрд╕реЗрдЬрд┐рдВрдЧ рдореИрдк рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ - рдПрдХ рдЬрдЯрд┐рд▓ рдЧреНрд░рд╛рдл рдХреЗ рдмрдЬрд╛рдп, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд▓реВрдк рд╣реИред
- рдЗрд╕ рд╕рд░рд▓реАрдХрд░рдг рдиреЗ рдмрдЧ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрдм рдиреБрдХрд╕рд╛рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЯрд╛рдЗрдорд░ рдХреЛ рдХрдИ рдмрд╛рд░
Stop
рдорд┐рд▓рд╛ред - рд╕рдВрджреЗрд╢реЛрдВ рдХреА рд╕реВрдЪреА рдХрдо рдХрд░ рджреА рдЧрдИ рд╣реИред рдХрдо рдХреЛрдб - рдХрдо рдмреБрд░рд╛рдИ!
рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
let [<Literal>] commandAddress = "command" let [<Literal>] timerAddress = "timer" let [<Literal>] gameAddress = "game" // - let commandAgent (mailboxNetwork: MailboxNetwork) = mailboxNetwork.Box<CommandMessage, Command list>(commandAddress) let timerAgent (mailboxNetwork: MailboxNetwork) = mailboxNetwork.Box<TimerCommand, TimerState>(timerAddress) let gameAgent (mailboxNetwork: MailboxNetwork) = mailboxNetwork.Box<Command list, GameState>(gameAddress) // message loop let gameAgentFn (mailboxNetwork: MailboxNetwork) updateUi gameState cmd = let timerAgent = timerAgent mailboxNetwork // match gameState.gameFrame with // | Frame field -> // let gameState = Game.updateGameState gameState cmd timerAgent.Post Next // updateUi gameState // gameState // ! | End (Win _) -> timerAgent.Post PauseOrResume Game.updateGameState gameState cmd // | _ -> timerAgent.Post Stop // gameState // message loop let commandAgentFn (mailboxNetwork: MailboxNetwork) commands msg = let gameAgent = gameAgent mailboxNetwork match msg with | Cmd cmd -> cmd::commands // | Flush -> commands |> gameAgent.Post // [] // message loop let timerAgentFn (mailboxNetwork: MailboxNetwork) (state: TimerState) cmd = let commandAgent = commandAgent mailboxNetwork match cmd with | Start -> commandAgent.Post Flush; {state with active = true} | Next -> if state.active then // , Threading.Thread.Sleep(state.delay) commandAgent.Post Flush; state | Stop -> printfn "Stop received"; { state with active = false } | PauseOrResume -> if not state.active then //
рд╕рдВрджрд░реНрдн