Optimize more listmos procs, rename a few vars

This commit is contained in:
Bjorn Neergaard
2016-02-05 18:56:41 -06:00
parent 7822b1ee75
commit bb10a81310
3 changed files with 101 additions and 119 deletions
@@ -7,42 +7,36 @@ What are the archived variables for?
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
var/list/cached_gases_list = null
var/list/gas_meta = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
var/list/gas_cache = null
/proc/gaslist(gasid)
if(!cached_gases_list)
cached_gases_list = new /list(meta_gas_info.len)
/proc/gaslist(id)
if(!gas_cache)
gas_cache = new(gas_meta.len)
if(!gas_cache[id])
if(!gas_meta[id])
CRASH("Gas [id] does not exist!")
if(!cached_gases_list[gasid])
if(!meta_gas_info[gasid])
CRASH("Error: no such gas type! Type : [gasid]")
var/list/gas = new(3)
gas[MOLES] = 0
gas[ARCHIVE] = 0
gas[GAS_META] = gas_meta[id]
gas_cache[id] = gas
var/list/new_gas_list = new(3)
new_gas_list[MOLES] = 0
new_gas_list[ARCHIVE] = 0
new_gas_list[GAS_META] = meta_gas_info[gasid]
cached_gases_list[gasid] = new_gas_list
var/list/gas = cached_gases_list[gasid]
. = gas.Copy()
var/list/cached_gas = gas_cache[id]
. = cached_gas.Copy()
/datum/gas_mixture
var/list/gases
var/temperature //in Kelvin
var/tmp/temperature_archived
var/volume
var/last_share
var/tmp/fuel_burnt
var/list/gases = list()
var/temperature = 0 // degrees Kelvin
var/tmp/temperature_archived = 0
var/volume = 0
var/last_share = 0
var/tmp/fuel_burnt = 0
/datum/gas_mixture/New(Volume = CELL_VOLUME)
. = ..()
gases = new
temperature = 0
temperature_archived = 0
volume = Volume
last_share = 0
fuel_burnt = 0
/datum/gas_mixture/New(vol = CELL_VOLUME)
..()
volume = vol
//listmos procs
@@ -60,12 +54,12 @@ var/list/cached_gases_list = null
assert_gas(id)
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
//gas list for this id.
//gas list for this id. This can clobber existing gases.
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
/datum/gas_mixture/proc/add_gas(gas_id)
gases[gas_id] = gaslist(gas_id)
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
/datum/gas_mixture/proc/add_gases()
for(var/id in args)
add_gas(id)
@@ -77,11 +71,10 @@ var/list/cached_gases_list = null
/datum/gas_mixture/proc/garbage_collect()
var/list/cached_gases = gases
for(var/id in cached_gases)
var/gas = cached_gases[id]
if(gas[MOLES] <= 0 && gas[ARCHIVE] <= 0)
if(cached_gases[id][MOLES] <= 0 && cached_gases[id][ARCHIVE] <= 0)
cached_gases -= id
//PV=nRT - related procedures
//PV = nRT
/datum/gas_mixture/proc/heat_capacity()
var/list/cached_gases = gases
. = 0
@@ -101,29 +94,28 @@ var/list/cached_gases_list = null
. += cached_gases[id][MOLES]
/datum/gas_mixture/proc/return_pressure()
if(volume>0)
return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
return 0
. = 0
if(volume > 0)
. = total_moles() * R_IDEAL_GAS_EQUATION * temperature / volume
/datum/gas_mixture/proc/return_temperature()
return temperature
. = temperature
/datum/gas_mixture/proc/return_volume()
return max(0, volume)
. = max(0, volume)
/datum/gas_mixture/proc/thermal_energy()
return temperature*heat_capacity()
. = temperature * heat_capacity()
//Procedures used for very specific events
/datum/gas_mixture/proc/react(atom/dump_location)
var/list/cached_gases = gases //this speeds things up because >byond
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
if(temperature < TCMB)
temperature = TCMB
if(cached_gases["agent_b"] && temperature > 900 && cached_gases["plasma"] && cached_gases["co2"])
if(cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY)
var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05)
@@ -267,9 +259,13 @@ var/list/cached_gases_list = null
/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample)
//Copies variables from sample
/datum/gas_mixture/proc/copy_from_turf(turf/model)
//Copies all gas info from the turf into the gas list along with temperature
/datum/gas_mixture/proc/share(datum/gas_mixture/sharer)
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
//Return: amount of gas exchanged (+ if sharer received)
/datum/gas_mixture/proc/mimic(turf/model)
//Similar to share(...), except the model is not modified
//Return: amount of gas exchanged
@@ -287,9 +283,6 @@ var/list/cached_gases_list = null
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
//returns: a string indicating what check failed, or "" if check passes
/datum/gas_mixture/proc/copy_from_turf(turf/model)
//Copies all gas info from the turf into the gas list along with copying temperature, then archives
/datum/gas_mixture/archive()
var/list/cached_gases = gases
@@ -300,8 +293,9 @@ var/list/cached_gases_list = null
. = 1
/datum/gas_mixture/merge(datum/gas_mixture/giver)
. = 0
if(!giver)
return 0
return
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
@@ -319,10 +313,11 @@ var/list/cached_gases_list = null
. = 1
/datum/gas_mixture/remove(amount)
. = null
var/sum = total_moles()
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
return
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new
@@ -338,8 +333,9 @@ var/list/cached_gases_list = null
. = removed
/datum/gas_mixture/remove_ratio(ratio)
. = null
if(ratio <= 0)
return null
return
ratio = min(ratio, 1)
var/list/cached_gases = gases
@@ -370,14 +366,25 @@ var/list/cached_gases_list = null
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/sample_gases = sample.gases
var/list/copied_gases = list()
temperature = sample.temperature
for(var/id in sample_gases)
assert_gas(id)
cached_gases[id][MOLES] = sample_gases[id][MOLES]
copied_gases += id
cached_gases &= copied_gases
cached_gases &= sample_gases
. = 1
/datum/gas_mixture/copy_from_turf(turf/model)
var/list/cached_gases = gases
assert_gases(arglist(hardcoded_gases))
temperature = model.temperature
cached_gases["o2"][MOLES] = model.oxygen
cached_gases["n2"][MOLES] = model.nitrogen
cached_gases["plasma"][MOLES] = model.toxins
cached_gases["co2"][MOLES] = model.carbon_dioxide
cached_gases &= hardcoded_gases
. = 1
@@ -391,38 +398,37 @@ var/list/cached_gases_list = null
if(!sharer)
return
var/moved_moles = 0
var/abs_moved_moles = 0
//make this local to the proc for sanic speed
var/list/sharercache = sharer.gases
var/list/selfcache = gases
var/list/cached_gases = gases
var/list/sharer_gases = sharer.gases
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
var/temperature_delta = temperature_archived - sharer.temperature_archived
var/abs_temperature_delta = abs(temperature_delta)
var/old_self_heat_capacity = 0
var/old_sharer_heat_capacity = 0
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
for(var/sharer_id in sharercache-selfcache)
add_gas(sharer_id) //we can use add_gas() because we're looping only through the IDs not in our cache
var/moved_moles = 0
var/abs_moved_moles = 0
//GAS TRANSFER
for(var/id in selfcache)
if(!sharercache[id]) //checking here prevents an uneeded proc call if the check fails.
for(var/id in sharer_gases - cached_gases) // create gases not in our cache
add_gas(id)
for(var/id in cached_gases) // transfer gases
if(!sharer_gases[id]) //checking here prevents an uneeded proc call if the check fails.
sharer.add_gas(id)
var/gas = selfcache[id]
var/sharergas = sharercache[id]
var/gas = cached_gases[id]
var/sharergas = sharer_gases[id]
var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/gas_heat_capacity = delta * gas[GAS_META][META_GAS_SPECIFIC_HEAT]
if(delta > 0)
heat_capacity_self_to_sharer += gas_heat_capacity
@@ -437,7 +443,7 @@ var/list/cached_gases_list = null
last_share = abs_moved_moles
//THERMAL ENERGY TRANSFER
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
@@ -453,9 +459,9 @@ var/list/cached_gases_list = null
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
. = delta_pressure*R_IDEAL_GAS_EQUATION/volume
. = delta_pressure * R_IDEAL_GAS_EQUATION / volume
garbage_collect()
sharer.garbage_collect()
@@ -467,13 +473,13 @@ var/list/cached_gases_list = null
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
//transfer of thermal energy (via conduction) between self and sharer
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/temperature_delta = temperature_archived - sharer.temperature_archived
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity_archived()
var/sharer_heat_capacity = sharer.heat_capacity_archived()
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*delta_temperature* \
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
@@ -481,23 +487,23 @@ var/list/cached_gases_list = null
//thermal energy of the system (self and sharer) is unchanged
/datum/gas_mixture/temperature_mimic(turf/model, conduction_coefficient)
var/delta_temperature = (temperature - model.temperature)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/temperature_delta = temperature - model.temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*delta_temperature* \
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
/datum/gas_mixture/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
var/delta_temperature = (temperature_archived - sharer.temperature)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/temperature_delta = temperature_archived - sharer.temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*delta_temperature* \
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
@@ -508,12 +514,12 @@ var/list/cached_gases_list = null
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
var/list/cached_gases = gases
for(var/id in cached_gases|sample_gases)
for(var/id in cached_gases | sample_gases) // only compare gases we both have
var/gas_moles = cached_gases[id] ? cached_gases[id][datatype] : 0
var/sample_moles = sample_gases[id] ? sample_gases[id][datatype] : 0
var/delta = abs(gas_moles - sample_moles)/(adjacents+1)
if(delta > MINIMUM_AIR_TO_SUSPEND && \
delta > gas_moles*MINIMUM_AIR_RATIO_TO_SUSPEND)
delta > gas_moles * MINIMUM_AIR_RATIO_TO_SUSPEND)
return id
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
@@ -528,50 +534,28 @@ var/list/cached_gases_list = null
temp = temperature_archived
sample_temp = sample.temperature_archived
var/delta_temperature = abs(temp-sample_temp)
if((delta_temperature > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
delta_temperature > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND*temp)
var/temperature_delta = abs(temp - sample_temp)
if((temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND * temp)
return "temp"
/datum/gas_mixture/copy_from_turf(turf/model)
assert_gases(arglist(hardcoded_gases))
var/list/cached_gases = gases
cached_gases["o2"][MOLES] = model.oxygen
cached_gases["n2"][MOLES] = model.nitrogen
cached_gases["plasma"][MOLES] = model.toxins
cached_gases["co2"][MOLES] = model.carbon_dioxide
for(var/id in cached_gases-hardcoded_gases)
cached_gases[id][MOLES] = 0 //turfs don't account for anything other than the four old hardcoded gases
temperature = model.temperature
garbage_collect()
//Takes the amount of the gas you want to PP as an argument
//So I don't have to do some hacky switches/defines/magic strings
//eg:
//Tox_PP = get_partial_pressure(gas_mixture.toxins)
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
//Does handle trace gases!
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure*R_IDEAL_GAS_EQUATION*temperature)/BREATH_VOLUME
//Reverse of the above
/datum/gas_mixture/proc/get_true_breath_pressure(breath_pp)
return (breath_pp*BREATH_VOLUME)/(R_IDEAL_GAS_EQUATION*temperature)
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME
//inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature)
//Mathematical proofs:
/*
get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp
get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
10/20*5 = 2.5
10 = 2.5/5*20
*/
@@ -1,7 +1,7 @@
var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases, which were at one time hardcoded
/proc/meta_gas_list()
var/meta_list = new /list
. = list()
for(var/gas_path in subtypesof(/datum/gas))
var/list/gas_info = new(4)
var/datum/gas/g = gas_path
@@ -11,9 +11,7 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
gas_info[META_GAS_MOLES_VISIBLE] = initial(g.moles_visible)
if(gas_info[META_GAS_MOLES_VISIBLE] != null)
gas_info[META_GAS_OVERLAY] = new /obj/effect/overlay/gas(initial(g.gas_overlay))
meta_list[initial(g.id)] = gas_info
. = meta_list
.[initial(g.id)] = gas_info
/*||||||||||||||/----------\||||||||||||||*\
||||||||||||||||[GAS DATUMS]||||||||||||||||
@@ -146,10 +146,10 @@
if("filter")
filter_type = ""
var/filter_name = "nothing"
var/mode = params["mode"]
if(mode in meta_gas_info)
filter_type = mode
filter_name = meta_gas_info[mode][META_GAS_NAME]
var/gas = params["mode"]
if(gas in gas_meta)
filter_type = gas
filter_name = gas_meta[gas][META_GAS_NAME]
investigate_log("was set to filter [filter_name] by [key_name(usr)]", "atmos")
. = TRUE
update_icon()