metasepi team meeting #6: "snatch-driven development"

39
Metasepi team meeting #6: "Snatch-driven development" Metasepi team meeting #6: "Snatch-driven development" Metasepi team meeting #6: "Snatch-driven development" Metasepi team meeting #6: "Snatch-driven development" Metasepi team meeting #6: "Snatch-driven development" Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe

Upload: kiwamu-okabe

Post on 15-Jan-2015

2.502 views

Category:

Technology


0 download

DESCRIPTION

Metasepi team meeting #6: "Snatch-driven development"

TRANSCRIPT

Page 1: Metasepi team meeting #6: "Snatch-driven development"

Metasepi team meeting #6: "Snatch-driven development"

Metasepi team meeting #6: "Snatch-driven development"

Metasepi team meeting #6: "Snatch-driven development"

Metasepi team meeting #6: "Snatch-driven development"

Metasepi team meeting #6:"Snatch-driven development"

Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe

Page 2: Metasepi team meeting #6: "Snatch-driven development"

Who am I?Who am I?Who am I?Who am I?Who am I?

☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/☆ http://www.masterq.net/

☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q

☆ Organizer of Metasepi project☆ Organizer of Metasepi project☆ Organizer of Metasepi project☆ Organizer of Metasepi project☆ Organizer of Metasepi project

☆ A developer of Ajhc Haskell compiler☆ A developer of Ajhc Haskell compiler☆ A developer of Ajhc Haskell compiler☆ A developer of Ajhc Haskell compiler☆ A developer of Ajhc Haskell compiler

☆ A Debian Maintainer☆ A Debian Maintainer☆ A Debian Maintainer☆ A Debian Maintainer☆ A Debian Maintainer

☆ 10 years' experience in developing OS using NetBSD.☆ 10 years' experience in developing OS using NetBSD.☆ 10 years' experience in developing OS using NetBSD.☆ 10 years' experience in developing OS using NetBSD.☆ 10 years' experience in developing OS using NetBSD.

Page 3: Metasepi team meeting #6: "Snatch-driven development"

AgendaAgendaAgendaAgendaAgenda

☆ [1] Demo☆ [1] Demo☆ [1] Demo☆ [1] Demo☆ [1] Demo

☆ [2] What is Ajhc?☆ [2] What is Ajhc?☆ [2] What is Ajhc?☆ [2] What is Ajhc?☆ [2] What is Ajhc?

☆ [3] What is Metasepi?☆ [3] What is Metasepi?☆ [3] What is Metasepi?☆ [3] What is Metasepi?☆ [3] What is Metasepi?

☆ [4] What is compiler to build OS☆ [4] What is compiler to build OS☆ [4] What is compiler to build OS☆ [4] What is compiler to build OS☆ [4] What is compiler to build OS

☆ [5] How to use Ajhc☆ [5] How to use Ajhc☆ [5] How to use Ajhc☆ [5] How to use Ajhc☆ [5] How to use Ajhc

☆ [6] Case study: Snatch Android☆ [6] Case study: Snatch Android☆ [6] Case study: Snatch Android☆ [6] Case study: Snatch Android☆ [6] Case study: Snatch Android

☆ [7] Detail of Snatch process☆ [7] Detail of Snatch process☆ [7] Detail of Snatch process☆ [7] Detail of Snatch process☆ [7] Detail of Snatch process

Page 4: Metasepi team meeting #6: "Snatch-driven development"

[1] Demo[1] Demo[1] Demo[1] Demo[1] Demo

☆ RSS reader running on mbed (ARM).☆ RSS reader running on mbed (ARM).☆ RSS reader running on mbed (ARM).☆ RSS reader running on mbed (ARM).☆ RSS reader running on mbed (ARM).

☆ Show reddit articles on LCD display.☆ Show reddit articles on LCD display.☆ Show reddit articles on LCD display.☆ Show reddit articles on LCD display.☆ Show reddit articles on LCD display.

☆ You can watch the movie following.☆ You can watch the movie following.☆ You can watch the movie following.☆ You can watch the movie following.☆ You can watch the movie following.

http://bit.ly/mbedmovhttp://bit.ly/mbedmovhttp://bit.ly/mbedmovhttp://bit.ly/mbedmovhttp://bit.ly/mbedmov

Page 5: Metasepi team meeting #6: "Snatch-driven development"

Demo hardwareDemo hardwareDemo hardwareDemo hardwareDemo hardware

Architecture: ARM Cortex-M3Architecture: ARM Cortex-M3Architecture: ARM Cortex-M3Architecture: ARM Cortex-M3Architecture: ARM Cortex-M3

RAM size: 64kBRAM size: 64kBRAM size: 64kBRAM size: 64kBRAM size: 64kB

IO: Ethernet, LED, LCD, SD Card, USB host/device, SerialIO: Ethernet, LED, LCD, SD Card, USB host/device, SerialIO: Ethernet, LED, LCD, SD Card, USB host/device, SerialIO: Ethernet, LED, LCD, SD Card, USB host/device, SerialIO: Ethernet, LED, LCD, SD Card, USB host/device, Serial

Page 6: Metasepi team meeting #6: "Snatch-driven development"

Demo softwareDemo softwareDemo softwareDemo softwareDemo software

github.com/ajhc/demo-cortex-m3github.com/ajhc/demo-cortex-m3github.com/ajhc/demo-cortex-m3github.com/ajhc/demo-cortex-m3github.com/ajhc/demo-cortex-m3

Page 7: Metasepi team meeting #6: "Snatch-driven development"

Demo source codeDemo source codeDemo source codeDemo source codeDemo source codedemo-cortex-m3`-- mbed-nxp-lpc1768 |-- BuildShell <= Compile enviroment |-- build | `-- mbed.ld <= Linker Sscript |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a <= mbed library (compiled) |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface <= TCP/IP protocol stack | |-- c_extern.h | |-- dummy4jhc.c <= C lanuage stub for Haskell | |-- hs_src | | `-- *.hs <= Haskell source code | |-- main.c <= C language main function | `-- mbed-rtos <= mbed-rtos OS `-- src `-- gcc4mbed.c

demo-cortex-m3`-- mbed-nxp-lpc1768 |-- BuildShell <= Compile enviroment |-- build | `-- mbed.ld <= Linker Sscript |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a <= mbed library (compiled) |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface <= TCP/IP protocol stack | |-- c_extern.h | |-- dummy4jhc.c <= C lanuage stub for Haskell | |-- hs_src | | `-- *.hs <= Haskell source code | |-- main.c <= C language main function | `-- mbed-rtos <= mbed-rtos OS `-- src `-- gcc4mbed.c

demo-cortex-m3`-- mbed-nxp-lpc1768 |-- BuildShell <= Compile enviroment |-- build | `-- mbed.ld <= Linker Sscript |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a <= mbed library (compiled) |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface <= TCP/IP protocol stack | |-- c_extern.h | |-- dummy4jhc.c <= C lanuage stub for Haskell | |-- hs_src | | `-- *.hs <= Haskell source code | |-- main.c <= C language main function | `-- mbed-rtos <= mbed-rtos OS `-- src `-- gcc4mbed.c

demo-cortex-m3`-- mbed-nxp-lpc1768 |-- BuildShell <= Compile enviroment |-- build | `-- mbed.ld <= Linker Sscript |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a <= mbed library (compiled) |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface <= TCP/IP protocol stack | |-- c_extern.h | |-- dummy4jhc.c <= C lanuage stub for Haskell | |-- hs_src | | `-- *.hs <= Haskell source code | |-- main.c <= C language main function | `-- mbed-rtos <= mbed-rtos OS `-- src `-- gcc4mbed.c

demo-cortex-m3`-- mbed-nxp-lpc1768 |-- BuildShell <= Compile enviroment |-- build | `-- mbed.ld <= Linker Sscript |-- external | `-- mbed | `-- LPC1768 | `-- GCC_ARM | `-- libmbed.a <= mbed library (compiled) |-- linux_install |-- samples | `-- Haskell_Http | |-- EthernetInterface <= TCP/IP protocol stack | |-- c_extern.h | |-- dummy4jhc.c <= C lanuage stub for Haskell | |-- hs_src | | `-- *.hs <= Haskell source code | |-- main.c <= C language main function | `-- mbed-rtos <= mbed-rtos OS `-- src `-- gcc4mbed.c

Page 8: Metasepi team meeting #6: "Snatch-driven development"

[2] What is Ajhc?[2] What is Ajhc?[2] What is Ajhc?[2] What is Ajhc?[2] What is Ajhc?

http://ajhc.metasepi.org/http://ajhc.metasepi.org/http://ajhc.metasepi.org/http://ajhc.metasepi.org/http://ajhc.metasepi.org/

☆ Ajhc := A fork of jhc☆ Ajhc := A fork of jhc☆ Ajhc := A fork of jhc☆ Ajhc := A fork of jhc☆ Ajhc := A fork of jhc

☆ jhc := John's Haskell Compiler☆ jhc := John's Haskell Compiler☆ jhc := John's Haskell Compiler☆ jhc := John's Haskell Compiler☆ jhc := John's Haskell Compiler

☆ http://repetae.net/computer/jhc/☆ http://repetae.net/computer/jhc/☆ http://repetae.net/computer/jhc/☆ http://repetae.net/computer/jhc/☆ http://repetae.net/computer/jhc/

☆ Jhc outputs binary that has low-memory-footprint and runs fast.☆ Jhc outputs binary that has low-memory-footprint and runs fast.☆ Jhc outputs binary that has low-memory-footprint and runs fast.☆ Jhc outputs binary that has low-memory-footprint and runs fast.☆ Jhc outputs binary that has low-memory-footprint and runs fast.

☆ Good for embedded software.☆ Good for embedded software.☆ Good for embedded software.☆ Good for embedded software.☆ Good for embedded software.

Page 9: Metasepi team meeting #6: "Snatch-driven development"

Why need Ajhc?Why need Ajhc?Why need Ajhc?Why need Ajhc?Why need Ajhc?

☆ GHC is de facto standard on Haskell.☆ GHC is de facto standard on Haskell.☆ GHC is de facto standard on Haskell.☆ GHC is de facto standard on Haskell.☆ GHC is de facto standard on Haskell.

☆ GHC := Glasgow Haskell Compiler☆ GHC := Glasgow Haskell Compiler☆ GHC := Glasgow Haskell Compiler☆ GHC := Glasgow Haskell Compiler☆ GHC := Glasgow Haskell Compiler

☆ http://www.haskell.org/ghc/☆ http://www.haskell.org/ghc/☆ http://www.haskell.org/ghc/☆ http://www.haskell.org/ghc/☆ http://www.haskell.org/ghc/

☆ Why need another Haskell compiler?☆ Why need another Haskell compiler?☆ Why need another Haskell compiler?☆ Why need another Haskell compiler?☆ Why need another Haskell compiler?

☆ To develop kernel named "Metasepi".☆ To develop kernel named "Metasepi".☆ To develop kernel named "Metasepi".☆ To develop kernel named "Metasepi".☆ To develop kernel named "Metasepi".

Page 10: Metasepi team meeting #6: "Snatch-driven development"

[3] What is Metasepi?[3] What is Metasepi?[3] What is Metasepi?[3] What is Metasepi?[3] What is Metasepi?

http://metasepi.org/http://metasepi.org/http://metasepi.org/http://metasepi.org/http://metasepi.org/

☆ Unix-like OS designed by strong type.☆ Unix-like OS designed by strong type.☆ Unix-like OS designed by strong type.☆ Unix-like OS designed by strong type.☆ Unix-like OS designed by strong type.

☆ Using ML or more strong type lang.☆ Using ML or more strong type lang.☆ Using ML or more strong type lang.☆ Using ML or more strong type lang.☆ Using ML or more strong type lang.

Haskell http://www.haskell.org/Haskell http://www.haskell.org/Haskell http://www.haskell.org/Haskell http://www.haskell.org/Haskell http://www.haskell.org/

OCaml http://caml.inria.fr/OCaml http://caml.inria.fr/OCaml http://caml.inria.fr/OCaml http://caml.inria.fr/OCaml http://caml.inria.fr/

MLton http://mlton.org/MLton http://mlton.org/MLton http://mlton.org/MLton http://mlton.org/MLton http://mlton.org/

. . . and suchlike.. . . and suchlike.. . . and suchlike.. . . and suchlike.. . . and suchlike.

Page 11: Metasepi team meeting #6: "Snatch-driven development"

Why need Metasepi?Why need Metasepi?Why need Metasepi?Why need Metasepi?Why need Metasepi?

☆ We have already Linux or Windows.☆ We have already Linux or Windows.☆ We have already Linux or Windows.☆ We have already Linux or Windows.☆ We have already Linux or Windows.

☆ But the developers are suffering.☆ But the developers are suffering.☆ But the developers are suffering.☆ But the developers are suffering.☆ But the developers are suffering.

☆ If use the kernel changed by you,☆ If use the kernel changed by you,☆ If use the kernel changed by you,☆ If use the kernel changed by you,☆ If use the kernel changed by you,

☆ you will get many runtime error.☆ you will get many runtime error.☆ you will get many runtime error.☆ you will get many runtime error.☆ you will get many runtime error.

☆ Difficult even to reproduce it.☆ Difficult even to reproduce it.☆ Difficult even to reproduce it.☆ Difficult even to reproduce it.☆ Difficult even to reproduce it.

Page 12: Metasepi team meeting #6: "Snatch-driven development"

Doesn't OSS have good quality?Doesn't OSS have good quality?Doesn't OSS have good quality?Doesn't OSS have good quality?Doesn't OSS have good quality?

☆ "The Cathedral and the Bazaar"☆ "The Cathedral and the Bazaar"☆ "The Cathedral and the Bazaar"☆ "The Cathedral and the Bazaar"☆ "The Cathedral and the Bazaar"

☆ "Given enough eyeballs, all bugs are shallow."☆ "Given enough eyeballs, all bugs are shallow."☆ "Given enough eyeballs, all bugs are shallow."☆ "Given enough eyeballs, all bugs are shallow."☆ "Given enough eyeballs, all bugs are shallow."http://cruel.org/freeware/cathedral.htmlhttp://cruel.org/freeware/cathedral.htmlhttp://cruel.org/freeware/cathedral.htmlhttp://cruel.org/freeware/cathedral.htmlhttp://cruel.org/freeware/cathedral.html

☆ But if you develop your own product reusing OSS...☆ But if you develop your own product reusing OSS...☆ But if you develop your own product reusing OSS...☆ But if you develop your own product reusing OSS...☆ But if you develop your own product reusing OSS...

Page 13: Metasepi team meeting #6: "Snatch-driven development"

Low quality out of OSS umbrellaLow quality out of OSS umbrellaLow quality out of OSS umbrellaLow quality out of OSS umbrellaLow quality out of OSS umbrella

Page 14: Metasepi team meeting #6: "Snatch-driven development"

Type safetyType safetyType safetyType safetyType safety

☆ Less runtime errors.☆ Less runtime errors.☆ Less runtime errors.☆ Less runtime errors.☆ Less runtime errors.

☆ "数理科学的バグ撲滅方法論のすすめ"☆ "数理科学的バグ撲滅方法論のすすめ"☆ "数理科学的バグ撲滅方法論のすすめ"☆ "数理科学的バグ撲滅方法論のすすめ"☆ "数理科学的バグ撲滅方法論のすすめ"http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/http://itpro.nikkeibp.co.jp/article/COLUMN/20060915/248230/

Page 15: Metasepi team meeting #6: "Snatch-driven development"

Kernel desperately wants typeKernel desperately wants typeKernel desperately wants typeKernel desperately wants typeKernel desperately wants type

☆ Kernels are developed with C lang.☆ Kernels are developed with C lang.☆ Kernels are developed with C lang.☆ Kernels are developed with C lang.☆ Kernels are developed with C lang.

☆ Error on user space => SEGV☆ Error on user space => SEGV☆ Error on user space => SEGV☆ Error on user space => SEGV☆ Error on user space => SEGV

☆ Error on kernel space => halt!☆ Error on kernel space => halt!☆ Error on kernel space => halt!☆ Error on kernel space => halt!☆ Error on kernel space => halt!

☆ Should design kernel with the greatest care.☆ Should design kernel with the greatest care.☆ Should design kernel with the greatest care.☆ Should design kernel with the greatest care.☆ Should design kernel with the greatest care.

☆ C language is safe?☆ C language is safe?☆ C language is safe?☆ C language is safe?☆ C language is safe?

Page 16: Metasepi team meeting #6: "Snatch-driven development"

[4] What is compiler to build OS[4] What is compiler to build OS[4] What is compiler to build OS[4] What is compiler to build OS[4] What is compiler to build OS

☆ Need strong type.☆ Need strong type.☆ Need strong type.☆ Need strong type.☆ Need strong type.

☆ Need flexibility such as C language.☆ Need flexibility such as C language.☆ Need flexibility such as C language.☆ Need flexibility such as C language.☆ Need flexibility such as C language.

☆ Create it if there are not!☆ Create it if there are not!☆ Create it if there are not!☆ Create it if there are not!☆ Create it if there are not!

☆ From scratch? No thank you...☆ From scratch? No thank you...☆ From scratch? No thank you...☆ From scratch? No thank you...☆ From scratch? No thank you...

☆ Look for our compiler base.☆ Look for our compiler base.☆ Look for our compiler base.☆ Look for our compiler base.☆ Look for our compiler base.

Page 17: Metasepi team meeting #6: "Snatch-driven development"

Want POSIX free compilerWant POSIX free compilerWant POSIX free compilerWant POSIX free compilerWant POSIX free compiler

Programs to print "hoge" on terminal.Programs to print "hoge" on terminal.Programs to print "hoge" on terminal.Programs to print "hoge" on terminal.Programs to print "hoge" on terminal.

Measurement value is smaller, dependence on POSIX is small.Measurement value is smaller, dependence on POSIX is small.Measurement value is smaller, dependence on POSIX is small.Measurement value is smaller, dependence on POSIX is small.Measurement value is smaller, dependence on POSIX is small.

Page 18: Metasepi team meeting #6: "Snatch-driven development"

Jhc output has only 20 undefJhc output has only 20 undefJhc output has only 20 undefJhc output has only 20 undefJhc output has only 20 undef$ nm hs.out | grep "U " U _IO_putc@@GLIBC_2.2.5 U __libc_start_main@@GLIBC_2.2.5 U _setjmp@@GLIBC_2.2.5 U abort@@GLIBC_2.2.5 U ctime@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fflush@@GLIBC_2.2.5 U fprintf@@GLIBC_2.2.5 U fputc@@GLIBC_2.2.5 U fputs@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U fwrite@@GLIBC_2.2.5 U getenv@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U posix_memalign@@GLIBC_2.2.5 U realloc@@GLIBC_2.2.5 U setlocale@@GLIBC_2.2.5 U sysconf@@GLIBC_2.2.5 U times@@GLIBC_2.2.5

$ nm hs.out | grep "U " U _IO_putc@@GLIBC_2.2.5 U __libc_start_main@@GLIBC_2.2.5 U _setjmp@@GLIBC_2.2.5 U abort@@GLIBC_2.2.5 U ctime@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fflush@@GLIBC_2.2.5 U fprintf@@GLIBC_2.2.5 U fputc@@GLIBC_2.2.5 U fputs@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U fwrite@@GLIBC_2.2.5 U getenv@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U posix_memalign@@GLIBC_2.2.5 U realloc@@GLIBC_2.2.5 U setlocale@@GLIBC_2.2.5 U sysconf@@GLIBC_2.2.5 U times@@GLIBC_2.2.5

$ nm hs.out | grep "U " U _IO_putc@@GLIBC_2.2.5 U __libc_start_main@@GLIBC_2.2.5 U _setjmp@@GLIBC_2.2.5 U abort@@GLIBC_2.2.5 U ctime@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fflush@@GLIBC_2.2.5 U fprintf@@GLIBC_2.2.5 U fputc@@GLIBC_2.2.5 U fputs@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U fwrite@@GLIBC_2.2.5 U getenv@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U posix_memalign@@GLIBC_2.2.5 U realloc@@GLIBC_2.2.5 U setlocale@@GLIBC_2.2.5 U sysconf@@GLIBC_2.2.5 U times@@GLIBC_2.2.5

$ nm hs.out | grep "U " U _IO_putc@@GLIBC_2.2.5 U __libc_start_main@@GLIBC_2.2.5 U _setjmp@@GLIBC_2.2.5 U abort@@GLIBC_2.2.5 U ctime@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fflush@@GLIBC_2.2.5 U fprintf@@GLIBC_2.2.5 U fputc@@GLIBC_2.2.5 U fputs@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U fwrite@@GLIBC_2.2.5 U getenv@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U posix_memalign@@GLIBC_2.2.5 U realloc@@GLIBC_2.2.5 U setlocale@@GLIBC_2.2.5 U sysconf@@GLIBC_2.2.5 U times@@GLIBC_2.2.5

$ nm hs.out | grep "U " U _IO_putc@@GLIBC_2.2.5 U __libc_start_main@@GLIBC_2.2.5 U _setjmp@@GLIBC_2.2.5 U abort@@GLIBC_2.2.5 U ctime@@GLIBC_2.2.5 U exit@@GLIBC_2.2.5 U fflush@@GLIBC_2.2.5 U fprintf@@GLIBC_2.2.5 U fputc@@GLIBC_2.2.5 U fputs@@GLIBC_2.2.5 U free@@GLIBC_2.2.5 U fwrite@@GLIBC_2.2.5 U getenv@@GLIBC_2.2.5 U malloc@@GLIBC_2.2.5 U memset@@GLIBC_2.2.5 U posix_memalign@@GLIBC_2.2.5 U realloc@@GLIBC_2.2.5 U setlocale@@GLIBC_2.2.5 U sysconf@@GLIBC_2.2.5 U times@@GLIBC_2.2.5

Page 19: Metasepi team meeting #6: "Snatch-driven development"

Jhc is translator to C languageJhc is translator to C languageJhc is translator to C languageJhc is translator to C languageJhc is translator to C language

Page 20: Metasepi team meeting #6: "Snatch-driven development"

Easy to cross buildEasy to cross buildEasy to cross buildEasy to cross buildEasy to cross build

Page 21: Metasepi team meeting #6: "Snatch-driven development"

Survive burning outSurvive burning outSurvive burning outSurvive burning outSurvive burning out

Let's develop in dogfooding style. (The method is called "Snatch".)Let's develop in dogfooding style. (The method is called "Snatch".)Let's develop in dogfooding style. (The method is called "Snatch".)Let's develop in dogfooding style. (The method is called "Snatch".)Let's develop in dogfooding style. (The method is called "Snatch".)

Page 22: Metasepi team meeting #6: "Snatch-driven development"

[5] How to use Ajhc[5] How to use Ajhc[5] How to use Ajhc[5] How to use Ajhc[5] How to use Ajhc

Case of Ubuntu 12.04 amd64.Case of Ubuntu 12.04 amd64.Case of Ubuntu 12.04 amd64.Case of Ubuntu 12.04 amd64.Case of Ubuntu 12.04 amd64.$ sudo apt-get install haskell-platform libncurses5-dev gcc m4$ cabal update$ export PATH=$HOME/.cabal/bin/:$PATH$ cabal install ajhc$ which ajhc/home/USER/.cabal/bin/ajhc$ echo 'main = print "hoge"' > Hoge.hs$ ajhc Hoge.hs$ ./hs.out"hoge"

$ sudo apt-get install haskell-platform libncurses5-dev gcc m4$ cabal update$ export PATH=$HOME/.cabal/bin/:$PATH$ cabal install ajhc$ which ajhc/home/USER/.cabal/bin/ajhc$ echo 'main = print "hoge"' > Hoge.hs$ ajhc Hoge.hs$ ./hs.out"hoge"

$ sudo apt-get install haskell-platform libncurses5-dev gcc m4$ cabal update$ export PATH=$HOME/.cabal/bin/:$PATH$ cabal install ajhc$ which ajhc/home/USER/.cabal/bin/ajhc$ echo 'main = print "hoge"' > Hoge.hs$ ajhc Hoge.hs$ ./hs.out"hoge"

$ sudo apt-get install haskell-platform libncurses5-dev gcc m4$ cabal update$ export PATH=$HOME/.cabal/bin/:$PATH$ cabal install ajhc$ which ajhc/home/USER/.cabal/bin/ajhc$ echo 'main = print "hoge"' > Hoge.hs$ ajhc Hoge.hs$ ./hs.out"hoge"

$ sudo apt-get install haskell-platform libncurses5-dev gcc m4$ cabal update$ export PATH=$HOME/.cabal/bin/:$PATH$ cabal install ajhc$ which ajhc/home/USER/.cabal/bin/ajhc$ echo 'main = print "hoge"' > Hoge.hs$ ajhc Hoge.hs$ ./hs.out"hoge"

You can use on Windows or Mac OS X.You can use on Windows or Mac OS X.You can use on Windows or Mac OS X.You can use on Windows or Mac OS X.You can use on Windows or Mac OS X.

Page 23: Metasepi team meeting #6: "Snatch-driven development"

Detail of usageDetail of usageDetail of usageDetail of usageDetail of usage

Please read "Ajhc User's Manual".Please read "Ajhc User's Manual".Please read "Ajhc User's Manual".Please read "Ajhc User's Manual".Please read "Ajhc User's Manual".

☆ ajhc.metasepi.org/manual.html☆ ajhc.metasepi.org/manual.html☆ ajhc.metasepi.org/manual.html☆ ajhc.metasepi.org/manual.html☆ ajhc.metasepi.org/manual.html

Also you can read in Japanese.Also you can read in Japanese.Also you can read in Japanese.Also you can read in Japanese.Also you can read in Japanese.

☆ ajhc.metasepi.org/manual_ja.html☆ ajhc.metasepi.org/manual_ja.html☆ ajhc.metasepi.org/manual_ja.html☆ ajhc.metasepi.org/manual_ja.html☆ ajhc.metasepi.org/manual_ja.html

Page 24: Metasepi team meeting #6: "Snatch-driven development"

[6] Case study: Snatch Android[6] Case study: Snatch Android[6] Case study: Snatch Android[6] Case study: Snatch Android[6] Case study: Snatch Android

Let's snatch sample app "native-activity".Let's snatch sample app "native-activity".Let's snatch sample app "native-activity".Let's snatch sample app "native-activity".Let's snatch sample app "native-activity".

developer.android.com/tools/sdk/ndk/developer.android.com/tools/sdk/ndk/developer.android.com/tools/sdk/ndk/developer.android.com/tools/sdk/ndk/developer.android.com/tools/sdk/ndk/

Page 25: Metasepi team meeting #6: "Snatch-driven development"

Snatch planSnatch planSnatch planSnatch planSnatch plan

Page 26: Metasepi team meeting #6: "Snatch-driven development"

[7] Detail of Snatch method[7] Detail of Snatch method[7] Detail of Snatch method[7] Detail of Snatch method[7] Detail of Snatch method

Let's watch Snatch animation on Android NDK Apps. Have popcorn?Let's watch Snatch animation on Android NDK Apps. Have popcorn?Let's watch Snatch animation on Android NDK Apps. Have popcorn?Let's watch Snatch animation on Android NDK Apps. Have popcorn?Let's watch Snatch animation on Android NDK Apps. Have popcorn?

If you want to know more detail, try the following.If you want to know more detail, try the following.If you want to know more detail, try the following.If you want to know more detail, try the following.If you want to know more detail, try the following.$ git clone https://github.com/ajhc/demo-android-ndk.git$ cd demo-android-ndk$ git log -p

$ git clone https://github.com/ajhc/demo-android-ndk.git$ cd demo-android-ndk$ git log -p

$ git clone https://github.com/ajhc/demo-android-ndk.git$ cd demo-android-ndk$ git log -p

$ git clone https://github.com/ajhc/demo-android-ndk.git$ cd demo-android-ndk$ git log -p

$ git clone https://github.com/ajhc/demo-android-ndk.git$ cd demo-android-ndk$ git log -p

Page 27: Metasepi team meeting #6: "Snatch-driven development"

Step0: Before SnatchStep0: Before SnatchStep0: Before SnatchStep0: Before SnatchStep0: Before Snatch// ### native-activity/jni/main.c ###struct saved_state {// --snip--struct engine {// --snip--static int engine_init_display(struct engine* engine) {// --snip--static void engine_draw_frame(struct engine* engine) {// --snip--static void engine_term_display(struct engine* engine) {// --snip--static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {// --snip--static void engine_handle_cmd(struct android_app* app, int32_t cmd) {// --snip--void android_main(struct android_app* state) {// --snip--

// ### native-activity/jni/main.c ###struct saved_state {// --snip--struct engine {// --snip--static int engine_init_display(struct engine* engine) {// --snip--static void engine_draw_frame(struct engine* engine) {// --snip--static void engine_term_display(struct engine* engine) {// --snip--static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {// --snip--static void engine_handle_cmd(struct android_app* app, int32_t cmd) {// --snip--void android_main(struct android_app* state) {// --snip--

// ### native-activity/jni/main.c ###struct saved_state {// --snip--struct engine {// --snip--static int engine_init_display(struct engine* engine) {// --snip--static void engine_draw_frame(struct engine* engine) {// --snip--static void engine_term_display(struct engine* engine) {// --snip--static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {// --snip--static void engine_handle_cmd(struct android_app* app, int32_t cmd) {// --snip--void android_main(struct android_app* state) {// --snip--

// ### native-activity/jni/main.c ###struct saved_state {// --snip--struct engine {// --snip--static int engine_init_display(struct engine* engine) {// --snip--static void engine_draw_frame(struct engine* engine) {// --snip--static void engine_term_display(struct engine* engine) {// --snip--static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {// --snip--static void engine_handle_cmd(struct android_app* app, int32_t cmd) {// --snip--void android_main(struct android_app* state) {// --snip--

// ### native-activity/jni/main.c ###struct saved_state {// --snip--struct engine {// --snip--static int engine_init_display(struct engine* engine) {// --snip--static void engine_draw_frame(struct engine* engine) {// --snip--static void engine_term_display(struct engine* engine) {// --snip--static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {// --snip--static void engine_handle_cmd(struct android_app* app, int32_tcmd) {// --snip--void android_main(struct android_app* state) {// --snip--

Page 28: Metasepi team meeting #6: "Snatch-driven development"

Step1: Call Haskell empty codeStep1: Call Haskell empty codeStep1: Call Haskell empty codeStep1: Call Haskell empty codeStep1: Call Haskell empty code-- ### native-activity/hs_src/Main.hs ###main :: IO ()main = return ()

-- ### native-activity/hs_src/Main.hs ###main :: IO ()main = return ()

-- ### native-activity/hs_src/Main.hs ###main :: IO ()main = return ()

-- ### native-activity/hs_src/Main.hs ###main :: IO ()main = return ()

-- ### native-activity/hs_src/Main.hs ###main :: IO ()main = return ()

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {// --snip-- { // Run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); }// --snip--

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {// --snip-- { // Run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); }// --snip--

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {// --snip-- { // Run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); }// --snip--

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {// --snip-- { // Run Haskell code. int hsargc = 1; char *hsargv = "q"; char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); }// --snip--

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {// --snip-- { // Run Haskell code.

int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp); _amain(); hs_exit(); }// --snip--

Page 29: Metasepi team meeting #6: "Snatch-driven development"

Step2: struct => Storable (cont.)Step2: struct => Storable (cont.)Step2: struct => Storable (cont.)Step2: struct => Storable (cont.)Step2: struct => Storable (cont.)-- ### native-activity/hs_src/AndroidNdk.hs ###{-# LANGUAGE ForeignFunctionInterface #-}module AndroidNdk whereimport Foreign.Storableimport Foreign.C.Typesimport Foreign.Ptr

foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Intforeign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Intforeign import primitive "const.offsetof(struct saved_state, x)" offsetOf_SavedState_x :: Intforeign import primitive "const.offsetof(struct saved_state, y)" offsetOf_SavedState_y :: Int

data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int }

-- ### native-activity/hs_src/AndroidNdk.hs ###{-# LANGUAGE ForeignFunctionInterface #-}module AndroidNdk whereimport Foreign.Storableimport Foreign.C.Typesimport Foreign.Ptr

foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Intforeign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Intforeign import primitive "const.offsetof(struct saved_state, x)" offsetOf_SavedState_x :: Intforeign import primitive "const.offsetof(struct saved_state, y)" offsetOf_SavedState_y :: Int

data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int }

-- ### native-activity/hs_src/AndroidNdk.hs ###{-# LANGUAGE ForeignFunctionInterface #-}module AndroidNdk whereimport Foreign.Storableimport Foreign.C.Typesimport Foreign.Ptr

foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Intforeign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Intforeign import primitive "const.offsetof(struct saved_state, x)" offsetOf_SavedState_x :: Intforeign import primitive "const.offsetof(struct saved_state, y)" offsetOf_SavedState_y :: Int

data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int }

-- ### native-activity/hs_src/AndroidNdk.hs ###{-# LANGUAGE ForeignFunctionInterface #-}module AndroidNdk whereimport Foreign.Storableimport Foreign.C.Typesimport Foreign.Ptr

foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Intforeign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Intforeign import primitive "const.offsetof(struct saved_state, x)" offsetOf_SavedState_x :: Intforeign import primitive "const.offsetof(struct saved_state, y)" offsetOf_SavedState_y :: Int

data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int }

-- ### native-activity/hs_src/AndroidNdk.hs ###{-# LANGUAGE ForeignFunctionInterface #-}module AndroidNdk whereimport Foreign.Storableimport Foreign.C.Typesimport Foreign.Ptr

foreign import primitive "const.sizeof(struct saved_state)" sizeOf_SavedState :: Intforeign import primitive "const.offsetof(struct saved_state, angle)" offsetOf_SavedState_angle :: Intforeign import primitive "const.offsetof(struct saved_state, x)" offsetOf_SavedState_x :: Intforeign import primitive "const.offsetof(struct saved_state, y)" offsetOf_SavedState_y :: Int

data SavedState = SavedState { sStateAngle :: Float , sStateX :: Int , sStateY :: Int }

Page 30: Metasepi team meeting #6: "Snatch-driven development"

Step2: struct => StorableStep2: struct => StorableStep2: struct => StorableStep2: struct => StorableStep2: struct => Storableinstance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y }-- snip --

instance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y }-- snip --

instance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y }-- snip --

instance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y }-- snip --

instance Storable SavedState where sizeOf = const sizeOf_SavedState alignment = sizeOf poke p sstat = do pokeByteOff p offsetOf_SavedState_angle $ sStateAngle sstat pokeByteOff p offsetOf_SavedState_x $ sStateX sstat pokeByteOff p offsetOf_SavedState_y $ sStateY sstat peek p = do angle <- peekByteOff p offsetOf_SavedState_angle x <- peekByteOff p offsetOf_SavedState_x y <- peekByteOff p offsetOf_SavedState_y

return $ SavedState { sStateAngle = angle, sStateX = x, sStateY = y }-- snip --

// ### native-activity/jni/c_extern.h ###struct saved_state { float angle; int32_t x; int32_t y;};

// ### native-activity/jni/c_extern.h ###struct saved_state { float angle; int32_t x; int32_t y;};

// ### native-activity/jni/c_extern.h ###struct saved_state { float angle; int32_t x; int32_t y;};

// ### native-activity/jni/c_extern.h ###struct saved_state { float angle; int32_t x; int32_t y;};

// ### native-activity/jni/c_extern.h ###struct saved_state {

float angle;int32_t x;int32_t y;

};

Page 31: Metasepi team meeting #6: "Snatch-driven development"

Step3: Snatch 1st func (cont.)Step3: Snatch 1st func (cont.)Step3: Snatch 1st func (cont.)Step3: Snatch 1st func (cont.)Step3: Snatch 1st func (cont.)-- ### native-activity/hs_src/AndroidNdk.hs ###newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent ()foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Intforeign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Intforeign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Floatforeign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float

engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO IntengineHandleInput eng event = do t <- c_AInputEvent_getType event if t /= c_AINPUT_EVENT_TYPE_MOTION then return 0 else do enghs <- peek eng let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0 let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs' return 1

-- ### native-activity/hs_src/AndroidNdk.hs ###newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent ()foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Intforeign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Intforeign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Floatforeign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float

engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO IntengineHandleInput eng event = do t <- c_AInputEvent_getType event if t /= c_AINPUT_EVENT_TYPE_MOTION then return 0 else do enghs <- peek eng let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0 let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs' return 1

-- ### native-activity/hs_src/AndroidNdk.hs ###newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent ()foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Intforeign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Intforeign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Floatforeign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float

engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO IntengineHandleInput eng event = do t <- c_AInputEvent_getType event if t /= c_AINPUT_EVENT_TYPE_MOTION then return 0 else do enghs <- peek eng let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0 let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs' return 1

-- ### native-activity/hs_src/AndroidNdk.hs ###newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent ()foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Intforeign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Intforeign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Floatforeign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float

engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO IntengineHandleInput eng event = do t <- c_AInputEvent_getType event if t /= c_AINPUT_EVENT_TYPE_MOTION then return 0 else do enghs <- peek eng let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0 let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs' return 1

-- ### native-activity/hs_src/AndroidNdk.hs ###newtype {-# CTYPE "AInputEvent" #-} AInputEvent = AInputEvent ()foreign import primitive "const.AINPUT_EVENT_TYPE_MOTION" c_AINPUT_EVENT_TYPE_MOTION :: Intforeign import ccall "c_extern.h AInputEvent_getType" c_AInputEvent_getType :: Ptr AInputEvent -> IO Intforeign import ccall "c_extern.h AMotionEvent_getX" c_AMotionEvent_getX :: Ptr AInputEvent -> CSize -> IO Floatforeign import ccall "c_extern.h AMotionEvent_getY" c_AMotionEvent_getY :: Ptr AInputEvent -> CSize -> IO Float

engineHandleInput :: Ptr AndroidEngine -> Ptr AInputEvent -> IO IntengineHandleInput eng event = do t <- c_AInputEvent_getType eventif t /= c_AINPUT_EVENT_TYPE_MOTION then return 0else do enghs <- peek eng

let stat = engState enghs x <- c_AMotionEvent_getX event 0 y <- c_AMotionEvent_getY event 0

let enghs' = enghs { engAnimating = 1, engState = stat { sStateX = truncate x, sStateY = truncate y } } poke eng enghs'

return 1

Page 32: Metasepi team meeting #6: "Snatch-driven development"

Step3: Snatch 1st funcStep3: Snatch 1st funcStep3: Snatch 1st funcStep3: Snatch 1st funcStep3: Snatch 1st func// ### native-activity/jni/main.c ###extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; return engineHandleInput(engine, event);}

// ### native-activity/jni/main.c ###extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; return engineHandleInput(engine, event);}

// ### native-activity/jni/main.c ###extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; return engineHandleInput(engine, event);}

// ### native-activity/jni/main.c ###extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; return engineHandleInput(engine, event);}

// ### native-activity/jni/main.c ###extern int32_t engineHandleInput(struct engine* engine, AInputEvent* event); // Haskell impl

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {struct engine* engine = (struct engine*)app->userData;return engineHandleInput(engine, event);

}

Page 33: Metasepi team meeting #6: "Snatch-driven development"

Step4: Snatch 2nd func (cont.)Step4: Snatch 2nd func (cont.)Step4: Snatch 2nd func (cont.)Step4: Snatch 2nd func (cont.)Step4: Snatch 2nd func (cont.)-- ### native-activity/hs_src/AndroidNdk.hs ###foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int-- snip --foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Intforeign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO ()-- snip --foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int

engineHandleCmd :: Ptr AndroidEngine -> Int -> IO ()engineHandleCmd eng cmd | cmd == c_APP_CMD_SAVE_STATE = do enghs <- peek eng let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs-- snip --

-- ### native-activity/hs_src/AndroidNdk.hs ###foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int-- snip --foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Intforeign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO ()-- snip --foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int

engineHandleCmd :: Ptr AndroidEngine -> Int -> IO ()engineHandleCmd eng cmd | cmd == c_APP_CMD_SAVE_STATE = do enghs <- peek eng let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs-- snip --

-- ### native-activity/hs_src/AndroidNdk.hs ###foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int-- snip --foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Intforeign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO ()-- snip --foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int

engineHandleCmd :: Ptr AndroidEngine -> Int -> IO ()engineHandleCmd eng cmd | cmd == c_APP_CMD_SAVE_STATE = do enghs <- peek eng let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs-- snip --

-- ### native-activity/hs_src/AndroidNdk.hs ###foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int-- snip --foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Intforeign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO ()-- snip --foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int

engineHandleCmd :: Ptr AndroidEngine -> Int -> IO ()engineHandleCmd eng cmd | cmd == c_APP_CMD_SAVE_STATE = do enghs <- peek eng let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs-- snip --

-- ### native-activity/hs_src/AndroidNdk.hs ###foreign import primitive "const.APP_CMD_SAVE_STATE" c_APP_CMD_SAVE_STATE :: Int-- snip --foreign import ccall "c_extern.h engine_init_display" c_engine_init_display :: Ptr AndroidEngine -> IO Intforeign import ccall "c_extern.h engine_draw_frame" c_engine_draw_frame :: Ptr AndroidEngine -> IO ()-- snip --foreign import ccall "c_extern.h ASensorEventQueue_disableSensor" c_ASensorEventQueue_disableSensor :: Ptr ASensorEventQueue -> Ptr ASensor -> IO Int

engineHandleCmd :: Ptr AndroidEngine -> Int -> IO ()engineHandleCmd eng cmd| cmd == c_APP_CMD_SAVE_STATE = do enghs <- peek eng

let app = engApp enghs apphs <- peek app sstat <- malloc poke sstat $ engState enghs-- snip --

Page 34: Metasepi team meeting #6: "Snatch-driven development"

Step4: Snatch 2nd funcStep4: Snatch 2nd funcStep4: Snatch 2nd funcStep4: Snatch 2nd funcStep4: Snatch 2nd func// ### native-activity/jni/c_extern.h ###int engine_init_display(struct engine* engine);void engine_draw_frame(struct engine* engine);void engine_term_display(struct engine* engine);

// ### native-activity/jni/c_extern.h ###int engine_init_display(struct engine* engine);void engine_draw_frame(struct engine* engine);void engine_term_display(struct engine* engine);

// ### native-activity/jni/c_extern.h ###int engine_init_display(struct engine* engine);void engine_draw_frame(struct engine* engine);void engine_term_display(struct engine* engine);

// ### native-activity/jni/c_extern.h ###int engine_init_display(struct engine* engine);void engine_draw_frame(struct engine* engine);void engine_term_display(struct engine* engine);

// ### native-activity/jni/c_extern.h ###int engine_init_display(struct engine* engine);void engine_draw_frame(struct engine* engine);void engine_term_display(struct engine* engine);

// ### native-activity/jni/main.c ###extern void engineHandleCmd(struct engine* engine, int32_t cmd);

static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; engineHandleCmd(engine, cmd);}

// ### native-activity/jni/main.c ###extern void engineHandleCmd(struct engine* engine, int32_t cmd);

static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; engineHandleCmd(engine, cmd);}

// ### native-activity/jni/main.c ###extern void engineHandleCmd(struct engine* engine, int32_t cmd);

static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; engineHandleCmd(engine, cmd);}

// ### native-activity/jni/main.c ###extern void engineHandleCmd(struct engine* engine, int32_t cmd);

static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; engineHandleCmd(engine, cmd);}

// ### native-activity/jni/main.c ###extern void engineHandleCmd(struct engine* engine, int32_t cmd);

static void engine_handle_cmd(struct android_app* app, int32_tcmd) {struct engine* engine = (struct engine*)app->userData;

engineHandleCmd(engine, cmd);}

Page 35: Metasepi team meeting #6: "Snatch-driven development"

Step5: Snatch remaining funcsStep5: Snatch remaining funcsStep5: Snatch remaining funcsStep5: Snatch remaining funcsStep5: Snatch remaining funcs

Snatch the following functions.Snatch the following functions.Snatch the following functions.Snatch the following functions.Snatch the following functions.

☆ engine_init_display()☆ engine_init_display()☆ engine_init_display()☆ engine_init_display()☆ engine_init_display()

☆ engine_draw_frame()☆ engine_draw_frame()☆ engine_draw_frame()☆ engine_draw_frame()☆ engine_draw_frame()

☆ engine_term_display()☆ engine_term_display()☆ engine_term_display()☆ engine_term_display()☆ engine_term_display()

Page 36: Metasepi team meeting #6: "Snatch-driven development"

Step6: Snatch main func (cont.)Step6: Snatch main func (cont.)Step6: Snatch main func (cont.)Step6: Snatch main func (cont.)Step6: Snatch main func (cont.)-- ### native-activity/hs_src/Main.hs ###main :: IO () -- Dummymain = return ()

foreign export ccall "androidMain" androidMain :: Ptr AndroidApp -> IO ()androidMain :: Ptr AndroidApp -> IO () -- True mainandroidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek app let apphs' = apphs { appUserData = eng, appOnAppCmd = p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng -- Prepare to monitor accelerometer sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETER let looper = appLooper apphs' when (ss_p /= nullPtr) $ do ss <- peek ss_p-- snip --

-- ### native-activity/hs_src/Main.hs ###main :: IO () -- Dummymain = return ()

foreign export ccall "androidMain" androidMain :: Ptr AndroidApp -> IO ()androidMain :: Ptr AndroidApp -> IO () -- True mainandroidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek app let apphs' = apphs { appUserData = eng, appOnAppCmd = p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng -- Prepare to monitor accelerometer sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETER let looper = appLooper apphs' when (ss_p /= nullPtr) $ do ss <- peek ss_p-- snip --

-- ### native-activity/hs_src/Main.hs ###main :: IO () -- Dummymain = return ()

foreign export ccall "androidMain" androidMain :: Ptr AndroidApp -> IO ()androidMain :: Ptr AndroidApp -> IO () -- True mainandroidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek app let apphs' = apphs { appUserData = eng, appOnAppCmd = p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng -- Prepare to monitor accelerometer sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETER let looper = appLooper apphs' when (ss_p /= nullPtr) $ do ss <- peek ss_p-- snip --

-- ### native-activity/hs_src/Main.hs ###main :: IO () -- Dummymain = return ()

foreign export ccall "androidMain" androidMain :: Ptr AndroidApp -> IO ()androidMain :: Ptr AndroidApp -> IO () -- True mainandroidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek app let apphs' = apphs { appUserData = eng, appOnAppCmd = p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng -- Prepare to monitor accelerometer sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETER let looper = appLooper apphs' when (ss_p /= nullPtr) $ do ss <- peek ss_p-- snip --

-- ### native-activity/hs_src/Main.hs ###main :: IO () -- Dummymain = return ()

foreign export ccall "androidMain" androidMain :: Ptr AndroidApp -> IO ()androidMain :: Ptr AndroidApp -> IO () -- True mainandroidMain app = do eng <- malloc poke eng defaultAndroidEngine apphs <- peek applet apphs' = apphs { appUserData = eng, appOnAppCmd =

p_engineHandleCmd , appOnInputEvent = p_engineHandleInput } poke app apphs' enghs <- peek eng-- Prepare to monitor accelerometer

sManage <- c_ASensorManager_getInstance accel <- c_ASensorManager_getDefaultSensor sManage c_ASENSOR_TYPE_ACCELEROMETERlet looper = appLooper apphs'

when (ss_p /= nullPtr) $ do ss <- peek ss_p-- snip --

Page 37: Metasepi team meeting #6: "Snatch-driven development"

Step6: Snatch main funcStep6: Snatch main funcStep6: Snatch main funcStep6: Snatch main funcStep6: Snatch main func// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {

app_dummy(); // Make sure glue isn't stripped.

// Init & run Haskell code.int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp);androidMain(state);hs_exit();

}

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {

app_dummy(); // Make sure glue isn't stripped.

// Init & run Haskell code.int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp);androidMain(state);hs_exit();

}

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {

app_dummy(); // Make sure glue isn't stripped.

// Init & run Haskell code.int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp);androidMain(state);hs_exit();

}

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {

app_dummy(); // Make sure glue isn't stripped.

// Init & run Haskell code.int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp);androidMain(state);hs_exit();

}

// ### native-activity/jni/main.c ###void android_main(struct android_app* state) {

app_dummy(); // Make sure glue isn't stripped.

// Init & run Haskell code.int hsargc = 1;char *hsargv = "q";char **hsargvp = &hsargv;

hs_init(&hsargc, &hsargvp);androidMain(state);hs_exit();

}

Page 38: Metasepi team meeting #6: "Snatch-driven development"

Step7: Get clear => GOALStep7: Get clear => GOALStep7: Get clear => GOALStep7: Get clear => GOALStep7: Get clear => GOAL

We are in the strong typed world.We are in the strong typed world.We are in the strong typed world.We are in the strong typed world.We are in the strong typed world.

Haskell's turn, now!Haskell's turn, now!Haskell's turn, now!Haskell's turn, now!Haskell's turn, now!

>>>>>

Page 39: Metasepi team meeting #6: "Snatch-driven development"

PR: Call For ArticlesPR: Call For ArticlesPR: Call For ArticlesPR: Call For ArticlesPR: Call For Articles

☆ http://www.paraiso-lang.org/ikmsm/☆ http://www.paraiso-lang.org/ikmsm/☆ http://www.paraiso-lang.org/ikmsm/☆ http://www.paraiso-lang.org/ikmsm/☆ http://www.paraiso-lang.org/ikmsm/

☆ Fanzine of functional programming.☆ Fanzine of functional programming.☆ Fanzine of functional programming.☆ Fanzine of functional programming.☆ Fanzine of functional programming.

☆ About Haskell or OCaml or . . .☆ About Haskell or OCaml or . . .☆ About Haskell or OCaml or . . .☆ About Haskell or OCaml or . . .☆ About Haskell or OCaml or . . .

☆ Article about Ajhc in C84 book.☆ Article about Ajhc in C84 book.☆ Article about Ajhc in C84 book.☆ Article about Ajhc in C84 book.☆ Article about Ajhc in C84 book.

☆ Call me if you read it!☆ Call me if you read it!☆ Call me if you read it!☆ Call me if you read it!☆ Call me if you read it!http://www.paraiso-lang.org/ikmsm/books/c85.htmlhttp://www.paraiso-lang.org/ikmsm/books/c85.htmlhttp://www.paraiso-lang.org/ikmsm/books/c85.htmlhttp://www.paraiso-lang.org/ikmsm/books/c85.htmlhttp://www.paraiso-lang.org/ikmsm/books/c85.html

>>>>>