Add "icon sheet" asset type

This asset class bundles entire dmi files worth of icons together into a single CSS file using inline data urls.  Much faster than sending dozens of files.
Also changed it so we don't need a hard coded list of all types of asset daturms.
This commit is contained in:
Leshana
2020-04-25 12:15:05 -04:00
parent 4d67e76a50
commit 63f0f69ce8
2 changed files with 69 additions and 3 deletions

View File

@@ -6,9 +6,11 @@ SUBSYSTEM_DEF(assets)
var/list/preload = list() var/list/preload = list()
/datum/controller/subsystem/assets/Initialize(timeofday) /datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple)) for(var/type in typesof(/datum/asset))
var/datum/asset/A = new type() var/datum/asset/A = type
A.register() if (type != initial(A._abstract))
get_asset_datum(type)
preload = cache.Copy() //don't preload assets generated during the round preload = cache.Copy() //don't preload assets generated during the round

View File

@@ -137,8 +137,12 @@ You can set verify to TRUE if you want send() to sleep until the client has the
return new type() return new type()
return asset_datums[type] return asset_datums[type]
/datum/asset
var/_abstract = /datum/asset // Marker so we don't instanatiate abstract types
/datum/asset/New() /datum/asset/New()
asset_datums[type] = src asset_datums[type] = src
register()
/datum/asset/proc/register() /datum/asset/proc/register()
return return
@@ -148,6 +152,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
//If you don't need anything complicated. //If you don't need anything complicated.
/datum/asset/simple /datum/asset/simple
_abstract = /datum/asset/simple
var/assets = list() var/assets = list()
var/verify = FALSE var/verify = FALSE
@@ -157,6 +162,65 @@ You can set verify to TRUE if you want send() to sleep until the client has the
/datum/asset/simple/send(client) /datum/asset/simple/send(client)
send_asset_list(client,assets,verify) send_asset_list(client,assets,verify)
//
// iconsheet Assets - For making lots of icon states available at once without sending a thousand tiny files.
//
/datum/asset/iconsheet
_abstract = /datum/asset/iconsheet
var/name // Name of the iconsheet. Asset will be named after this.
var/verify = FALSE
/datum/asset/iconsheet/register(var/list/sprites)
if (!name)
CRASH("iconsheet [type] cannot register without a name")
if (!islist(sprites))
CRASH("iconsheet [type] cannot register without a sprites list")
var/res_name = "iconsheet_[name].css"
var/fname = "data/iconsheets/[res_name]"
fdel(fname)
text2file(generate_css(sprites), fname)
register_asset(res_name, fcopy_rsc(fname))
fdel(fname)
/datum/asset/iconsheet/send(client/C)
if (!name)
return
send_asset_list(C, list("iconsheet_[name].css"), verify)
/datum/asset/iconsheet/proc/generate_css(var/list/sprites)
var/list/out = list(".[name]{display:inline-block;}")
for(var/sprite_id in sprites)
var/icon/I = sprites[sprite_id]
var/data_url = "'data:image/png;base64,[icon2base64(I)]'"
out += ".[name].[sprite_id]{width:[I.Width()]px;height:[I.Height()]px;background-image:url([data_url]);}"
return out.Join("\n")
/datum/asset/iconsheet/proc/build_sprite_list(icon/I, list/directions, prefix = null)
if (length(prefix))
prefix = "[prefix]-"
if (!directions)
directions = list(SOUTH)
var/sprites = list()
for (var/icon_state_name in icon_states(I))
for (var/direction in directions)
var/suffix = (directions.len > 1) ? "-[dir2text(direction)]" : ""
var/sprite_name = "[prefix][icon_state_name][suffix]"
var/icon/sprite = icon(I, icon_state=icon_state_name, dir=direction, frame=1, moving=FALSE)
if (!sprite || !length(icon_states(sprite))) // that direction or state doesn't exist
continue
sprites[sprite_name] = sprite
return sprites
// Get HTML link tag for including the iconsheet css file.
/datum/asset/iconsheet/proc/css_tag()
return "<link rel='stylesheet' href='iconsheet_[name].css' />"
// get HTML tag for showing an icon
/datum/asset/iconsheet/proc/icon_tag(icon_state, dir = SOUTH)
return "<span class='[name] [icon_state]-[dir2text(dir)]'></span>"
//DEFINITIONS FOR ASSET DATUMS START HERE. //DEFINITIONS FOR ASSET DATUMS START HERE.
/datum/asset/simple/pda /datum/asset/simple/pda