From 9f42ae963924935ff9294b17764f20aeec5ed73a Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Mon, 13 Jun 2016 00:48:37 +0900 Subject: [PATCH] thread pooling terraingen, WIP Former-commit-id: 1d0687d8b34d5e8192b652904a437cdb29f27b10 Former-commit-id: 1c06ce97a59eb13455cc180a4d5f13ffbead1f84 --- res/books/cjk_test.txt | 58 ++++++++++++++ res/locales/helpOnTheFly.csv | 19 ++--- src/net/torvald/terrarum/Game.kt | 2 +- src/net/torvald/terrarum/Terrarum.kt | 9 +++ .../{ => gameactors}/ThreadActorUpdate.kt | 4 +- .../terrarum/mapgenerator/MapGenerator.kt | 78 ++++++++++++------- .../mapgenerator/ThreadProcessNoiseLayers.kt | 46 +++++++++++ .../terrarum/tileproperties/tileprop.csv | 10 +-- 8 files changed, 180 insertions(+), 46 deletions(-) create mode 100644 res/books/cjk_test.txt rename src/net/torvald/terrarum/{ => gameactors}/ThreadActorUpdate.kt (82%) create mode 100644 src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt diff --git a/res/books/cjk_test.txt b/res/books/cjk_test.txt new file mode 100644 index 000000000..35794d251 --- /dev/null +++ b/res/books/cjk_test.txt @@ -0,0 +1,58 @@ +流れてく時の中ででも気だるさが ほらクルクル廻って +흘러만 가는 시간 속 한가운데도 나른함이 봐, 계속 빙글빙글 돌고 있어 +私から離れる心も見えないわ そう知らない +보이지 않아, 나에게서 멀어지는 마음 따위는, 그래 나는 몰라 +自分から動くこともなく 時の隙間に流され続けて +스스로부터 움직이는 일도 없이 시간의 틈새에서 우두커니 바라볼 뿐 +知らないわ周りのことなど 私は私 それだけ +그런 건 몰라, 내 주변의 일 같은 건, 나는 나일 뿐 더는 신경 안 써 + + +夢見てる 何も見てない 語るも無駄な自分の言葉 +꿈이 보이니? 어둠만이 보이니? 부질없이 울리는 나 자신의 혼잣말 +悲しむなんで疲れるだけよ 何も感じす過ごせばいいの +슬픔에 잠기는 건 이젠 지칠 뿐이야, 아무 감정도 없이 지내면 되는 거야 +戸惑う言葉与えられても 自分の心ただ上の空 +뜻밖의 놀라운 말 나에게 온다 해도 아직 나의 마음은 그저 흘려들을 뿐 +もし私から動くのならば 全て変えるのなら黒にする +만약 나 자신부터 움직일 수 있다면, 모든 걸 바꿀 수 있다면 검게 하겠어 + + +こんな自分に未来はあるの こんな世界に私はいるの +이런 나 자신에게 미래는 있는 걸까, 이런 세상 가운데 난 끼어 있는 걸까 +今切ないの 今悲しいの 自分のこともわからないまま +애달퍼하는 걸까, 슬픔에 잠긴 걸까, 이런 자신조차도 알지 못하는 채로 +歩むことさえ疲れるだけよ 人のことなど知りもしないわ +발을 내딛는 것도 이젠 지칠 뿐이야, 주변의 일들 따윈 알고 싶지도 않아 +こんな私も変われるのなら もし変われるのなら白になる +이런 나 같은 것도 바뀔 수가 있다면, 바뀔 수만 있다면 나는 하얘지겠어 + + +流れてく時の中ででも気だるさが ほらクルクル廻って +흘러만 가는 시간 속 한가운데도 나른함이 봐, 계속 빙글빙글 돌고 있어 +私から離れる心も見えないわ そう知らない +보이지 않아, 나에게서 멀어지는 마음 따위는, 그래 나는 몰라 +自分から動くこともなく 時の隙間に流され続けて +스스로부터 움직이는 일도 없이 시간의 틈새에서 우두커니 바라볼 뿐 +知らないわ周りのことなど 私は私 それだけ +그런 건 몰라, 내 주변의 일 같은 건, 나는 나일 뿐, 더는 신경 안 써 + + +夢見てる 何も見てない 語るも無駄な自分の言葉 +꿈이 보이니? 어둠만이 보이니? 부질없이 울리는 나 자신의 혼잣말 +悲しむなんで疲れるだけよ 何も感じす過ごせばいいの +슬픔에 잠기는 건 이젠 지칠 뿐이야, 아무 감정도 없이 지내면 되는 거야 +戸惑う言葉与えられても 自分の心ただ上の空 +뜻밖의 놀라운 말 나에게 온다 해도 아직 나의 마음은 그저 흘려들을 뿐 +もし私から動くのならば 全て変えるのなら黒にする +만약 나 자신부터 움직일 수 있다면, 모든 걸 바꿀 수 있다면 검게 하겠어 + + +動くのならば 動くのならば 全て壊すの 全て壊すの +움직이고 있다면, 움직이고 있다면, 모두 다 부숴버려, 모두 다 부숴버려 +悲しむならば 悲しむならば 私の心白く変われる +슬퍼하고 있으면, 슬퍼하고 있으면, 이런 나의 마음도 하얘질 수 있을까 +貴方のことも 私のことも 全てのこともまだ知らないの +그대에 관해서도, 자신에 관해서도, 모두에 관해서도 아직도 나는 몰라 +重い目蓋を開けてのならば 全て壊すのなら黒になれ +무거운 눈꺼풀을 뜨게할 수 있다면, 모든 걸 부순다면 모두 검게 되어라 \ No newline at end of file diff --git a/res/locales/helpOnTheFly.csv b/res/locales/helpOnTheFly.csv index 99ad393a9..9f1ef04cd 100644 --- a/res/locales/helpOnTheFly.csv +++ b/res/locales/helpOnTheFly.csv @@ -1,14 +1,15 @@ "STRING_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC" -"HELP_OTF_MAIN_1";;"Type “help slow” for the ways to make the game run faster.";"Tapez « help slow » si votre jeu fonctionne lentement.";;;;;;;;;;;;;;;"ゲームの実行がおそければ「help slow」を入力してください。";;;"게임이 느리게 돌아간다면 “help slow”를 입력해 보세요." -"HELP_OTF_MAIN_2";;"Press PageUp/PageDown to scroll the messages.";"Appuyez sur PageUp/PageDown pour faire défiler les messages.";;;;;;;;;;;;;;;"PageUp/PageDownキーを使ってメッセージのスクロールができます。";;;"PageUp/PageDown 키를 사용해 메시지를 스크롤할 수 있습니다." +"HELP_OTF_MAIN_1";;"Type “help slow” for the ways to make the game run faster.";"Tapez « help slow » si votre jeu fonctionne lentement.";;;;;;;;;;;;;;;"ゲームの実行がおそければ「help slow」を入力してください。";;;"게임이 느리게 돌아간다면 “help slow”를 입력해 보세요.";;;;;;"ゲームのじっこうが おそければ「help slow」を にんりょくしてください。" +"HELP_OTF_MAIN_2";;"Press PageUp/PageDown to scroll the messages.";"Appuyez sur PageUp/PageDown pour faire défiler les messages.";;;;;;;;;;;;;;;"PageUp/PageDownキーを使ってメッセージのスクロールができます。";;;"PageUp/PageDown 키를 사용해 메시지를 스크롤할 수 있습니다.";;;;;;"PageUp/PageDownキーをつかって メッセージのスクロールができます。" "HELP_OTF_MAIN_3";;"Utility keys:";"Touches utilitaires:";;;;;;;;;;;;;;;"技能キー";;;"기능 키:" -"HELP_OTF_MAIN_4";;"• F3: (debug) basic information";"• F3: (déboguer) informations de base";;;;;;;;;;;;;;;"• F3: (デバッグ)基本的な情報";;;"• F3: (디버그) 기본 정보" -"HELP_OTF_MAIN_5";;"• F7: (debug) toggle light blending";"• F7: (déboguer) basculer fusion de lumière";;;;;;;;;;;;;;;"• F7: (デバッグ)光源のブレンドON/OFF";;;"• F7: (디버그) 광원 블렌딩 켜고 끄기" -"HELP_OTF_MAIN_6";;"• F8: toggle smooth lighting effect";"• F8: basculer effet éclairage lisse";;;;;;;;;;;;;;;"• F8: すべすべの光源効果ON/OFF";;;"• F8: 부드러운 광원 효과 켜고 끄기" +"HELP_OTF_MAIN_4";;"• F3: (debug) basic information";"• F3: (déboguer) informations de base";;;;;;;;;;;;;;;"• F3: (デバッグ)基本的な情報を見る";;;"• F3: (디버그) 기본 정보";;;;;;"• F3: (デバッグ)きほんてきな じょうほうを みる" +"HELP_OTF_MAIN_5";;"• F7: (debug) toggle light blending";"• F7: (déboguer) basculer fusion de lumière";;;;;;;;;;;;;;;"• F7: (デバッグ)光源のブレンドをオン・オフする";;;"• F7: (디버그) 광원 블렌딩 켜고 끄기";;;;;;"• F7: (デバッグ)こうげんのブレンドを オン・オフする" +"HELP_OTF_MAIN_6";;"• F8: toggle smooth lighting effect";"• F8: basculer effet éclairage lisse";;;;;;;;;;;;;;;"• F8: すべすべの光源効果をオン・オフする";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: すべすべのこうげん こうかを オン・オフする" +"HELP_OTF_MAIN_JP_1";;"• F4: toggle Kana/Kanji mode";;;;;;;;;;;;;;;;"• F8: 【日本語】かな・漢字モードを変換する";;;"• F8: 부드러운 광원 효과 켜고 끄기";;;;;;"• F8: 【日本語】かな・かんじモードを" -"HELP_OTF_SLOW_1";;"If your game runs slowly:";"Si votre jeu tourne lentement :";;;;;;;;;;;;;;;"ゲームの実行がおそければ";;;"게임이 느리게 돌아간다면" -"HELP_OTF_SLOW_2";;"• Reset screen zoom to 1.";"• Réinitialisez le zoom de l‘écran à 1.";;;;;;;;;;;;;;;"• スクリーンのズームを1倍にリセットしてください。";;;"• 화면 줌을 1로 돌려주세요. " -"HELP_OTF_SLOW_3";;"• Close the basic information window.";"• Désactivez la fenêtre d‘informations.";;;;;;;;;;;;;;;"• 情報ウィンドウをとじてください。";;;"• 기본 정보 창을 꺼 주세요." -"HELP_OTF_SLOW_4";;"• Turn off smooth lighting effect. You can do it now by pressing F8.";"• Désactivez effet éclairage lisse en utilisant F8.";;;;;;;;;;;;;;;"• F8で、すべすべの光源効果をオフしてください。";;;"• 부드러운 광원 효과를 꺼 주세요. F8을 사용할 수 있습니다." +"HELP_OTF_SLOW_1";;"If your game runs slowly:";"Si votre jeu tourne lentement :";;;;;;;;;;;;;;;"ゲームの実行がおそければ";;;"게임이 느리게 돌아간다면";;;;;;"ゲームのじっこうが おそければ" +"HELP_OTF_SLOW_2";;"• Reset screen zoom to 1.";"• Réinitialisez le zoom de l‘écran à 1.";;;;;;;;;;;;;;;"• スクリーンのズームを1倍にリセットしてください。";;;"• 화면 줌을 1로 돌려주세요. ";;;;;;"• スクリーンのズームを 1にリセットしてください。" +"HELP_OTF_SLOW_3";;"• Close the basic information window.";"• Désactivez la fenêtre d‘informations.";;;;;;;;;;;;;;;"• 情報ウィンドウをとじてください。";;;"• 기본 정보 창을 꺼 주세요.";;;;;;"• じょうほうウィンドウを とじてください。" +"HELP_OTF_SLOW_4";;"• Turn off smooth lighting effect. You can do it now by pressing F8.";"• Désactivez effet éclairage lisse en utilisant F8.";;;;;;;;;;;;;;;"• F8で、すべすべの光源効果をオフしてください。";;;"• 부드러운 광원 효과를 꺼 주세요. F8을 사용할 수 있습니다.";;;;;;"• F8で、すべすべのこうげん こうかを オフしてください。" diff --git a/src/net/torvald/terrarum/Game.kt b/src/net/torvald/terrarum/Game.kt index ca9e659e8..61384a8b0 100644 --- a/src/net/torvald/terrarum/Game.kt +++ b/src/net/torvald/terrarum/Game.kt @@ -373,7 +373,7 @@ constructor() : BasicGameState() { } fun updateActors(gc: GameContainer, delta: Int) { - if (CORES >= 2 && Terrarum.getConfigBoolean("multithread")) { + if (false) { // don't multithread this for now, it's SLOWER //if (Terrarum.MULTITHREAD) { val actors = actorContainer.size.toFloat() // set up indices for (i in 0..ThreadPool.POOL_SIZE - 1) { diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 8ca170cfb..6722cacfa 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -114,6 +114,15 @@ constructor(gamename: String) : StateBasedGame(gamename) { /** Available CPU cores */ val CORES = Runtime.getRuntime().availableProcessors(); + /** + * If the game is multithreading. + * True if: + * + * CORES >= 2 and config "multithread" is true + */ + val MULTITHREAD: Boolean + get() = CORES >= 2 && getConfigBoolean("multithread") + private lateinit var configDir: String /** diff --git a/src/net/torvald/terrarum/ThreadActorUpdate.kt b/src/net/torvald/terrarum/gameactors/ThreadActorUpdate.kt similarity index 82% rename from src/net/torvald/terrarum/ThreadActorUpdate.kt rename to src/net/torvald/terrarum/gameactors/ThreadActorUpdate.kt index 83de8d45a..7d120e22b 100644 --- a/src/net/torvald/terrarum/ThreadActorUpdate.kt +++ b/src/net/torvald/terrarum/gameactors/ThreadActorUpdate.kt @@ -1,6 +1,6 @@ -package net.torvald.terrarum +package net.torvald.terrarum.gameactors -import net.torvald.terrarum.gameactors.Player +import net.torvald.terrarum.Terrarum import org.newdawn.slick.GameContainer /** diff --git a/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt b/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt index 0f8edec8f..1ca88f9a8 100644 --- a/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt +++ b/src/net/torvald/terrarum/mapgenerator/MapGenerator.kt @@ -6,12 +6,15 @@ import net.torvald.terrarum.tileproperties.TileNameCode import com.jme3.math.FastMath import com.sudoplay.joise.Joise import com.sudoplay.joise.module.* +import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.concurrent.ThreadPool +import net.torvald.terrarum.gameactors.ThreadActorUpdate import java.util.* object MapGenerator { - private lateinit var map: GameMap - private lateinit var random: Random + internal lateinit var map: GameMap + internal lateinit var random: Random //private static float[] noiseArray; var SEED: Long = 0 var WIDTH: Int = 0 @@ -56,7 +59,7 @@ object MapGenerator { private val GRASSCUR_DOWN = 2 private val GRASSCUR_LEFT = 3 - private val TILE_MACRO_ALL = -1 + internal val TILE_MACRO_ALL = -1 fun attachMap(map: GameMap) { this.map = map @@ -665,33 +668,50 @@ object MapGenerator { } private fun processNoiseLayers(noiseRecords: Array) { - for (record in noiseRecords) { - println("[mapgenerator] ${record.message}...") - for (y in 0..HEIGHT - 1) { - for (x in 0..WIDTH - 1) { - val noise: Float = record.noiseModule.get( - x.toDouble() / 48.0, // 48: Fixed value - y.toDouble() / 48.0 - ).toFloat() - - val fromTerr = record.replaceFromTerrain - val fromWall = record.replaceFromWall - val to: Int = when(record.replaceTo) { - is Int -> record.replaceTo as Int - is IntArray -> (record.replaceTo as IntArray)[random.nextInt((record.replaceTo as IntArray).size)] - else -> throw IllegalArgumentException("[mapgenerator] Unknown replaceTo tile type '${record.replaceTo.javaClass.canonicalName}': Only 'kotlin.Int' and 'kotlin.IntArray' is valid.") - } - if (to == TILE_MACRO_ALL) throw IllegalArgumentException("[mapgenerator] Invalid replaceTo: TILE_MACRO_ALL") - val threshold = record.filter.getGrad(y, record.filterArg1, record.filterArg2) - - if (noise > threshold * record.scarcity) { - if ((map.getTileFromTerrain(x, y) == fromTerr || fromTerr == TILE_MACRO_ALL) - && (map.getTileFromWall(x, y) == fromWall || fromWall == TILE_MACRO_ALL)) { - map.setTileTerrain(x, y, to) - } - } - } + if (Terrarum.MULTITHREAD) { + // set up indices + for (i in 0..ThreadPool.POOL_SIZE - 1) { + ThreadPool.map( + i, + ThreadProcessNoiseLayers( + ((HEIGHT / Terrarum.CORES) * i).toInt(), + ((HEIGHT / Terrarum.CORES) * i.plus(1)).toInt() - 1, + noiseRecords + ), + "SampleJoiseMap" + ) } + + ThreadPool.startAll() + // FIXME game starts prematurely + /* Console: + [mapgenerator] Seed: 85336530 + [mapgenerator] Raising and eroding terrain... + [mapgenerator] Shaping world... + [mapgenerator] Carving caves... + [mapgenerator] Carving caves... + [mapgenerator] Carving caves... + [mapgenerator] Flooding bottom lava... + [mapgenerator] Carving caves... + [mapgenerator] Planting grass... + [mapgenerator] Placing floating islands... + [UIHandler] Creating UI 'ConsoleWindow' + Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false + Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 2048x256 + [UIHandler] Creating UI 'BasicDebugInfoWindow' + Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false + Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 2048x1024 + [UIHandler] Creating UI 'Notification' + Mon Jun 13 00:43:57 KST 2016 INFO:Offscreen Buffers FBO=true PBUFFER=true PBUFFERRT=false + Mon Jun 13 00:43:57 KST 2016 DEBUG:Creating FBO 512x64 + [mapgenerator] Collapsing caves... + [mapgenerator] Collapsing caves... + [mapgenerator] Collapsing caves... + [mapgenerator] Collapsing caves... + */ + } + else { + ThreadProcessNoiseLayers(0, HEIGHT - 1, noiseRecords).run() } } diff --git a/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt b/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt new file mode 100644 index 000000000..c4fcfa028 --- /dev/null +++ b/src/net/torvald/terrarum/mapgenerator/ThreadProcessNoiseLayers.kt @@ -0,0 +1,46 @@ +package net.torvald.terrarum.mapgenerator + +/** + * Created by minjaesong on 16-06-13. + */ +class ThreadProcessNoiseLayers(val startIndex: Int, val endIndex: Int, + val noiseRecords: Array) : Runnable { + + + override fun run() { + for (record in noiseRecords) { + println("[mapgenerator] ${record.message}...") + for (y in startIndex..endIndex) { + for (x in 0..MapGenerator.WIDTH - 1) { + val noise: Float = record.noiseModule.get( + x.toDouble() / 48.0, // 48: Fixed value + y.toDouble() / 48.0 + ).toFloat() + + val fromTerr = record.replaceFromTerrain + val fromWall = record.replaceFromWall + + val to: Int = when (record.replaceTo) { + // replace to designated tile + is Int -> record.replaceTo as Int + // replace to randomly selected tile from given array of tile IDs + is IntArray -> (record.replaceTo as IntArray)[MapGenerator.random.nextInt((record.replaceTo as IntArray).size)] + else -> throw IllegalArgumentException("[mapgenerator] Unknown replaceTo tile type '${record.replaceTo.javaClass.canonicalName}': Only 'kotlin.Int' and 'kotlin.IntArray' is valid.") + } + // replace to ALL? this is bullshit + if (to == MapGenerator.TILE_MACRO_ALL) throw IllegalArgumentException("[mapgenerator] Invalid replaceTo: TILE_MACRO_ALL") + + // filtered threshold + val threshold = record.filter.getGrad(y, record.filterArg1, record.filterArg2) + + if (noise > threshold * record.scarcity) { + if ((MapGenerator.map.getTileFromTerrain(x, y) == fromTerr || fromTerr == MapGenerator.TILE_MACRO_ALL) + && (MapGenerator.map.getTileFromWall(x, y) == fromWall || fromWall == MapGenerator.TILE_MACRO_ALL)) { + MapGenerator.map.setTileTerrain(x, y, to) + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/tileproperties/tileprop.csv b/src/net/torvald/terrarum/tileproperties/tileprop.csv index 5a26fece9..27b1a77d2 100644 --- a/src/net/torvald/terrarum/tileproperties/tileprop.csv +++ b/src/net/torvald/terrarum/tileproperties/tileprop.csv @@ -45,7 +45,7 @@ "11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16" "12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16" "12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16" - "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "248768744"; "13"; "0"; "0";"16" + "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "239319274"; "13"; "0"; "0";"16" "13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246656000"; "13"; "1"; "0";"16" "13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246602752"; "13"; "2"; "0";"16" "13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0";"16" @@ -128,12 +128,12 @@ # dsty: density. As we are putting water an 1000, it is identical to specific gravity. [g/l] -## Illuminants ## +## Illuminators ## -# Illuminant white: RGB(237,250,232), simulation of mercury-vapour lamp (If you want high CRI lamp, collect a daylight!) +# Illuminator white: RGB(228,238,234), simulation of a halophosphate FL lamp (If you want high CRI lamp, collect a daylight!) # Defalut torch : L 70 a 51 b 59; real candlelight colour taken from properly configured camera. -# Sunstone: Artificial sunlight, change colour over time in sync with sunlight. Set by game's code. -# Sunlight capacitor: daylight at 11h of 22h day. Set by game's code. +# Sunstone: Artificial sunlight, change colour over time in sync with sunlight. The light is set by game's code. +# Sunlight capacitor: daylight at noon. Set by game's code. ## Tiles ##