123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="generator" content="Asciidoctor 1.5.4">
- <title>Application States</title>
- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
- <style>
- /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
- /* Remove comment around @import statement below when using as a custom stylesheet */
- /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
- article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
- audio,canvas,video{display:inline-block}
- audio:not([controls]){display:none;height:0}
- [hidden],template{display:none}
- script{display:none!important}
- html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
- body{margin:0}
- a{background:transparent}
- a:focus{outline:thin dotted}
- a:active,a:hover{outline:0}
- h1{font-size:2em;margin:.67em 0}
- abbr[title]{border-bottom:1px dotted}
- b,strong{font-weight:bold}
- dfn{font-style:italic}
- hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
- mark{background:#ff0;color:#000}
- code,kbd,pre,samp{font-family:monospace;font-size:1em}
- pre{white-space:pre-wrap}
- q{quotes:"\201C" "\201D" "\2018" "\2019"}
- small{font-size:80%}
- sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
- sup{top:-.5em}
- sub{bottom:-.25em}
- img{border:0}
- svg:not(:root){overflow:hidden}
- figure{margin:0}
- fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
- legend{border:0;padding:0}
- button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
- button,input{line-height:normal}
- button,select{text-transform:none}
- button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
- button[disabled],html input[disabled]{cursor:default}
- input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
- input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
- input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
- button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
- textarea{overflow:auto;vertical-align:top}
- table{border-collapse:collapse;border-spacing:0}
- *,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
- html,body{font-size:100%}
- body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
- a:hover{cursor:pointer}
- img,object,embed{max-width:100%;height:auto}
- object,embed{height:100%}
- img{-ms-interpolation-mode:bicubic}
- .left{float:left!important}
- .right{float:right!important}
- .text-left{text-align:left!important}
- .text-right{text-align:right!important}
- .text-center{text-align:center!important}
- .text-justify{text-align:justify!important}
- .hide{display:none}
- body{-webkit-font-smoothing:antialiased}
- img,object,svg{display:inline-block;vertical-align:middle}
- textarea{height:auto;min-height:50px}
- select{width:100%}
- .center{margin-left:auto;margin-right:auto}
- .spread{width:100%}
- p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
- .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
- div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
- a{color:#2156a5;text-decoration:underline;line-height:inherit}
- a:hover,a:focus{color:#1d4b8f}
- a img{border:none}
- p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
- p aside{font-size:.875em;line-height:1.35;font-style:italic}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
- h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
- h1{font-size:2.125em}
- h2{font-size:1.6875em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
- h4,h5{font-size:1.125em}
- h6{font-size:1em}
- hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
- em,i{font-style:italic;line-height:inherit}
- strong,b{font-weight:bold;line-height:inherit}
- small{font-size:60%;line-height:inherit}
- code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
- ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
- ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
- ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
- ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
- ul.square{list-style-type:square}
- ul.circle{list-style-type:circle}
- ul.disc{list-style-type:disc}
- ul.no-bullet{list-style:none}
- ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
- dl dt{margin-bottom:.3125em;font-weight:bold}
- dl dd{margin-bottom:1.25em}
- abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
- abbr{text-transform:none}
- blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
- blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
- blockquote cite:before{content:"\2014 \0020"}
- blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
- blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
- @media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
- h1{font-size:2.75em}
- h2{font-size:2.3125em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
- h4{font-size:1.4375em}}
- table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
- table thead,table tfoot{background:#f7f8f7;font-weight:bold}
- table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
- table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
- table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
- table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
- body{tab-size:4}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
- h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
- .clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
- .clearfix:after,.float-group:after{clear:both}
- *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
- pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
- .keyseq{color:rgba(51,51,51,.8)}
- kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
- .keyseq kbd:first-child{margin-left:0}
- .keyseq kbd:last-child{margin-right:0}
- .menuseq,.menu{color:rgba(0,0,0,.8)}
- b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
- b.button:before{content:"[";padding:0 3px 0 2px}
- b.button:after{content:"]";padding:0 2px 0 3px}
- p a>code:hover{color:rgba(0,0,0,.9)}
- #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
- #header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
- #header:after,#content:after,#footnotes:after,#footer:after{clear:both}
- #content{margin-top:1.25em}
- #content:before{content:none}
- #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
- #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
- #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
- #header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
- #header .details span:first-child{margin-left:-.125em}
- #header .details span.email a{color:rgba(0,0,0,.85)}
- #header .details br{display:none}
- #header .details br+span:before{content:"\00a0\2013\00a0"}
- #header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
- #header .details br+span#revremark:before{content:"\00a0|\00a0"}
- #header #revnumber{text-transform:capitalize}
- #header #revnumber:after{content:"\00a0"}
- #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
- #toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
- #toc>ul{margin-left:.125em}
- #toc ul.sectlevel0>li>a{font-style:italic}
- #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
- #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
- #toc li{line-height:1.3334;margin-top:.3334em}
- #toc a{text-decoration:none}
- #toc a:active{text-decoration:underline}
- #toctitle{color:#7a2518;font-size:1.2em}
- @media only screen and (min-width:768px){#toctitle{font-size:1.375em}
- body.toc2{padding-left:15em;padding-right:0}
- #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
- #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
- #toc.toc2>ul{font-size:.9em;margin-bottom:0}
- #toc.toc2 ul ul{margin-left:0;padding-left:1em}
- #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
- body.toc2.toc-right{padding-left:0;padding-right:15em}
- body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
- @media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
- #toc.toc2{width:20em}
- #toc.toc2 #toctitle{font-size:1.375em}
- #toc.toc2>ul{font-size:.95em}
- #toc.toc2 ul ul{padding-left:1.25em}
- body.toc2.toc-right{padding-left:0;padding-right:20em}}
- #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- #content #toc>:first-child{margin-top:0}
- #content #toc>:last-child{margin-bottom:0}
- #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
- #footer-text{color:rgba(255,255,255,.8);line-height:1.44}
- .sect1{padding-bottom:.625em}
- @media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
- .sect1+.sect1{border-top:1px solid #efefed}
- #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
- #content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
- #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
- #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
- #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
- .audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
- .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
- table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
- .paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
- table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
- .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
- .admonitionblock>table td.icon{text-align:center;width:80px}
- .admonitionblock>table td.icon img{max-width:none}
- .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
- .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
- .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
- .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
- .exampleblock>.content>:first-child{margin-top:0}
- .exampleblock>.content>:last-child{margin-bottom:0}
- .sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- .sidebarblock>:first-child{margin-top:0}
- .sidebarblock>:last-child{margin-bottom:0}
- .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
- .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
- .literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
- .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
- .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
- .literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
- @media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
- @media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
- .literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
- .listingblock pre.highlightjs{padding:0}
- .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
- .listingblock pre.prettyprint{border-width:0}
- .listingblock>.content{position:relative}
- .listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
- .listingblock:hover code[data-lang]:before{display:block}
- .listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
- .listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
- table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
- table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
- table.pyhltable td.code{padding-left:.75em;padding-right:0}
- pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
- pre.pygments .lineno{display:inline-block;margin-right:.25em}
- table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
- .quoteblock{margin:0 1em 1.25em 1.5em;display:table}
- .quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
- .quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
- .quoteblock blockquote{margin:0;padding:0;border:0}
- .quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
- .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
- .quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
- .quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
- .quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
- .quoteblock .quoteblock blockquote:before{display:none}
- .verseblock{margin:0 1em 1.25em 1em}
- .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
- .verseblock pre strong{font-weight:400}
- .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
- .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
- .quoteblock .attribution br,.verseblock .attribution br{display:none}
- .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
- .quoteblock.abstract{margin:0 0 1.25em 0;display:block}
- .quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
- .quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
- table.tableblock{max-width:100%;border-collapse:separate}
- table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
- table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
- table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
- table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
- table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
- table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
- table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
- table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
- table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
- table.frame-all{border-width:1px}
- table.frame-sides{border-width:0 1px}
- table.frame-topbot{border-width:1px 0}
- th.halign-left,td.halign-left{text-align:left}
- th.halign-right,td.halign-right{text-align:right}
- th.halign-center,td.halign-center{text-align:center}
- th.valign-top,td.valign-top{vertical-align:top}
- th.valign-bottom,td.valign-bottom{vertical-align:bottom}
- th.valign-middle,td.valign-middle{vertical-align:middle}
- table thead th,table tfoot th{font-weight:bold}
- tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
- tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
- p.tableblock>code:only-child{background:none;padding:0}
- p.tableblock{font-size:1em}
- td>div.verse{white-space:pre}
- ol{margin-left:1.75em}
- ul li ol{margin-left:1.5em}
- dl dd{margin-left:1.125em}
- dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
- ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
- ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
- ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
- ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
- ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
- ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
- ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
- ul.inline>li>*{display:block}
- .unstyled dl dt{font-weight:400;font-style:normal}
- ol.arabic{list-style-type:decimal}
- ol.decimal{list-style-type:decimal-leading-zero}
- ol.loweralpha{list-style-type:lower-alpha}
- ol.upperalpha{list-style-type:upper-alpha}
- ol.lowerroman{list-style-type:lower-roman}
- ol.upperroman{list-style-type:upper-roman}
- ol.lowergreek{list-style-type:lower-greek}
- .hdlist>table,.colist>table{border:0;background:none}
- .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
- td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
- td.hdlist1{font-weight:bold;padding-bottom:1.25em}
- .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
- .colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
- .colist>table tr>td:last-of-type{padding:.25em 0}
- .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
- .imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
- .imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
- .imageblock>.title{margin-bottom:0}
- .imageblock.thumb,.imageblock.th{border-width:6px}
- .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
- .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
- .image.left{margin-right:.625em}
- .image.right{margin-left:.625em}
- a.image{text-decoration:none;display:inline-block}
- a.image object{pointer-events:none}
- sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
- sup.footnote a,sup.footnoteref a{text-decoration:none}
- sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
- #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
- #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
- #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
- #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
- #footnotes .footnote:last-of-type{margin-bottom:0}
- #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
- .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
- .gist .file-data>table td.line-data{width:99%}
- div.unbreakable{page-break-inside:avoid}
- .big{font-size:larger}
- .small{font-size:smaller}
- .underline{text-decoration:underline}
- .overline{text-decoration:overline}
- .line-through{text-decoration:line-through}
- .aqua{color:#00bfbf}
- .aqua-background{background-color:#00fafa}
- .black{color:#000}
- .black-background{background-color:#000}
- .blue{color:#0000bf}
- .blue-background{background-color:#0000fa}
- .fuchsia{color:#bf00bf}
- .fuchsia-background{background-color:#fa00fa}
- .gray{color:#606060}
- .gray-background{background-color:#7d7d7d}
- .green{color:#006000}
- .green-background{background-color:#007d00}
- .lime{color:#00bf00}
- .lime-background{background-color:#00fa00}
- .maroon{color:#600000}
- .maroon-background{background-color:#7d0000}
- .navy{color:#000060}
- .navy-background{background-color:#00007d}
- .olive{color:#606000}
- .olive-background{background-color:#7d7d00}
- .purple{color:#600060}
- .purple-background{background-color:#7d007d}
- .red{color:#bf0000}
- .red-background{background-color:#fa0000}
- .silver{color:#909090}
- .silver-background{background-color:#bcbcbc}
- .teal{color:#006060}
- .teal-background{background-color:#007d7d}
- .white{color:#bfbfbf}
- .white-background{background-color:#fafafa}
- .yellow{color:#bfbf00}
- .yellow-background{background-color:#fafa00}
- span.icon>.fa{cursor:default}
- .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
- .admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
- .admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
- .admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
- .admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
- .admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
- .conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
- .conum[data-value] *{color:#fff!important}
- .conum[data-value]+b{display:none}
- .conum[data-value]:after{content:attr(data-value)}
- pre .conum[data-value]{position:relative;top:-.125em}
- b.conum *{color:inherit!important}
- .conum:not([data-value]):empty{display:none}
- dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
- h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
- p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
- p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
- p{margin-bottom:1.25rem}
- .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
- .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
- .print-only{display:none!important}
- @media print{@page{margin:1.25cm .75cm}
- *{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
- a{color:inherit!important;text-decoration:underline!important}
- a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
- a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
- abbr[title]:after{content:" (" attr(title) ")"}
- pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
- thead{display:table-header-group}
- svg{max-width:100%}
- p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
- h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
- #toc,.sidebarblock,.exampleblock>.content{background:none!important}
- #toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
- .sect1{padding-bottom:0!important}
- .sect1+.sect1{border:0!important}
- #header>h1:first-child{margin-top:1.25rem}
- body.book #header{text-align:center}
- body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
- body.book #header .details{border:0!important;display:block;padding:0!important}
- body.book #header .details span:first-child{margin-left:0!important}
- body.book #header .details br{display:block}
- body.book #header .details br+span:before{content:none!important}
- body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
- body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
- .listingblock code[data-lang]:before{display:block}
- #footer{background:none!important;padding:0 .9375em}
- #footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
- .hide-on-print{display:none!important}
- .print-only{display:block!important}
- .hide-for-print{display:none!important}
- .show-for-print{display:inherit!important}}
- </style>
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
- <style>
- /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
- /*pre.CodeRay {background-color:#f7f7f8;}*/
- .CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
- .CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
- .CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
- table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
- table.CodeRay td{vertical-align: top;line-height:1.45}
- table.CodeRay td.line-numbers{text-align:right}
- table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
- table.CodeRay td.code{padding:0 0 0 .5em}
- table.CodeRay td.code>pre{padding:0}
- .CodeRay .debug{color:#fff !important;background:#000080 !important}
- .CodeRay .annotation{color:#007}
- .CodeRay .attribute-name{color:#000080}
- .CodeRay .attribute-value{color:#700}
- .CodeRay .binary{color:#509}
- .CodeRay .comment{color:#998;font-style:italic}
- .CodeRay .char{color:#04d}
- .CodeRay .char .content{color:#04d}
- .CodeRay .char .delimiter{color:#039}
- .CodeRay .class{color:#458;font-weight:bold}
- .CodeRay .complex{color:#a08}
- .CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
- .CodeRay .color{color:#099}
- .CodeRay .class-variable{color:#369}
- .CodeRay .decorator{color:#b0b}
- .CodeRay .definition{color:#099}
- .CodeRay .delimiter{color:#000}
- .CodeRay .doc{color:#970}
- .CodeRay .doctype{color:#34b}
- .CodeRay .doc-string{color:#d42}
- .CodeRay .escape{color:#666}
- .CodeRay .entity{color:#800}
- .CodeRay .error{color:#808}
- .CodeRay .exception{color:inherit}
- .CodeRay .filename{color:#099}
- .CodeRay .function{color:#900;font-weight:bold}
- .CodeRay .global-variable{color:#008080}
- .CodeRay .hex{color:#058}
- .CodeRay .integer,.CodeRay .float{color:#099}
- .CodeRay .include{color:#555}
- .CodeRay .inline{color:#000}
- .CodeRay .inline .inline{background:#ccc}
- .CodeRay .inline .inline .inline{background:#bbb}
- .CodeRay .inline .inline-delimiter{color:#d14}
- .CodeRay .inline-delimiter{color:#d14}
- .CodeRay .important{color:#555;font-weight:bold}
- .CodeRay .interpreted{color:#b2b}
- .CodeRay .instance-variable{color:#008080}
- .CodeRay .label{color:#970}
- .CodeRay .local-variable{color:#963}
- .CodeRay .octal{color:#40e}
- .CodeRay .predefined{color:#369}
- .CodeRay .preprocessor{color:#579}
- .CodeRay .pseudo-class{color:#555}
- .CodeRay .directive{font-weight:bold}
- .CodeRay .type{font-weight:bold}
- .CodeRay .predefined-type{color:inherit}
- .CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
- .CodeRay .key{color:#808}
- .CodeRay .key .delimiter{color:#606}
- .CodeRay .key .char{color:#80f}
- .CodeRay .value{color:#088}
- .CodeRay .regexp .delimiter{color:#808}
- .CodeRay .regexp .content{color:#808}
- .CodeRay .regexp .modifier{color:#808}
- .CodeRay .regexp .char{color:#d14}
- .CodeRay .regexp .function{color:#404;font-weight:bold}
- .CodeRay .string{color:#d20}
- .CodeRay .string .string .string{background:#ffd0d0}
- .CodeRay .string .content{color:#d14}
- .CodeRay .string .char{color:#d14}
- .CodeRay .string .delimiter{color:#d14}
- .CodeRay .shell{color:#d14}
- .CodeRay .shell .delimiter{color:#d14}
- .CodeRay .symbol{color:#990073}
- .CodeRay .symbol .content{color:#a60}
- .CodeRay .symbol .delimiter{color:#630}
- .CodeRay .tag{color:#008080}
- .CodeRay .tag-special{color:#d70}
- .CodeRay .variable{color:#036}
- .CodeRay .insert{background:#afa}
- .CodeRay .delete{background:#faa}
- .CodeRay .change{color:#aaf;background:#007}
- .CodeRay .head{color:#f8f;background:#505}
- .CodeRay .insert .insert{color:#080}
- .CodeRay .delete .delete{color:#800}
- .CodeRay .change .change{color:#66f}
- .CodeRay .head .head{color:#f4f}
- </style>
- </head>
- <body class="article toc2 toc-left">
- <div id="header">
- <h1>Application States</h1>
- <div class="details">
- <span id="author" class="author"></span><br>
- <span id="revnumber">version ,</span>
- <span id="revdate">2016/03/17 20:48</span>
- </div>
- <div id="toc" class="toc2">
- <div id="toctitle">Table of Contents</div>
- <ul class="sectlevel1">
- <li><a href="#overview">Overview</a>
- <ul class="sectlevel2">
- <li><a href="#use-case-examples">Use Case Examples</a></li>
- <li><a href="#supported-features">Supported Features</a></li>
- <li><a href="#usage">Usage</a></li>
- <li><a href="#code-samples">Code Samples</a></li>
- </ul>
- </li>
- <li><a href="#appstate">AppState</a></li>
- <li><a href="#abstractappstate">AbstractAppState</a></li>
- <li><a href="#pausing-and-unpausing">Pausing and Unpausing</a></li>
- <li><a href="#appstatemanager">AppStateManager</a></li>
- <li><a href="#best-practices">Best Practices</a>
- <ul class="sectlevel2">
- <li><a href="#communication-among-appstates">Communication Among AppStates</a></li>
- <li><a href="#initialize-familiar-class-fields">Initialize Familiar Class Fields</a></li>
- </ul>
- </li>
- </ul>
- </div>
- </div>
- <div id="content">
- <div id="preamble">
- <div class="sectionbody">
- <div class="paragraph">
- <p>The <code>com.jme3.app.state.AppState</code> class is a customizable jME3 interface that allows you to control the global game logic, the overall game mechanics. (To control the behaviour of a Spatial, see <a href="../../jme3/advanced/custom_controls.html">Custom Controls</a> instead. Controls and AppStates can be used together.)</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="overview">Overview</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="use-case-examples">Use Case Examples</h3>
- <div class="paragraph">
- <p>There are situations during your game development where you think:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Mouse and key inputs are handled differently in-game versus in the main menu. Can I group a set of input handler settings, and activate and deactivate them all in one step?</p>
- </li>
- <li>
- <p>I have the in-game scene, and a character editor, and a Captain’s Quarters screen. Can I group a set of nodes and behaviours, and swap them in and out in one step?</p>
- </li>
- <li>
- <p>When I pause the game, I want the character’s “idle animation to continue, but all other loops and game events should stop. How do I define what happens when the game is paused/unpaused?</p>
- </li>
- <li>
- <p>I have a conditional block that takes up a lot of space in my simpleUpdate() loop. Can I wrap up this block of code, and switch it on and off in one step?</p>
- </li>
- <li>
- <p>Can I package everything that belongs in-game, and everything that belongs to the menu screen, and switch between these two “big states in one step?</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>You can! This is what AppStates are there for. An AppState class is subset of (or an extension to) your application. Every AppState class has access to all fields in your main application (AssetManager, ViewPort, StateManager, InputManager, RootNode, GuiNode, etc) and hooks into the main update loop. An AppState can contain:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>a subset of class fields, functions, methods (game state data and accessors),</p>
- </li>
- <li>
- <p>a subset of <abbr title="Graphical User Interface">GUI</abbr> elements and their listeners,</p>
- </li>
- <li>
- <p>a subset of input handlers and mappings,</p>
- </li>
- <li>
- <p>a subset of nodes that you load and attach to the rootNode,</p>
- </li>
- <li>
- <p>a subset of conditional actions that you branch to in the simpleUpdate() loop,</p>
- </li>
- <li>
- <p>a subset of other AppStates and Controls</p>
- </li>
- <li>
- <p>… or combinations thereof.</p>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect2">
- <h3 id="supported-features">Supported Features</h3>
- <div class="paragraph">
- <p>Each AppState lets you define what happens to it in the following situations:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><strong>The AppState is initialized:</strong> You load and initialize game data, InputHandlers, AppStates and Controls and attach nodes.<br>
- The AppState executes its own simpleInitApp() method when it is attached, so to speak.</p>
- </li>
- <li>
- <p><strong>The AppState has been enabled (unpaused):</strong> This toggles a boolean isEnabled() to true. Here you attach nodes and listeners that should become active while it’s running.</p>
- </li>
- <li>
- <p><strong>While the AppState is running/paused:</strong> You can poll isEnabled() to define paused and unpaused game behaviour in the update() loop. In update(), you poll and modify the game state, modify the scene graph, and trigger events. Test if <code>!isEnabled()</code>, and write code that skips the running sections of this AppState’s <code>update()</code> loop.<br>
- Each AppState has its own update loop, which hooks into the main simpleUpdate() loop (callback).</p>
- </li>
- <li>
- <p><strong>The AppState has been disabled (paused):</strong> This toggles a boolean isEnabled() to false. Here you switch all objects to their specific “paused behaviour.</p>
- </li>
- <li>
- <p><strong>The AppState is cleaned up:</strong> Here you decide what happens when the AppState is detached. Save this AppState’s game state, unregister Controls and InputHandlers, detach related AppStates, detach nodes from the rootNode, etc.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p><abbr title="Graphical User Interface">GUI</abbr><abbr title="Graphical User Interface">GUI</abbr></p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="usage">Usage</h3>
- <div class="paragraph">
- <p>To implement game logic:</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>Create one AbstractAppState instance for each set of game mechanics.</p>
- </li>
- <li>
- <p>Implement game behaviour in the AppState’s update() method.</p>
- <div class="ulist">
- <ul>
- <li>
- <p>You can pass custom data as arguments in the constructor.</p>
- </li>
- <li>
- <p>The AppState has access to everything inside the app’s scope via the Application <code>app</code> object.</p>
- </li>
- </ul>
- </div>
- </li>
- <li>
- <p>Create and attach the AppState to the AppStateManager (<code>stateManager.attach(myAppState);</code>) and initialize it.</p>
- </li>
- <li>
- <p>Enable and disable (unpause and pause) the AppStates that you need during the game.</p>
- </li>
- <li>
- <p>Detach the AppState from the AppStateManager (<code>stateManager.detach(myAppState);</code>) and clean it up.</p>
- </li>
- </ol>
- </div>
- <div class="paragraph">
- <p>When you add several AppStates to one Application and activate them, their initialize() methods and update() loops are executed in the order in which the AppStates were added to the AppStateManager.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="code-samples">Code Samples</h3>
- <div class="paragraph">
- <p>JME3 comes with a BulletAppState that implements Physical behaviour (using the jBullet library). You, for example, could write an Artificial Intelligence AppState to control all your enemy units. Existing examples in the code base include:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-bullet/src/common/java/com/jme3/bullet/BulletAppState.java">BulletAppState</a> controls physical behaviour in PhysicsControl’ed Spatials.</p>
- </li>
- <li>
- <p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/app/state/TestAppStates.java">TestAppStates.java</a> an example of a custom AppState</p>
- <div class="ulist">
- <ul>
- <li>
- <p><a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/app/state/RootNodeState.java">RootNodeState.java</a></p>
- </li>
- </ul>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="appstate">AppState</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The AppState interface lets you initialize sets of objects, and hook a set of continuously executing code into the main loop.</p>
- </div>
- <table class="tableblock frame-all grid-all spread">
- <colgroup>
- <col style="width: 50%;">
- <col style="width: 50%;">
- </colgroup>
- <thead>
- <tr>
- <th class="tableblock halign-left valign-top">AppState Method</th>
- <th class="tableblock halign-left valign-top">Usage</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>initialize(asm,app)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>When this AppState is added to the game, the RenderThread initializes the AppState and then calls this method. You can modify the scene graph from here (e.g. attach nodes). To get access to the main app, call:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="local-variable">super</span>.initialize(stateManager, app);
- <span class="local-variable">this</span>.app = (SimpleApplication) app;</code></pre>
- </div>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>cleanup()</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>This method is executed after you remove the AppState from the game. Here you implement clean-up code for when this state is detached. You can modify the scene graph from here (e.g. detach nodes).</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>update(float tpf)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Here you implement the behaviour that you want to hook into the simpleUpdate() loop while this state is attached to the game. You can modify the scene graph from here.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>isInitialized()</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Your implementations of this interface should return the correct respective boolean value. (See AbstractAppState)</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>setEnabled(true)<br>
- setEnabled(false)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Temporarily enables or disables an AppState. (See AbstractAppState)</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>isEnabled()</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Test whether AppState is enabled or disabled. Your implementation should consider the boolean. (See AbstractAppState)</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>stateAttached(asm)<br>
- stateDetached(asm)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>The AppState knows when it is attached to, or detached from, the AppStateManager, and triggers these two methods. Don’t modify the scene graph from here! (Typically not used.)</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>render(RenderManager rm)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Renders the state, plus your optional customizations. (Typically not used.)</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>postRender()</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Called after all rendering commands are flushed, including your optional customizations. (Typically not used.)</p>
- </div></div></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="sect1">
- <h2 id="abstractappstate">AbstractAppState</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The <a href="https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-core/src/main/java/com/jme3/app/state/AbstractAppState.java">AbstractAppState</a> class already implements some common methods (<code>isInitialized(), setEnabled(), isEnabled()</code>) and makes creation of custom AppStates a bit easier. We recommend you extend AbstractAppState and override the remaining AppState methods: <code>initialize(), setEnabled(), cleanup()</code>.</p>
- </div>
- <div class="paragraph">
- <p>Definition:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">MyAppState</span> <span class="directive">extends</span> AbstractAppState {
- <span class="directive">private</span> SimpleApplication app;
- <span class="directive">private</span> Node x = <span class="keyword">new</span> Node(<span class="string"><span class="delimiter">"</span><span class="content">x</span><span class="delimiter">"</span></span>); <span class="comment">// some custom class fields...</span>
- <span class="directive">public</span> Node getX(){ <span class="keyword">return</span> x; } <span class="comment">// some custom methods...</span>
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> initialize(AppStateManager stateManager, Application app) {
- <span class="local-variable">super</span>.initialize(stateManager, app);
- <span class="local-variable">this</span>.app = (SimpleApplication)app; <span class="comment">// cast to a more specific class</span>
- <span class="comment">// init stuff that is independent of whether state is PAUSED or RUNNING</span>
- <span class="local-variable">this</span>.app.getRootNode().attachChild(getX()); <span class="comment">// modify scene graph...</span>
- <span class="local-variable">this</span>.app.doSomething(); <span class="comment">// call custom methods...</span>
- }
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> cleanup() {
- <span class="local-variable">super</span>.cleanup();
- <span class="comment">// unregister all my listeners, detach all my nodes, etc...</span>
- <span class="local-variable">this</span>.app.getRootNode().detachChild(getX()); <span class="comment">// modify scene graph...</span>
- <span class="local-variable">this</span>.app.doSomethingElse(); <span class="comment">// call custom methods...</span>
- }
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> setEnabled(<span class="type">boolean</span> enabled) {
- <span class="comment">// Pause and unpause</span>
- <span class="local-variable">super</span>.setEnabled(enabled);
- <span class="keyword">if</span>(enabled){
- <span class="comment">// init stuff that is in use while this state is RUNNING</span>
- <span class="local-variable">this</span>.app.getRootNode().attachChild(getX()); <span class="comment">// modify scene graph...</span>
- <span class="local-variable">this</span>.app.doSomethingElse(); <span class="comment">// call custom methods...</span>
- } <span class="keyword">else</span> {
- <span class="comment">// take away everything not needed while this state is PAUSED</span>
- ...
- }
- }
- <span class="comment">// Note that update is only called while the state is both attached and enabled.</span>
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> update(<span class="type">float</span> tpf) {
- <span class="comment">// do the following while game is RUNNING</span>
- <span class="local-variable">this</span>.app.getRootNode().getChild(<span class="string"><span class="delimiter">"</span><span class="content">blah</span><span class="delimiter">"</span></span>).scale(tpf); <span class="comment">// modify scene graph...</span>
- x.setUserData(...); <span class="comment">// call some methods...</span>
- }
- }</code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="pausing-and-unpausing">Pausing and Unpausing</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>You define what an AppState does when Paused or Unpaused, in the <code>setEnabled()</code> and <code>update()</code> methods. Call <code>myState.setEnabled(false)</code> on all states that you want to pause. Call <code>myState.setEnabled(true)</code> on all states that you want to unpause.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="appstatemanager">AppStateManager</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The com.jme3.app.state.AppStateManager holds the list of AppStates for an application. AppStateManager ensures that active AppStates can modify the scene graph, and that the update() loops of active AppStates is executed. There is one AppStateManager per application. You typically attach several AppStates to one AppStateManager, but the same state can only be attached once.</p>
- </div>
- <table class="tableblock frame-all grid-all spread">
- <colgroup>
- <col style="width: 50%;">
- <col style="width: 50%;">
- </colgroup>
- <thead>
- <tr>
- <th class="tableblock halign-left valign-top">AppStateManager Method</th>
- <th class="tableblock halign-left valign-top">Usage</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>hasState(myState)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Is AppState object 'myState' attached?</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>getState(MyAppState.class)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Returns the first attached state that is an instance of a subclass of <code>MyAppState.class</code>.</p>
- </div></div></td>
- </tr>
- </tbody>
- </table>
- <div class="paragraph">
- <p>The AppStateManager’s <code>render(), postRender(), cleanup()</code> methods are internal, ignore them, users never call them directly.</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>If a detached AppState is attached then initialize() will be called on the following render pass.</p>
- </li>
- <li>
- <p>If an attached AppState is detached then cleanup() will be called on the following render pass.</p>
- </li>
- <li>
- <p>If you attach an already-attached AppState then the second attach is a no-op and will return false.</p>
- </li>
- <li>
- <p>If you both attach and detach an AppState within one frame then neither initialize() or cleanup() will be called, although if either is called both will be.</p>
- </li>
- <li>
- <p>If you both detach and then re-attach an AppState within one frame then on the next update pass its cleanup() and initialize() methods will be called in that order.</p>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="best-practices">Best Practices</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="communication-among-appstates">Communication Among AppStates</h3>
- <div class="paragraph">
- <p>You can only access other AppStates (read from and write to them) from certain places: From a Control’s update() method, from an AppState’s update() method, and from the SimpleApplication’s simpleUpdate() loop. Don’t mess with the AppState from other places, because from other methods you have no control over the order of modifications; the game can go out of sync because you can’t know when (during which half-finished step of another state change) your modification will be performed.</p>
- </div>
- <div class="paragraph">
- <p>You can use custom accessors to get data from AppStates, to set data in AppStates, or to trigger methods in AppStates.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="local-variable">this</span>.app.getStateManager().getState(MyAppState.class).doSomeCustomStuffInThisState();</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="initialize-familiar-class-fields">Initialize Familiar Class Fields</h3>
- <div class="paragraph">
- <p>To access class fields of the SimpleApplication the way you are used to, initialize them to local variables, as shown in the following AppState template:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> SimpleApplication app;
- <span class="directive">private</span> Node rootNode;
- <span class="directive">private</span> AssetManager assetManager;
- <span class="directive">private</span> AppStateManager stateManager;
- <span class="directive">private</span> InputManager inputManager;
- <span class="directive">private</span> ViewPort viewPort;
- <span class="directive">private</span> BulletAppState physics;
- <span class="directive">public</span> <span class="type">class</span> <span class="class">MyAppState</span> <span class="directive">extends</span> AbstractAppState {
- <span class="annotation">@Override</span>
- <span class="directive">public</span> <span class="type">void</span> initialize(AppStateManager stateManager, Application app) {
- <span class="local-variable">super</span>.initialize(stateManager, app);
- <span class="local-variable">this</span>.app = (SimpleApplication) app; <span class="comment">// can cast Application to something more specific</span>
- <span class="local-variable">this</span>.rootNode = <span class="local-variable">this</span>.app.getRootNode();
- <span class="local-variable">this</span>.assetManager = <span class="local-variable">this</span>.app.getAssetManager();
- <span class="local-variable">this</span>.stateManager = <span class="local-variable">this</span>.app.getStateManager();
- <span class="local-variable">this</span>.inputManager = <span class="local-variable">this</span>.app.getInputManager();
- <span class="local-variable">this</span>.viewPort = <span class="local-variable">this</span>.app.getViewPort();
- <span class="local-variable">this</span>.physics = <span class="local-variable">this</span>.stateManager.getState(BulletAppState.class);
- }
- }</code></pre>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div id="footer">
- <div id="footer-text">
- Version <br>
- Last updated 2016-06-05 15:58:32 UTC
- </div>
- </div>
- </body>
- </html>
|