Skip to content

Instantly share code, notes, and snippets.

@pfn
Last active February 17, 2016 04:44
Show Gist options
  • Save pfn/07e0ef3f63d4896a629b to your computer and use it in GitHub Desktop.
Save pfn/07e0ef3f63d4896a629b to your computer and use it in GitHub Desktop.
pure activity start
package com.hanhuy.android.irc
import android.app.Activity
import android.os.Bundle
import android.view.{View, Menu}
import iota.IO
/** beware:
* https://youtrack.jetbrains.com/issue/SCL-9888
* https://issues.scala-lang.org/browse/SI-9658
*/
trait PureActivity[S] extends Activity {
private[this] var state: S = _
sealed trait ActivityState[T] {
val state: S
val zero: T
def noUpdate[A](io: IO[A]): IO[(T,S)] = io map (_ => zero -> state)
def updateResult(io: IO[T]): IO[(T,S)]
def updateState(io: IO[S]): IO[(T,S)] = io map (s => zero -> s)
}
trait ActivityStateUnit extends ActivityState[Unit] {
val zero = ()
def updateResult(io: IO[Unit]): IO[(Unit,S)] = noUpdate(io)
}
case class OnCreate(state: S) extends ActivityStateUnit
case class OnDestroy(state: S) extends ActivityStateUnit
case class OnStart(state: S) extends ActivityStateUnit
case class OnStop(state: S) extends ActivityStateUnit
case class OnResume(state: S) extends ActivityStateUnit
case class OnPause(state: S) extends ActivityStateUnit
case class OnCreateOptionsMenu(state: S, menu: Menu) extends ActivityState[Boolean] {
val zero = false
def updateResult(io: IO[Boolean]): IO[(Boolean,S)] = io map (b => b -> state)
}
case class TransformState(state: S, oldState: S) extends ActivityStateUnit
case class SaveState(state: S, bundle: Bundle) extends ActivityStateUnit
def initialState(b: Option[Bundle]): S
def setContentView[V <: View](iov: IO[V]): IO[Unit] = IO {
setContentView(iov.perform())
}
def transformState(f: S => S): IO[Unit] = IO {
state = applyState(TransformState(f(state),state)).perform()._2
}
def applyState[T](s: ActivityState[T]): IO[(T,S)]
def defaultApplyState[T](s: ActivityState[T]): IO[(T,S)] = IO(s.zero -> s.state)
final override def onCreate(savedInstanceState: Bundle) = {
super.onCreate(savedInstanceState)
state = applyState(OnCreate(initialState(Option(savedInstanceState)))).perform()._2
}
final override def onCreateOptionsMenu(m: Menu): Boolean = {
val b = super.onCreateOptionsMenu(m)
val (r,st) = applyState(OnCreateOptionsMenu(state, m)).perform()
state = st
b || r
}
final override def onSaveInstanceState(outState: Bundle) = {
super.onSaveInstanceState(outState)
state = applyState(SaveState(state, outState)).perform()._2
}
final override def onStart() = {
super.onStart()
state = applyState(OnStart(state)).perform()._2
}
final override def onResume() = {
super.onResume()
state = applyState(OnResume(state)).perform()._2
}
final override def onPause() = {
super.onPause()
state = applyState(OnPause(state)).perform()._2
}
final override def onStop() = {
super.onStop()
state = applyState(OnStop(state)).perform()._2
}
final override def onDestroy() = {
super.onDestroy()
state = applyState(OnDestroy(state)).perform()._2
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment