Slide 1

Slide 1 text

4XJGUͷίʔυ͔Β ঢ়ଶભҠਤΛࣗಈͰੜ੒͠ ܧଓతʹϝϯςφϯε͠΍͘͢͢Δ J04%$+BQBO IUUQTHJUIVCDPNPCKFDUJWFBVEJPJ04%$

Slide 2

Slide 2 text

εςʔτϚγϯ ʢ༗ݶΦʔτϚτϯʣ ঢ়ଶͱભҠͱಈ࡞ͷ૊Έ߹Θ͔ͤΒͳΔ ৼΔ෣͍ͷϞσϧ

Slide 3

Slide 3 text

ྫɿυΞͷ։ด

Slide 4

Slide 4 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ

Slide 5

Slide 5 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ ঢ়ଶ ঢ়ଶ

Slide 6

Slide 6 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ ಈ࡞ ಈ࡞

Slide 7

Slide 7 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ ભҠ ભҠ

Slide 8

Slide 8 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ

Slide 9

Slide 9 text

ด͍ͯ͡Δ ։͍͍ͯΔ ։͘ ด͡Δ υΞͷ։ดͷঢ়ଶભҠਤ

Slide 10

Slide 10 text

ৼΔ෣͍Λίʔυʹ͢Δ

Slide 11

Slide 11 text

εςʔτύλʔϯ Ϋϥεʹڞ௨ͷΠϯλʔϑΣʔεΛఆٛͯ͠ ΠϯελϯεΛೖΕସ͑ͯৼΔ෣͍Λม͑Δ

Slide 12

Slide 12 text

໰୊ શମͷભҠ͕Θ͔Γʹ͍͘ ࣗ༝౓͕ߴ͗͢Δ Ϋϥε͕૿͑͗͢Δ

Slide 13

Slide 13 text

ղܾࡦ ঢ়ଶભҠਤΛ࡞Δ

Slide 14

Slide 14 text

ܧଓతʹίʔυͱਤΛ߹ΘͤΔͷ͕େม ໰୊

Slide 15

Slide 15 text

VJqPX IUUQTHJUIVCDPNIJSPLJEBJDIJVJqPX [࠷ॳʹ] Ϣʔβʔ͕ݟΔ΋ͷΛॻ͖·͢ɻ -- Ϣʔβʔ͕͢ΔߦಈΛॻ͖·͢ɻ [࣍ʹ] Ϣʔβʔ͕ݟΔ΋ͷ -- Ϣʔβʔ͕͢Δ͜ͱ̍ ==> ͦͷ݁Ռ̍ Ϣʔβʔ͕͢Δ͜ͱ̎ ==> ͦͷ݁Ռ̎ [ͦͷ݁Ռ̍] ݁Ռ [ͦͷ݁Ռ̎] ݁Ռ

Slide 16

Slide 16 text

"45 IUUQTTQFBLFSEFDLDPNLJTIJLBXBLBUTVNJBTUNFUBQSPHSBNNJOHJOTXJGU AST meta-programming in Swift try! Swift Tokyo 2018 Abstract Syntax Tree

Slide 17

Slide 17 text

'MPX(SBQI 4XJGUͷεςʔτϚγϯϥΠϒϥϦ IUUQTHJUIVCDPNPCKFDUJWFBVEJP4XJGU'MPX(SBQI

Slide 18

Slide 18 text

'MPX(SBQI%PU$POWFSUFS 'MPX(SBQIͰॻ͔Εͨίʔυ͔Β (SBQIWJ[ͷϑΝΠϧܗࣜʹॻ͖ग़͢ ίϚϯυϥΠϯπʔϧ IUUQTHJUIVCDPNPCKFDUJWFBVEJP'MPX(SBQI%PU$POWFSUFS

Slide 19

Slide 19 text

digraph { graph [label = "Door", labelloc = "t", labeljust = "l", fontcolor = "#333333", rankdir = "TB", fontname = "Osaka-Mono", fontsize = "12", charset = "UTF-8"] node [fontcolor = "#333333", fillcolor = "#F9F9F9", fontname = "Osaka-Mono", style = "solid,filled", fontsize = "10", color = "#CCCCCC"] edge [fontcolor = "#333333", fontname = "Osaka-Mono", fontsize = "9", color = "#AAAAAA"] opened [shape = "record", label = "{opened|։͍͍ͯΔ}", color = "#BBBBBB"] closing [shape = "record", label = "{closing|ด͡Δ}", color = "#40C5EE"] closed [shape = "record", label = "{closed|ด͍ͯ͡Δ}", color = "#00D54B"] opening [shape = "record", label = "{opening|։͘}", color = "#40C5EE"] "opened" -> "closing" [style = "solid", color = "#99DEF3"] "closing" -> "closed" [style = "dashed", color = "#AAAAAA"] "closed" -> "opening" [style = "solid", color = "#99DEF3"] // // Door.swift // import FlowGraph // υΞͷঢ়ଶ class Door: FlowGraphType { private(set) var isOpen: Bool = false { didSet { print("isOpen \(self.isOpen)") if let handler = self.isOpenHandler { handler(self.isOpen) } } } var isOpenHandler: ((Bool) -> Void)? enum WaitingState { case closed case opened } enum RunningState { case opening case closing } enum EventKind { case open case close } typealias Event = (kind: EventKind, object: Door) private let graph: FlowGraph init() { let builder = FlowGraphBuilder() // ด͍ͯ͡Δ builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } // ։͍͍ͯΔ builder.add(waiting: .opened) { event in if case .close = event.kind { return .run(.closing, event) } else { return .stay } } %PPSTXJGU %PPSEPU %PPSTWH

Slide 20

Slide 20 text

γΣϧεΫϦϓτͰ ΍͍ͬͯΔ͜ͱ

Slide 21

Slide 21 text

$ brew install graphviz (SBQIWJ[ΛΠϯετʔϧ $POWFSUFSͷ४උ )PNFCSFXΛΠϯετʔϧʢͷ֬ೝʣ

Slide 22

Slide 22 text

$ swift build -c release $ swift run -c release FlowGraphDotConverter ೖྗ͢ΔϑΝΠϧʢෳ਺ʣ--output ग़ྗ͢ΔϑΥϧμ $ dot -T svg ೖྗ͢Δύε -o ग़ྗ͢Δύε Ϗϧυ͢Δʢ4XJGU1BDLBHF.BOBHFSʣ 4XJGUϑΝΠϧΛղੳͯ͠(SBQIWJ[ͷܗࣜʹग़ྗ (SBQIWJ[Ͱਤʹม׵͢Δ $POWFSUFSͷ࣮ߦ

Slide 23

Slide 23 text

'MPX(SBQI

Slide 24

Slide 24 text

'MPX(SBQI%PPS DMPTFE PQFOFE DMPTJOH PQFOJOH &WFOU $VSSFOU

Slide 25

Slide 25 text

'MPX(SBQI%PPS DMPTFE PQFOFE 8BJUJOH4UBUF ଴ػ͢Δεςʔτ ֎෦͔ΒΠϕϯτΛड͚औ࣮ͬͯߦ͞ΕΔΫϩʔδϟΛ࣋ͭ &WFOU DMPTJOH ʢด͍ͯ͡Δʣ ʢ։͍͍ͯΔʣ

Slide 26

Slide 26 text

'MPX(SBQI%PPS DMPTFE PQFOFE Πϕϯτ 3VOOJOH4UBUF ॲཧΛ࣮ߦ͢Δεςʔτ 8BJUJOH4UBUF͔ΒΠϕϯτΛ ड͚औ࣮ͬͯߦ͞ΕΔ ΫϩʔδϟΛ࣋ͭ ଴ػ͢Δ͜ͱ͸Ͱ͖ͳ͍ DMPTJOH PQFOJOH ʢ։͘ʣ ʢด͡Δʣ

Slide 27

Slide 27 text

'MPX(SBQI%PPS DMPTFE PQFOFE &WFOU &WFOU ֎෦͔Β$VSSFOUͷ8BJUJOH4UBUFʹ౉͞ΕΔ 8BUJOH4UBUF͔Β3VOOJOH4UBUFʹ౉͞ΕΔ $VSSFOU DMPTJOH

Slide 28

Slide 28 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTFEεςʔτʹ଴ػ͍ͯ͠Δ DMPTJOH PQFOJOH

Slide 29

Slide 29 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS PQFO PQFOΠϕϯτΛDVSSFOUͷεςʔτʹ౉͢ DMPTJOH PQFOJOH

Slide 30

Slide 30 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS PQFOJOHεςʔτʹભҠͯ͠։͘ॲཧΛ࣮ߦ͢Δ DMPTJOH PQFOJOH

Slide 31

Slide 31 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS PQFOFEεςʔτʹભҠͯ͠଴ػ͢Δ DMPTJOH PQFOJOH

Slide 32

Slide 32 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTF DMPTFΠϕϯτΛDVSSFOUͷεςʔτʹ౉͢ DMPTJOH PQFOJOH

Slide 33

Slide 33 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTJOHεςʔτʹભҠͯ͠ด͡ΔॲཧΛ࣮ߦ͢Δ DMPTJOH PQFOJOH

Slide 34

Slide 34 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTFEεςʔτʹભҠͯ͠଴ػ͢Δ DMPTJOH PQFOJOH

Slide 35

Slide 35 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTFEεςʔτʹભҠͯ͠଴ػ͢Δ DMPTJOH PQFOJOH DMPTF

Slide 36

Slide 36 text

DMPTFE PQFOFE $VSSFOU 'MPX(SBQI%PPS DMPTFEεςʔτʹભҠͯ͠଴ػ͢Δ DMPTJOH PQFOJOH

Slide 37

Slide 37 text

'MPX(SBQIͷॻ͖ํ ܕͷఆٛ ઃܭΦϒδΣΫτͷੜ੒ εςʔτͷొ࿥ ࣮ߦΦϒδΣΫτͷੜ੒ ΠϕϯτΛड͚औΔ

Slide 38

Slide 38 text

ܕͷఆٛ

Slide 39

Slide 39 text

'MPX(SBQI5ZQFʹద߹ͨ͠ܕΛఆٛ public protocol FlowGraphType { associatedtype WaitingState: Hashable associatedtype RunningState: Hashable associatedtype Event ... }

Slide 40

Slide 40 text

class Door: FlowGraphType { enum WaitingState { case closed case opened } enum RunningState { case opening case closing } typealias Event = (kind: EventKind, object: Door) ... } 'MPX(SBQI5ZQFʹద߹ͨ͠ܕΛఆٛ

Slide 41

Slide 41 text

class Door: FlowGraphType { enum WaitingState { case closed case opened } enum RunningState { case opening case closing } typealias Event = (kind: EventKind, object: Door) ... } ଴ػ͢ΔεςʔτͷܕʢFOVNਪ঑ʣ 'MPX(SBQI5ZQFʹ४ڌͨ͠ܕΛఆٛ

Slide 42

Slide 42 text

class Door: FlowGraphType { enum WaitingState { case closed case opened } enum RunningState { case opening case closing } typealias Event = (kind: EventKind, object: Door) ... } ࣮ߦ͢ΔεςʔτͷܕʢFOVNਪ঑ʣ 'MPX(SBQI5ZQFʹ४ڌͨ͠ܕΛఆٛ

Slide 43

Slide 43 text

class Door: FlowGraphType { enum WaitingState { case closed case opened } enum RunningState { case opening case closing } typealias Event = (kind: EventKind, object: Door) ... } ड͚औΔΠϕϯτͷܕʢͳΜͰ΋ʣ 'MPX(SBQI5ZQFʹ४ڌͨ͠ܕΛఆٛ enum EventKind { case open case close }

Slide 44

Slide 44 text

ઃܭΦϒδΣΫτͷੜ੒

Slide 45

Slide 45 text

let builder = FlowGraphBuilder() 'MPX(SBQI#VJMEFSΛੜ੒

Slide 46

Slide 46 text

εςʔτͷొ࿥

Slide 47

Slide 47 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } 8BJUJOH4UBUFͷొ࿥

Slide 48

Slide 48 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } 8BJUJOH4UBUFͷొ࿥ ొ࿥͢Δεςʔτ໊

Slide 49

Slide 49 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } 8BJUJOH4UBUFͷొ࿥ ొ࿥͢ΔΫϩʔδϟ

Slide 50

Slide 50 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } ΠϕϯτΛड͚औΔ 8BJUJOH4UBUFͷొ࿥

Slide 51

Slide 51 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } 8BJUJOH4UBUFͷొ࿥ ผͷεςʔτʹભҠ͢Δ

Slide 52

Slide 52 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } 8BJUJOH4UBUFͷొ࿥ return .wait(.opened) ผͷεςʔτʹભҠ͢Δ

Slide 53

Slide 53 text

builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } Կ΋͠ͳ͍ 8BJUJOH4UBUFͷొ࿥

Slide 54

Slide 54 text

builder.add(running: .opening) { event in event.object.isOpen = true return .wait(.opened) } 3VOOJOH4UBUFͷొ࿥

Slide 55

Slide 55 text

builder.add(running: .opening) { event in event.object.isOpen = true return .wait(.opened) } Կ͔ॲཧΛ͢Δ 3VOOJOH4UBUFͷొ࿥

Slide 56

Slide 56 text

builder.add(running: .opening) { event in event.object.isOpen = true return .wait(.opened) } ผͷεςʔτʹભҠ͢Δ 3VOOJOH4UBUFͷొ࿥ ❇3VOOJOH4UBUFʹཹ·Δ͜ͱ͸Ͱ͖ͳ͍

Slide 57

Slide 57 text

࣮ߦΦϒδΣΫτͷੜ੒

Slide 58

Slide 58 text

self.graph = builder.build(initial: .closed) 'MPX(SBQIΛੜ੒͢Δ

Slide 59

Slide 59 text

self.graph = builder.build(initial: .closed) 'MPX(SBQIΛੜ੒͢Δ private let graph: FlowGraph ϓϩύςΟ

Slide 60

Slide 60 text

self.graph = builder.build(initial: .closed) 'MPX(SBQIΛੜ੒͢Δ ࠷ॳʹ଴ػ͢Δεςʔτ

Slide 61

Slide 61 text

Πϕϯτͷड͚औΓ

Slide 62

Slide 62 text

ΠϕϯτΛड͚औΔ func run(_ kind: EventKind) { self.graph.run((kind, self)) }

Slide 63

Slide 63 text

func run(_ kind: EventKind) { self.graph.run((kind, self)) } ΠϕϯτΛड͚औΔ ΠϕϯτΛ౉͢

Slide 64

Slide 64 text

'MPX(SBQI%PU$POWFSUFS

Slide 65

Slide 65 text

4PVSDF,JUUFO w 4PVSDF,JUΛίϚϯυϥΠϯͰ࢖͑ΔΑ͏ʹͨ͠ ϥΠϒϥϦ w 4XJGUͷίʔυΛղੳͯ͠ɺߏ଄ΛऔಘͰ͖Δ w 4PVSDF,JUUFO'SBNFXPSLΛΠϯϙʔτ͢Ε͹ɺ 4XJGUͷϥΠϒϥϦͱͯ͠΋࢖͑Δ

Slide 66

Slide 66 text

w4USVDUVSF w4ZOUBY ղੳ͢Δػೳ

Slide 67

Slide 67 text

4USVDUVSF w πϦʔߏ଄Ͱղੳ͢Δ w DMBTT΍ؔ਺΍ม਺ͳͲͷߏ଄͕औಘͰ͖Δ w ίϝϯτͳͲ͸ແࢹ͞ΕΔ

Slide 68

Slide 68 text

\ LFZEJBHOPTUJD@TUBHFTPVSDFEJBHOPTUJDTUBHFTXJGUQBSTF LFZMFOHUI LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJMJUZJOUFSOBM LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZFMFNFOUT< \ LFZLJOETPVSDFMBOHTXJGUTUSVDUVSFFMFNUZQFSFG LFZMFOHUI LFZP⒎TFU ^ > LFZJOIFSJUFEUZQFT< \ LFZOBNF'MPX(SBQI5ZQF ^ > LFZLJOETPVSDFMBOHTXJGUEFDMDMBTT LFZMFOHUI LFZOBNF%PPS LFZOBNFMFOHUI 4USVDUVSF

Slide 69

Slide 69 text

\ LFZEJBHOPTUJD@TUBHFTPVSDFEJBHOPTUJDTUBHFT LFZMFOHUI LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZFMFNFOUT< \ LFZLJOETPVSDFMBOHTXJGUTUSVDUVSFFMFN LFZMFOHUI LFZP⒎TFU P⒎TFUͱMFOHUIͰ ཁૉͷจࣈྻͷҐஔ͕ औಘͰ͖Δ

Slide 70

Slide 70 text

\ LFZEJBHOPTUJD@TUBHFTPVSDFEJBHOPTUJDTUBHFT LFZMFOHUI LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZFMFNFOUT< \ LFZLJOETPVSDFMBOHTXJGUTUSVDUVSFFMFN LFZMFOHUI LFZP⒎TFU TVCTUSVDUVSFʹࢠͷཁૉͷ഑ྻ

Slide 71

Slide 71 text

LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZFMFNFOUT< \ LFZLJOETPVSDFMBOHTXJGUTUSVDUVSFFMFN LFZMFOHUI LFZP⒎TFU ^ > LFZJOIFSJUFEUZQFT< LJOE͸ཁૉͷछྨ

Slide 72

Slide 72 text

ΫϥεΛ୳͢

Slide 73

Slide 73 text

// Door.swift // import FlowGraph // υΞͷঢ়ଶ class Door: FlowGraphType { private(set) var isOpen: Bool = false didSet { print("isOpen \(self.isOpen)") if let handler = self.isOpenHa handler(self.isOpen) } } } var isOpenHandler: ((Bool) -> Void)?

Slide 74

Slide 74 text

LFZJOIFSJUFEUZQFT< \ LFZOBNF'MPX(SBQI5ZQF ^ > LFZLJOETPVSDFMBOHTXJGUEFDMDMBTT LFZMFOHUI LFZOBNF%PPS LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZSVOUJNF@OBNF@5U$@@NBJO@@%PPS LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJM LJOE͕DMBTT

Slide 75

Slide 75 text

LFZJOIFSJUFEUZQFT< \ LFZOBNF'MPX(SBQI5ZQF ^ > LFZLJOETPVSDFMBOHTXJGUEFDMDMBTT LFZMFOHUI LFZOBNF%PPS LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZSVOUJNF@OBNF@5U$@@NBJO@@%PPS LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJM P⒎TFUͱMFOHIͰ ΫϥεͷҐஔΛऔಘ

Slide 76

Slide 76 text

LFZJOIFSJUFEUZQFT< \ LFZOBNF'MPX(SBQI5ZQF ^ > LFZLJOETPVSDFMBOHTXJGUEFDMDMBTT LFZMFOHUI LFZOBNF%PPS LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZSVOUJNF@OBNF@5U$@@NBJO@@%PPS LFZTVCTUSVDUVSF< \ LFZBDDFTTJCJMJUZTPVSDFMBOHTXJGUBDDFTTJCJM OBNFʹDMBTTͷ໊લ

Slide 77

Slide 77 text

εςʔτΛ୳͢

Slide 78

Slide 78 text

init() { let builder = FlowGraphBuilder() // ด͍ͯ͡Δ builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } // ։͍͍ͯΔ builder.add(waiting: .opened) { event in if case .close = event.kind { return .run(.closing, event) } else { return .stay

Slide 79

Slide 79 text

\ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSDBMM LFZMFOHUI LFZOBNFCVJMEFSBEE LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSBSHVNFOU LFZMFOHUI LFZOBNFXBJUJOH LFZOBNFMFOHUI FYQSDBMM͕ؔ਺ݺͼग़͠

Slide 80

Slide 80 text

\ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSDBMM LFZMFOHUI LFZOBNFCVJMEFSBEE LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSBSHVNFOU LFZMFOHUI LFZOBNFXBJUJOH LFZOBNFMFOHUI FYQSDBMMͷOBNFʹ ؔ਺໊

Slide 81

Slide 81 text

LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSBSHVNFOU LFZMFOHUI LFZOBNFXBJUJOH LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU ^ \ LFZCPEZMFOHUI LFZCPEZP⒎TFU BSHVNFOU͕ ؔ਺ͷҾ਺

Slide 82

Slide 82 text

LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSBSHVNFOU LFZMFOHUI LFZOBNFXBJUJOH LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU ^ \ LFZCPEZMFOHUI LFZCPEZP⒎TFU BSHVNFOUͷOBNFʹ Ҿ਺ͷϥϕϧ

Slide 83

Slide 83 text

LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU LFZTVCTUSVDUVSF< \ LFZCPEZMFOHUI LFZCPEZP⒎TFU LFZLJOETPVSDFMBOHTXJGUFYQSBSHVNFOU LFZMFOHUI LFZOBNFXBJUJOH LFZOBNFMFOHUI LFZOBNFP⒎TFU LFZP⒎TFU ^ \ LFZCPEZMFOHUI LFZCPEZP⒎TFU Ҿ਺ͷ஋ͷ෦෼͸Ґஔ͚ͩ

Slide 84

Slide 84 text

init() { let builder = FlowGraphBuilder() // ด͍ͯ͡Δ builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } // ։͍͍ͯΔ builder.add(waiting: .opened) { event in if case .close = event.kind { return .run(.closing, event) } else { return .stay SFUVSOͷҐஔ͸Θ͔Βͳ͍

Slide 85

Slide 85 text

4ZOUBY 4ZOUBY.BQ

Slide 86

Slide 86 text

{type:comment offset:0, length:3, content:'// '}, {type:comment offset:3, length:15, content:'// Door.swift '}, {type:comment offset:18, length:3, content:'// '}, {type:keyword offset:22, length:6, content:'import'}, {type:identifier offset:29, length:9, content:'FlowGraph'}, {type:comment offset:40, length:19, content:'// υΞͷঢ়ଶ '}, {type:keyword offset:59, length:5, content:'class'}, {type:identifier offset:65, length:4, content:'Door'}, {type:typeidentifier offset:71, length:13, content:'FlowGraphType'}, {type:attributeBuiltin offset:91, length:12, content:'private(set)'}, {type:keyword offset:104, length:3, content:'var'}, {type:identifier offset:108, length:6, content:'isOpen'}, {type:typeidentifier offset:116, length:4, content:'Bool'}, {type:keyword offset:123, length:5, content:'false'}, {type:keyword offset:139, length:6, content:'didSet'}, {type:identifier offset:160, length:5, content:'print'}, {type:string offset:166, length:8, content:'"isOpen '}, {type:stringInterpolationAnchor offset:175, length:1, content:'('}, {type:keyword offset:176, length:4, content:'self'}, {type:identifier offset:181, length:6, content:'isOpen'}, {type:stringInterpolationAnchor offset:187, length:1, content:')'},

Slide 87

Slide 87 text

{type:keyword offset:59, length:5, content:'class'}

Slide 88

Slide 88 text

{type:identifier offset:65, length:4, content:'Door'}

Slide 89

Slide 89 text

{type:comment offset:40, length:19, content:'// υΞͷঢ়ଶ '}

Slide 90

Slide 90 text

init() { let builder = FlowGraphBuilder() // ด͍ͯ͡Δ builder.add(waiting: .closed) { event in if case .open = event.kind { return .run(.opening, event) } else { return .stay } } // ։͍͍ͯΔ builder.add(waiting: .opened) { event in if case .close = event.kind { return .run(.closing, event) } else { return .stay ؔ਺ͷCPEZ෦෼

Slide 91

Slide 91 text

'}, {type:identifier offset:800, length:7, content:'builder'}, {type:identifier offset:808, length:3, content:'add'}, {type:identifier offset:812, length:7, content:'waiting'}, {type:identifier offset:822, length:6, content:'closed'}, {type:identifier offset:832, length:5, content:'event'}, {type:keyword offset:838, length:2, content:'in'}, {type:keyword offset:853, length:2, content:'if'}, {type:keyword offset:856, length:4, content:'case'}, {type:identifier offset:862, length:4, content:'open'}, {type:identifier offset:869, length:5, content:'event'}, {type:identifier offset:875, length:4, content:'kind'}, {type:keyword offset:898, length:6, content:'return'}, {type:identifier offset:906, length:3, content:'run'}, {type:identifier offset:911, length:7, content:'opening'}, {type:identifier offset:920, length:5, content:'event'}, {type:keyword offset:941, length:4, content:'else'}, {type:keyword offset:964, length:6, content:'return'}, {type:identifier offset:972, length:4, content:'stay'}, {type:comment offset:1018, length:19, content:'// ։͍͍ͯΔ '}, {type:identifier offset:1045, length:7, content:'builder'}, {type:identifier offset:1053, length:3, content:'add'}, {type:identifier offset:1057, length:7, content:'waiting'}, {type:identifier offset:1067, length:6, content:'opened'},

Slide 92

Slide 92 text

'}, {type:identifier offset:800, length:7, content:'builder'}, {type:identifier offset:808, length:3, content:'add'}, {type:identifier offset:812, length:7, content:'waiting'}, {type:identifier offset:822, length:6, content:'closed'}, {type:identifier offset:832, length:5, content:'event'}, {type:keyword offset:838, length:2, content:'in'}, {type:keyword offset:853, length:2, content:'if'}, {type:keyword offset:856, length:4, content:'case'}, {type:identifier offset:862, length:4, content:'open'}, {type:identifier offset:869, length:5, content:'event'}, {type:identifier offset:875, length:4, content:'kind'}, {type:keyword offset:898, length:6, content:'return'}, {type:identifier offset:906, length:3, content:'run'}, {type:identifier offset:911, length:7, content:'opening'}, {type:identifier offset:920, length:5, content:'event'}, {type:keyword offset:941, length:4, content:'else'}, {type:keyword offset:964, length:6, content:'return'}, {type:identifier offset:972, length:4, content:'stay'}, {type:comment offset:1018, length:19, content:'// ։͍͍ͯΔ '}, {type:identifier offset:1045, length:7, content:'builder'}, {type:identifier offset:1053, length:3, content:'add'}, {type:identifier offset:1057, length:7, content:'waiting'}, {type:identifier offset:1067, length:6, content:'opened'},

Slide 93

Slide 93 text

εςʔτͷ5PLFOΛղੳ͢Δ

Slide 94

Slide 94 text

waiting closed event in if case open event kind return run opening event else return stay ಄͔Βॱ൪ʹݟ͍ͯ͘

Slide 95

Slide 95 text

waiting closed event in if case open event kind return run opening event else return stay XBJUJOH͔ SVOOJOH ͳΒʜ XBJUJOH

Slide 96

Slide 96 text

waiting closed event in if case open event kind return run opening event else return stay ࣍͸ εςʔτ໊ XBJUJOH DMPTFE

Slide 97

Slide 97 text

waiting closed event in if case open event kind return run opening event else return stay JOͷޙ͔Β Ϋϩʔδϟ XBJUJOH DMPTFE

Slide 98

Slide 98 text

waiting closed event in if case open event kind return run opening event else return stay SFUVSOΛ୳͢ XBJUJOH DMPTFE

Slide 99

Slide 99 text

waiting closed event in if case open event kind return run opening event else return stay SVO͔ XBJUͳΒʜ XBJUJOH DMPTFE

Slide 100

Slide 100 text

waiting closed event in if case open event kind return run opening event else return stay ਐΉઌͷ εςʔτ໊ XBJUJOH DMPTFE PQFOJOH

Slide 101

Slide 101 text

waiting closed event in if case open event kind return run opening event else return stay SFUVSOΛ୳͢ XBJUJOH DMPTFE PQFOJOH

Slide 102

Slide 102 text

waiting closed event in if case open event kind return run opening event else return stay TUBZͳΒແࢹ XBJUJOH DMPTFE PQFOJOH

Slide 103

Slide 103 text

εςʔτղੳͷ ঢ়ଶભҠਤ

Slide 104

Slide 104 text

%PU

Slide 105

Slide 105 text

digraph { graph [label = "Door", labelloc = "t", labeljust = "l", fontcolor = "#333333", rankdir = "TB", fontname = "Osaka-Mono", fontsize = "12", charset = "UTF-8"] node [fontcolor = "#333333", fillcolor = "#F9F9F9", fontname = "Osaka-Mono", style = "solid,filled", fontsize = "10", color = "#CCCCCC"] edge [fontcolor = "#333333", fontname = "Osaka-Mono", fontsize = "9", color = "#AAAAAA"] opened [shape = "record", label = "{opened|։͍͍ͯΔ}", color = "#BBBBBB"] closing [shape = "record", label = "{closing|ด͡Δ}", color = "#40C5EE"] closed [shape = "record", label = "{closed|ด͍ͯ͡Δ}", color = "#00D54B"] opening [shape = "record", label = "{opening|։͘}", color = "#40C5EE"] "opened" -> "closing" [style = "solid", color = "#99DEF3"] "closing" -> "closed" [style = "dashed", color = "#AAAAAA"] "closed" -> "opening" [style = "solid", color = "#99DEF3"] "opening" -> "opened" [style = "dashed", color = "#AAAAAA"] } %PPSEPU

Slide 106

Slide 106 text

digraph { graph [label = "Door", labelloc = "t fontcolor = "#333333", rankdi fontname = "Osaka-Mono", font charset = "UTF-8"] node [fontcolor = "#333333", fillcol fontname = "Osaka-Mono", style fontsize = "10", color = "#CCC edge [fontcolor = "#333333", fontnam fontsize = "9", color = "#AAAA opened [shape = "record", label = "{ EJHSBQI͸༗޲άϥϑ %PPSEPU

Slide 107

Slide 107 text

charset = "UTF-8"] node [fontcolor = "#333333", fillcolor = " fontname = "Osaka-Mono", style = "so fontsize = "10", color = "#CCCCCC"] edge [fontcolor = "#333333", fontname = "O fontsize = "9", color = "#AAAAAA"] opened [shape = "record", label = "{opened|։͍͍ͯΔ}", color = "#BBBBBB"] closing [shape = "record", label = "{closi color = "#40C5EE"] closed [shape = "record", label = "{closed color = "#00D54B"] opening [shape = "record", label = "{openi color = "#40C5EE"] ϊʔυͷ໊લ ϊʔυ

Slide 108

Slide 108 text

charset = "UTF-8"] node [fontcolor = "#333333", fillcolor = " fontname = "Osaka-Mono", style = "so fontsize = "10", color = "#CCCCCC"] edge [fontcolor = "#333333", fontname = "O fontsize = "9", color = "#AAAAAA"] opened [shape = "record", label = "{opened|։͍͍ͯΔ}", color = "#BBBBBB"] closing [shape = "record", label = "{closi color = "#40C5EE"] closed [shape = "record", label = "{closed color = "#00D54B"] opening [shape = "record", label = "{openi color = "#40C5EE"] <>ͷதʹදࣔ͞ΕΔத਎ ϊʔυ

Slide 109

Slide 109 text

closing [shape = "record", label = "{closing color = "#40C5EE"] closed [shape = "record", label = "{closed|ด color = "#00D54B"] opening [shape = "record", label = "{opening color = "#40C5EE"] "opened" -> "closing" [style = "solid", color = "#99DEF3"] "closing" -> "closed" [style = "dashed", col "closed" -> "opening" [style = "solid", colo "opening" -> "opened" [style = "dashed", col } Τοδ ͰϊʔυΛͭͳ͛Δ

Slide 110

Slide 110 text

'MPX(SBQI IUUQTHJUIVCDPNPCKFDUJWFBVEJP4XJGU'MPX(SBQI 'MPX(SBQI%PU$POWFSUFS IUUQTHJUIVCDPNPCKFDUJWFBVEJP'MPX(SBQI%PU$POWFSUFS 4PVSDF,JUUFO (SBQIWJ[ IUUQTHJUIVCDPNKQTJN4PVSDF,JUUFO IUUQTXXXHSBQIWJ[PSH ຊ೔ͷαϯϓϧ IUUQTHJUIVCDPNPCKFDUJWFBVEJPJ04%$