8000 IconForge: Arbitrary Icon Creation Update, Improved Caching, Cleaner I/O by itsmeow · Pull Request #213 · tgstation/rust-g · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

IconForge: Arbitrary Icon Creation Update, Improved Caching, Cleaner I/O #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

itsmeow
Copy link
Contributor
@itsmeow itsmeow commented May 1, 2025

What This Does

  • Adds the ability for generate_spritesheet to output DMIs
  • Adds support for multi-dir & animated/multi-frame icons to the new DMI spritesheet generator
  • Improves the caching system by putting the image data into an Arc
  • Removes the old "hash_input" system and I/O conversions which were wasteful
  • Splits the code out into separate files because it was getting messy
  • Renames several functions to be more descriptive
  • Moves a few functions to impls on existing structs to reduce the amount of global functions doing type conversions
  • Slightly more verbose error message if there is an error during the final generation stage of spritesheets - it will now include the associated sprite_name that caused the error, rather than saying "N/A, in final generation stage".

Breaking DM change: add , FALSE, TRUE argument to the end of existing calls to rustg_iconforge_generate() or rustg_iconforge_generate_async()

Breaking DM change: The default arguments of the commonly used uni_icon API need to be adjusted so that dir and frame are null

/datum/universal_icon/New(icon/icon_file, icon_state="", dir=null, frame=null, datum/icon_transformer/transform=null, color=null)

Arbitrary Icon Generation

It's now technically possible to generate just about any icon that the game can make (excluding certain special operations) with just the uni_icon system and rustg_iconforge_generate(), because it now supports multi-dir and animated icons. However, the main benefit of IconForge is still parallelization and caching.

I got this idea because it would make tgstation/tgstation#90940 run significantly faster with very little effort.

I tested this using the linked TG PR with the following method replacement:

/datum/controller/subsystem/processing/greyscale/proc/ExportMapPreviewsForType(filename, atom/atom_typepath, list/type_blacklist)
	var/list/handled_types = list()
	var/list/sprite_entries = list()
	for(var/atom/atom_type as anything in subtypesof(atom_typepath))
		if(type_blacklist && type_blacklist[atom_type])
			continue
		handled_types[atom_type] = TRUE
		var/greyscale_config = atom_type::greyscale_config
		var/greyscale_colors = atom_type::greyscale_colors
		if(!greyscale_config || !greyscale_colors || atom_type::flags_1 & NO_NEW_GAGS_PREVIEW_1)
			continue
		var/datum/universal_icon/map_icon = GetColoredIconByTypeUniversalIcon(greyscale_config, greyscale_colors, atom_type::post_init_icon_state)
		sprite_entries["[atom_type]"] = map_icon.to_list()

	// Skip empty sheets
	if(!length(sprite_entries))
		return handled_types

	var/entries_json = json_encode(sprite_entries)
	var/data_out = rustg_iconforge_generate("icons/map_icons/", filename, entries_json, FALSE, TRUE)
	if (data_out == RUSTG_JOB_ERROR)
		CRASH("GAGS-MapIcon/Spritesheet [filename] JOB PANIC")
	else if(!findtext(data_out, "{", 1, 2))
		rustg_file_write(entries_json, "[GLOB.log_directory]/spritesheet_gags_mapicon_debug_[replacetext(filename, "/", "-")].json")
		CRASH("GAGS-MapIcon/Spritesheet [filename] UNKNOWN ERROR: [data_out]")
	var/data = json_decode(data_out)
	var/list/sizes = data["sizes"]
	var/list/sprites = data["sprites"]
	if(data["error"])
		CRASH("Error during GAGS-MapIcon/spritesheet generation for [filename]: [data["error"]]")
	for(var/size_id in sizes)
		if(size_id == "32x32")
			continue
		fdel("icons/map_icons/[filename]_[size_id].dmi")
		var/list/sprites_with_bad_size = list()
		for(var/sprite_name in sprites)
			var/list/sprite = sprites[sprite_name]
			if(sprite["size_id"] == "32x32")
				continue
			sprites_with_bad_size.Add(sprite_name)
		var/bad_sprites = jointext(sprites_with_bad_size, " \n")
		CRASH("Non 32x32 icons found in GAGS-MapIcon/spritesheet [filename] for typepaths: \n[bad_sprites]")
	var/output_filepath = "icons/map_icons/[filename]_32x32.dmi"
	var/filepath = "icons/map_icons/[filename].dmi"
#ifdef UNIT_TESTS
	var/old_md5 = rustg_hash_file(RUSTG_HASH_MD5, filepath)
#endif
	fcopy(output_filepath, filepath)
#ifdef UNIT_TESTS
	var/new_md5 = rustg_hash_file(RUSTG_HASH_MD5, filepath)
	if(old_md5 != new_md5)
		stack_trace("Generated map icons were different than what is currently saved. If you see this in a CI run it means you need to run the game once through initialization and commit the resulting files in 'icons/map_icons/'")
#endif
	fdel(output_filepath)
	return handled_types

The output was exactly as expected.

image
image
image

I did some tracy profiling, and it's actually faster now, due to changes in how caching and I/O works

image

@itsmeow itsmeow changed the title Add support for DMI output of spritesheets IconForge: Add support for DMI output of spritesheets May 1, 2025
@itsmeow itsmeow changed the title IconForge: Add support for DMI output of spritesheets IconForge: Arbitrary Icon Creation Update, Improved Caching, Cleaner I/O May 9, 2025
Copy link
@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the IconForge system by adding arbitrary icon generation with support for DMI output, improved caching using Arc and DashMap, and cleaner I/O handling. Key changes include new Rust modules for spritesheet generation, image caching, and blending, along with updated DM macros and documentation to support the new DMI and flatten parameters.

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/iconforge/spritesheet.rs Introduces new structures for spritesheet results with DMI support.
src/iconforge/image_cache.rs Implements enhanced caching for UniversalIcon data and DMI file parsing.
src/iconforge/byond.rs Adds DM bindings for synchronous and asynchronous icon generation functions.
src/iconforge/blending.rs Provides blending operations with a variety of blend modes for RGBA colors.
dmsrc/iconforge.dm Updates macros and documentation to include new generate_dmi and flatten flags.
Comments suppressed due to low confidence (1)

dmsrc/iconforge.dm:6

  • Typo in documentation: 'heplful' should be corrected to 'helpful'.
/// These hashes can be heplful for 'smart' caching (see rustg_iconforge_cache_valid), but require extra computation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0