fix: Improve exception logging for entity widgets
This commit is contained in:
@@ -10,9 +10,10 @@ import net.minecraft.client.gui.Element
|
|||||||
import net.minecraft.client.gui.ParentElement
|
import net.minecraft.client.gui.ParentElement
|
||||||
import net.minecraft.entity.LivingEntity
|
import net.minecraft.entity.LivingEntity
|
||||||
import moe.nea.firmament.gui.entity.EntityRenderer
|
import moe.nea.firmament.gui.entity.EntityRenderer
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
|
|
||||||
|
|
||||||
class EntityWidget(val entity: LivingEntity, val point: Point) : WidgetWithBounds() {
|
class EntityWidget(val entity: LivingEntity?, val point: Point) : WidgetWithBounds() {
|
||||||
override fun children(): List<Element> {
|
override fun children(): List<Element> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
@@ -22,9 +23,9 @@ class EntityWidget(val entity: LivingEntity, val point: Point) : WidgetWithBound
|
|||||||
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||||
try {
|
try {
|
||||||
if (!hasErrored)
|
if (!hasErrored)
|
||||||
EntityRenderer.renderEntity(entity, context, point.x, point.y, mouseX.toFloat(), mouseY.toFloat())
|
EntityRenderer.renderEntity(entity!!, context, point.x, point.y, mouseX.toFloat(), mouseY.toFloat())
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
EntityRenderer.logger.error("Failed to render constructed entity: $entity", ex)
|
ErrorUtil.softError("Failed to render constructed entity: $entity", ex)
|
||||||
hasErrored = true
|
hasErrored = true
|
||||||
}
|
}
|
||||||
if (hasErrored) {
|
if (hasErrored) {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() {
|
|||||||
} else {
|
} else {
|
||||||
EntityRenderer.applyModifiers(source, listOf())
|
EntityRenderer.applyModifiers(source, listOf())
|
||||||
}
|
}
|
||||||
if (entity != null) {
|
|
||||||
val level = display.neuRecipe.level
|
val level = display.neuRecipe.level
|
||||||
val fullMobName =
|
val fullMobName =
|
||||||
if (level > 0) Text.translatable("firmament.recipe.mobs.name", level, display.neuRecipe.name)
|
if (level > 0) Text.translatable("firmament.recipe.mobs.name", level, display.neuRecipe.name)
|
||||||
@@ -76,7 +75,6 @@ class SBMobDropRecipe(override val neuRecipe: NEUMobDropRecipe) : SBRecipe() {
|
|||||||
tt
|
tt
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
add(
|
add(
|
||||||
Widgets.createLabel(Point(bounds.minX + 15, bounds.minY + 5), Text.literal(display.neuRecipe.name))
|
Widgets.createLabel(Point(bounds.minX + 15, bounds.minY + 5), Text.literal(display.neuRecipe.name))
|
||||||
.leftAligned()
|
.leftAligned()
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package moe.nea.firmament.gui.entity
|
|||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import org.apache.logging.log4j.LogManager
|
|
||||||
import org.joml.Quaternionf
|
import org.joml.Quaternionf
|
||||||
import org.joml.Vector3f
|
import org.joml.Vector3f
|
||||||
import kotlin.math.atan
|
import kotlin.math.atan
|
||||||
@@ -15,8 +14,8 @@ import net.minecraft.entity.LivingEntity
|
|||||||
import net.minecraft.entity.SpawnReason
|
import net.minecraft.entity.SpawnReason
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
import moe.nea.firmament.util.ErrorUtil
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.assertNotNullOr
|
|
||||||
import moe.nea.firmament.util.iterate
|
import moe.nea.firmament.util.iterate
|
||||||
import moe.nea.firmament.util.openFirmamentResource
|
import moe.nea.firmament.util.openFirmamentResource
|
||||||
import moe.nea.firmament.util.render.enableScissorWithTranslation
|
import moe.nea.firmament.util.render.enableScissorWithTranslation
|
||||||
@@ -76,18 +75,15 @@ object EntityRenderer {
|
|||||||
"name" to ModifyName,
|
"name" to ModifyName,
|
||||||
)
|
)
|
||||||
|
|
||||||
val logger = LogManager.getLogger("Firmament.Entity")
|
|
||||||
fun applyModifiers(entityId: String, modifiers: List<JsonObject>): LivingEntity? {
|
fun applyModifiers(entityId: String, modifiers: List<JsonObject>): LivingEntity? {
|
||||||
val entityType = assertNotNullOr(entityIds[entityId]) {
|
val entityType = ErrorUtil.notNullOr(entityIds[entityId], "Could not create entity with id $entityId") {
|
||||||
logger.error("Could not create entity with id $entityId")
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
var entity = entityType()
|
var entity = ErrorUtil.catch("") { entityType() }.or { return null }
|
||||||
for (modifierJson in modifiers) {
|
for (modifierJson in modifiers) {
|
||||||
val modifier = assertNotNullOr(modifierJson["type"]?.asString?.let(entityModifiers::get)) {
|
val modifier = ErrorUtil.notNullOr(
|
||||||
logger.error("Unknown modifier $modifierJson")
|
modifierJson["type"]?.asString?.let(entityModifiers::get),
|
||||||
return null
|
"Could not create entity with id $entityId. Failed to apply modifier $modifierJson") { return null }
|
||||||
}
|
|
||||||
entity = modifier.apply(entity, modifierJson)
|
entity = modifier.apply(entity, modifierJson)
|
||||||
}
|
}
|
||||||
return entity
|
return entity
|
||||||
@@ -95,8 +91,7 @@ object EntityRenderer {
|
|||||||
|
|
||||||
fun constructEntity(info: JsonObject): LivingEntity? {
|
fun constructEntity(info: JsonObject): LivingEntity? {
|
||||||
val modifiers = (info["modifiers"] as JsonArray?)?.map { it.asJsonObject } ?: emptyList()
|
val modifiers = (info["modifiers"] as JsonArray?)?.map { it.asJsonObject } ?: emptyList()
|
||||||
val entityType = assertNotNullOr(info["entity"]?.asString) {
|
val entityType = ErrorUtil.notNullOr(info["entity"]?.asString, "Missing entity type on entity object") {
|
||||||
logger.error("Missing entity type on entity object")
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return applyModifiers(entityType, modifiers)
|
return applyModifiers(entityType, modifiers)
|
||||||
|
|||||||
@@ -37,6 +37,31 @@ object ErrorUtil {
|
|||||||
else Firmament.logger.error(message)
|
else Firmament.logger.error(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Catch<T> private constructor(val value: T?, val exc: Throwable?) {
|
||||||
|
inline fun or(block: (exc: Throwable) -> T): T {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||||
|
}
|
||||||
|
if (exc != null) return block(exc)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return value as T
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T> fail(exception: Throwable): Catch<T> = Catch(null, exception)
|
||||||
|
fun <T> succeed(value: T): Catch<T> = Catch(value, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> catch(message: String, block: () -> T): Catch<T> {
|
||||||
|
try {
|
||||||
|
return Catch.succeed(block())
|
||||||
|
} catch (exc: Throwable) {
|
||||||
|
softError(message, exc)
|
||||||
|
return Catch.fail(exc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
||||||
contract {
|
contract {
|
||||||
callsInPlace(orElse, InvocationKind.AT_MOST_ONCE)
|
callsInPlace(orElse, InvocationKind.AT_MOST_ONCE)
|
||||||
|
|||||||
Reference in New Issue
Block a user