Reimplement SettingsData.updateWith via reflection

This commit is contained in:
Fingercomp 2023-06-05 11:41:56 +07:00
parent a65c683529
commit 5516ca4e7d
No known key found for this signature in database
GPG Key ID: BBC71CEE45D86E37
2 changed files with 28 additions and 17 deletions

View File

@ -16,6 +16,8 @@ lazy val root = project.in(file("."))
lazy val brain = ProjectRef(file("lib/ocelot-brain"), "ocelot-brain") lazy val brain = ProjectRef(file("lib/ocelot-brain"), "ocelot-brain")
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value
libraryDependencies += "org.apache.logging.log4j" % "log4j-core" % "2.20.0" libraryDependencies += "org.apache.logging.log4j" % "log4j-core" % "2.20.0"
libraryDependencies += "org.apache.logging.log4j" % "log4j-api" % "2.20.0" libraryDependencies += "org.apache.logging.log4j" % "log4j-api" % "2.20.0"
libraryDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.20.0" libraryDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.20.0"
@ -41,4 +43,4 @@ assembly / assemblyMergeStrategy := {
case _ => MergeStrategy.first case _ => MergeStrategy.first
} }
assembly / assemblyJarName := s"ocelot-desktop.jar" assembly / assemblyJarName := "ocelot-desktop.jar"

View File

@ -1,8 +1,15 @@
package ocelot.desktop.util package ocelot.desktop.util
import ocelot.desktop.Settings.Int2D import ocelot.desktop.Settings.Int2D
import ocelot.desktop.util.SettingsData.Fields
import scala.reflect.runtime.{universe => ru}
class SettingsData { class SettingsData {
// implementation notes:
// this class relies on reflection to implement updateWith
// it's assumed all fields that should be copied are declared as **public var**
def this(data: SettingsData) { def this(data: SettingsData) {
this() this()
updateWith(data) updateWith(data)
@ -25,22 +32,24 @@ class SettingsData {
var saveOnExit: Boolean = true var saveOnExit: Boolean = true
var openLastWorkspace: Boolean = true var openLastWorkspace: Boolean = true
private val mirror = scala.reflect.runtime.universe.runtimeMirror(getClass.getClassLoader).reflect(this)
def updateWith(data: SettingsData): Unit = { def updateWith(data: SettingsData): Unit = {
// TODO: maybe apply some automated mapping solution for (fieldSym <- Fields) {
// TODO: please do that val value = data.mirror.reflectMethod(fieldSym.getter.asMethod)()
this.volumeMaster = data.volumeMaster mirror.reflectMethod(fieldSym.setter.asMethod)(value)
this.volumeBeep = data.volumeBeep }
this.volumeEnvironment = data.volumeEnvironment
this.volumeInterface = data.volumeInterface
this.scaleFactor = data.scaleFactor
this.windowPosition = data.windowPosition
this.windowValidatePosition = data.windowValidatePosition
this.windowSize = data.windowSize
this.windowFullscreen = data.windowFullscreen
this.stickyWindows = data.stickyWindows
this.saveOnExit = data.saveOnExit
this.openLastWorkspace = data.openLastWorkspace
} }
} }
object SettingsData {
private val Fields =
ru.typeOf[SettingsData]
.decls
.filter(_.isTerm)
.map(_.asTerm)
.filter(_.isVar)
// the var itself is private: check setter and getter
.filter(v => v.setter.isPublic && v.getter.isPublic)
.toList
}