Skip to content

Commit

Permalink
515 (the reckoning) (#230)
Browse files Browse the repository at this point in the history
Co-authored-by: Zonespace <[email protected]>
Co-authored-by: harryob <[email protected]>
Co-authored-by: harryob <[email protected]>
  • Loading branch information
4 people authored Apr 18, 2024
1 parent 0a95dda commit 1498abd
Show file tree
Hide file tree
Showing 30 changed files with 185 additions and 237 deletions.
2 changes: 0 additions & 2 deletions .github/alternate_byond_versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
# Format is version: map
# Example:
# 500.1337: runtimestation

515.1610: lv624
30 changes: 8 additions & 22 deletions .github/workflows/ci_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,30 +66,16 @@ jobs:

odlint:
name: Lint with OpenDream
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Get OpenDream Version
run: |
source dependencies.sh
echo "OPENDREAM_VERSION=$OPENDREAM_VERSION" >> $GITHUB_ENV
- name: Restore OpenDream cache
uses: actions/cache@v3
id: cache-od
- uses: actions/checkout@v4
- uses: robinraju/[email protected]
with:
path: ~/OpenDream
key: ${{ runner.os }}-opendream-${{ env.OPENDREAM_VERSION }}
- name: Download OpenDream
if: steps.cache-od.outputs.cache-hit != 'true'
run: |
bash tools/ci/download_od.sh
- name: Setup OpenDream
if: steps.cache-od.outputs.cache-hit != 'true'
run: |
bash tools/ci/setup_od.sh
- name: Run OpenDream
run: |
bash tools/ci/run_od.sh
repository: "OpenDreamProject/OpenDream"
tag: "latest"
fileName: "DMCompiler_linux-x64.tar.gz"
extract: true
- run: ./DMCompiler_linux-x64/DMCompiler --suppress-unimplemented colonialmarines.dme

compile_all_maps:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
Expand Down
2 changes: 1 addition & 1 deletion .tgs.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version: 1
byond: "514.1588"
byond: "515.1627"
static_files:
- name: config
- name: data
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/__spacemandmm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@
/world/Del()
var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
if (debug_server)
LIBCALL(debug_server, "auxtools_shutdown")()
call_ext(debug_server, "auxtools_shutdown")()
. = ..()
9 changes: 0 additions & 9 deletions code/__DEFINES/_macros.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,8 @@

#define subtypesof(A) (typesof(A) - A)

#ifdef EXPERIMENT_515_DONT_CACHE_REF
/// Takes a datum as input, returns its ref string
#define text_ref(datum) ref(datum)
#else
/// Takes a datum as input, returns its ref string, or a cached version of it
/// This allows us to cache \ref creation, which ensures it'll only ever happen once per datum, saving string tree time
/// It is slightly less optimal then a []'d datum, but the cost is massively outweighed by the potential savings
/// It will only work for datums mind, for datum reasons
/// : because of the embedded typecheck
#define text_ref(datum) (isdatum(datum) ? (datum:cached_ref ||= "\ref[datum]") : ("\ref[datum]"))
#endif

#define addToListNoDupe(L, index) if(L) L[index] = null; else L = list(index)

Expand Down
4 changes: 0 additions & 4 deletions code/__HELPERS/nameof.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@
/**
* NAMEOF that actually works in static definitions because src::type requires src to be defined
*/
#if DM_VERSION >= 515
#define NAMEOF_STATIC(datum, X) (nameof(type::##X))
#else
#define NAMEOF_STATIC(datum, X) (#X || ##datum.##X)
#endif
59 changes: 4 additions & 55 deletions code/_byond_version_compat.dm
Original file line number Diff line number Diff line change
@@ -1,56 +1,17 @@
// This file contains defines allowing targeting byond versions newer than the supported

//Update this whenever you need to take advantage of more recent byond features
#define MIN_COMPILER_VERSION 514
#define MIN_COMPILER_BUILD 1588
#define MIN_COMPILER_VERSION 515
#define MIN_COMPILER_BUILD 1627
#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM) && !defined(OPENDREAM)
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
#error You need version 514.1588 or higher
#endif

/*
#if (DM_VERSION == 514 && DM_BUILD > 1575 && DM_BUILD <= 1577)
#error Your version of BYOND currently has a crashing issue that will prevent you from running Dream Daemon test servers.
#error We require developers to test their content, so an inability to test means we cannot allow the compile.
#error Please consider downgrading to 514.1575 or lower.
#endif
*/

/*
// Keep savefile compatibilty at minimum supported level
#if DM_VERSION >= 515
/savefile/byond_version = MIN_COMPILER_VERSION
#endif
*/

// 515 split call for external libraries into call_ext
#if DM_VERSION < 515
#define LIBCALL call
#else
#define LIBCALL call_ext
#error Your version of BYOND is too out-of-date to compile this project. Go to https://www.byond.com/download and update.
#error You need version 515.1627 or higher
#endif

// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof()
// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global.

#if DM_VERSION < 515

/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (.proc/##X)
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (.verb/##X)

/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X)
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X)

/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)

#else

/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (nameof(.proc/##X))
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
Expand All @@ -64,16 +25,4 @@
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)

#endif

#if (DM_VERSION == 515)
/// fcopy will crash on 515 linux if given a non-existant file, instead of returning 0 like on 514 linux or 515 windows
/// var case matches documentation for fcopy.
/world/proc/__fcopy(Src, Dst)
if (istext(Src) && !fexists(Src))
return 0
return fcopy(Src, Dst)

#define fcopy(Src, Dst) world.__fcopy(Src, Dst)

#endif
24 changes: 1 addition & 23 deletions code/_experiments.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,7 @@
// Any flag you see here can be flipped with the `-D` CLI argument.
// For example, if you want to enable EXPERIMENT_MY_COOL_FEATURE, compile with -DEXPERIMENT_MY_COOL_FEATURE

// EXPERIMENT_515_QDEL_HARD_REFERENCE
// - Hold a hard reference for qdeleted items, and check ref_count, rather than using refs. Requires 515+.

// EXPERIMENT_515_DONT_CACHE_REF
// - Avoids `text_ref` caching, aided by improvements to ref() speed in 515.

#if DM_VERSION < 515

// You can't X-macro custom names :(
#ifdef EXPERIMENT_515_QDEL_HARD_REFERENCE
#warn EXPERIMENT_515_QDEL_HARD_REFERENCE is only available on 515+
#undef EXPERIMENT_515_QDEL_HARD_REFERENCE
#endif

#ifdef EXPERIMENT_515_DONT_CACHE_REF
#warn EXPERIMENT_515_DONT_CACHE_REF is only available on 515+
#undef EXPERIMENT_515_DONT_CACHE_REF
#endif

#elif defined(UNIT_TESTS)

//#define EXPERIMENT_515_QDEL_HARD_REFERENCE
#define EXPERIMENT_515_DONT_CACHE_REF
#if defined(UNIT_TESTS)

#endif

Expand Down
24 changes: 24 additions & 0 deletions code/controllers/configuration/entries/general.dm
Original file line number Diff line number Diff line change
Expand Up @@ -620,3 +620,27 @@ This maintains a list of ip addresses that are able to bypass topic filtering.
protection = CONFIG_ENTRY_HIDDEN|CONFIG_ENTRY_LOCKED

/datum/config_entry/flag/auto_profile

/datum/config_entry/number/client_warn_version
default = null
min_val = 500

/datum/config_entry/number/client_warn_build
default = null
min_val = 0

/datum/config_entry/string/client_warn_message
default = "Your version of BYOND may have issues or be blocked from accessing this server in the future."

/datum/config_entry/flag/client_warn_popup

/datum/config_entry/number/client_error_version
default = null
min_val = 500

/datum/config_entry/string/client_error_message
default = "Your version of BYOND is too old, may have issues, and is blocked from accessing this server."

/datum/config_entry/number/client_error_build
default = null
min_val = 0
5 changes: 4 additions & 1 deletion code/controllers/mc/globals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
GLOB = src

var/datum/controller/exclude_these = new
gvars_datum_in_built_vars = exclude_these.vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order))
// I know this is dumb but the nested vars list hangs a ref to the datum. This fixes that
var/list/controller_vars = exclude_these.vars.Copy()
controller_vars["vars"] = null
gvars_datum_in_built_vars = controller_vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order))
QDEL_IN(exclude_these, 0) //signal logging isn't ready

log_world("[vars.len - gvars_datum_in_built_vars.len] global variables")
Expand Down
44 changes: 8 additions & 36 deletions code/controllers/subsystem/garbage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,6 @@ SUBSYSTEM_DEF(garbage)
pass_counts[i] = 0
fail_counts[i] = 0

#ifdef EXPERIMENT_515_QDEL_HARD_REFERENCE
// 1 from the hard reference in the queue, and 1 from the variable used before this
#define IS_DELETED(datum, _) (refcount(##datum) == 2)
#else
#define IS_DELETED(datum, gcd_at_time) (isnull(##datum) || ##datum.gc_destroyed != gcd_at_time)
#endif

/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_FILTER)
if (level == GC_QUEUE_FILTER)
delslasttick = 0
Expand All @@ -162,7 +155,7 @@ SUBSYSTEM_DEF(garbage)

lastlevel = level

//We do this rather then for(var/refID in queue) because that sort of for loop copies the whole list.
//We do this rather then for(var/list/ref_info in queue) because that sort of for loop copies the whole list.
//Normally this isn't expensive, but the gc queue can grow to 40k items, and that gets costly/causes overrun.
for (var/i in 1 to length(queue))
var/list/L = queue[i]
Expand All @@ -173,21 +166,15 @@ SUBSYSTEM_DEF(garbage)
continue

var/queued_at_time = L[GC_QUEUE_ITEM_QUEUE_TIME]

if(queued_at_time > cut_off_time)
break // Everything else is newer, skip them
count++

#ifdef EXPERIMENT_515_QDEL_HARD_REFERENCE
var/datum/D = L[GC_QUEUE_ITEM_REF]
#else
var/GCd_at_time = L[GC_QUEUE_ITEM_GCD_DESTROYED]
var/refID = L[GC_QUEUE_ITEM_REF]
var/datum/D
D = locate(refID)
#endif

if (IS_DELETED(D, GCd_at_time)) // So if something else coincidently gets the same ref, it's not deleted by mistake

// 1 from the hard reference in the queue, and 1 from the variable used before this
// If that's all we've got, send er off
if (refcount(D) == 2)
++gcedlasttick
++totalgcs
pass_counts[level]++
Expand Down Expand Up @@ -221,11 +208,7 @@ SUBSYSTEM_DEF(garbage)
var/type = D.type
var/datum/qdel_item/I = items[type]

var/message = "## TESTING: GC: -- [text_ref(D)] | [type] was unable to be GC'd --"
#if DM_VERSION >= 515
message = "[message] (ref count of [refcount(D)])"
#endif
log_world(message)
log_world("## TESTING: GC: -- [text_ref(D)] | [type] was unable to be GC'd -- (ref count of [refcount(D)])")

#ifdef TESTING
for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage
Expand Down Expand Up @@ -261,8 +244,6 @@ SUBSYSTEM_DEF(garbage)
queue.Cut(1,count+1)
count = 0

#undef IS_DELETED

/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_FILTER)
if (isnull(D))
return
Expand All @@ -271,20 +252,11 @@ SUBSYSTEM_DEF(garbage)
return
var/queue_time = world.time

#ifdef EXPERIMENT_515_QDEL_HARD_REFERENCE
var/refid = D
#else
var/refid = text_ref(D)
#endif

var/static/uid = 0
uid = WRAP(uid+1, 1, SHORT_REAL_LIMIT - 1)
if (D.gc_destroyed <= 0)
D.gc_destroyed = uid
D.gc_destroyed = queue_time

var/list/queue = queues[level]

queue[++queue.len] = list(queue_time, refid, D.gc_destroyed) // not += for byond reasons
queue[++queue.len] = list(queue_time, D, D.gc_destroyed) // not += for byond reasons

//this is mainly to separate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/D, force)
Expand Down
8 changes: 8 additions & 0 deletions code/controllers/subsystem/ticker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ SUBSYSTEM_DEF(ticker)

var/current_state = GAME_STATE_STARTUP //State of current round used by process()
var/force_ending = FALSE //Round was ended by admin intervention

/// If TRUE, there is no lobby phase, the game starts immediately.
var/start_immediately = FALSE

var/bypass_checks = FALSE //Bypass mode init checks
var/setup_failed = FALSE //If the setup has failed at any point
var/setup_started = FALSE
Expand Down Expand Up @@ -79,6 +83,10 @@ SUBSYSTEM_DEF(ticker)
var/mob/new_player/player = i
if(player.ready) // TODO: port this == PLAYER_READY_TO_PLAY)
++totalPlayersReady

if(start_immediately)
time_left = 0

if(time_left < 0 || delay_start)
return

Expand Down
7 changes: 0 additions & 7 deletions code/datums/datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@
*/
var/list/cooldowns

#ifndef EXPERIMENT_515_DONT_CACHE_REF
/// A cached version of our \ref
/// The brunt of \ref costs are in creating entries in the string tree (a tree of immutable strings)
/// This avoids doing that more then once per datum by ensuring ref strings always have a reference to them after they're first pulled
var/cached_ref
#endif

/// A weak reference to another datum
var/datum/weakref/weak_reference

Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/autolathe.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
recipe.resources[material] = I.matter[material] //Doesn't take more if it's just a sheet or something. Get what you put in.
else
recipe.resources[material] = round(I.matter[material]*1.25) // More expensive to produce than they are to recycle.
qdel(I)
QDEL_NULL(I)

//Create parts for lathe.
for(var/component in components)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@

/obj/item/device/pdt_locator_tube/Destroy()
linked_bracelet = null
QDEL_NULL(battery)
return ..()

/obj/item/clothing/accessory/pdt_bracelet
Expand Down
4 changes: 4 additions & 0 deletions code/game/objects/items/reagent_containers/food/snacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2760,6 +2760,10 @@
var/list/boxes = list() // If the boxes are stacked, they come here
var/boxtag = ""

/obj/item/pizzabox/Destroy(force)
QDEL_NULL(pizza)
return ..()

/obj/item/pizzabox/update_icon()

overlays = list()
Expand Down
Loading

0 comments on commit 1498abd

Please sign in to comment.