Files
Bubberstation/code/controllers/subsystem/processing/instruments.dm
Watermelon914 6c017cf1e1 Refactors subsystems to use dependency-ordering to determine init order. Subsystems can now declare their own dependencies. (#90268)
## About The Pull Request
As the title says.
`init_order` is no more, subsystems ordering now depends on their
declared dependencies.
Subsystems can now declare which other subsystems need to init before
them using a list and the subsystem's typepath
I.e.
```dm
dependencies = list(
    /datum/controller/subsystem/atoms,
    /datum/controller/subsystem/mapping
)
```
The reverse can also be done, if a subsystem must initialize after your
own:
```dm
dependents = list(
    /datum/controller/subsystem/atoms
)
```
Cyclical dependencies are not allowed and will throw an error on
initialization if one is found.
There's also a debug tool to visualize the dependency graph, although
it's a bit basic:

![image](https://github.com/user-attachments/assets/80c854d9-c2a5-4f2f-92db-a031e9a8e257)

Subsystem load ordering can still be controlled using `init_stage`, some
subsystems use this in cases where they must initialize first or last
regardless of dependencies. An error will be thrown if a subsystem has
an `init_stage` before one of their dependencies.

## Why It's Good For The Game
Makes dealing with subsystem dependencies easier, and reduces the chance
of making a dependency error when needing to shift around subsystem
inits.

## Changelog
🆑
refactor: Refactored subsystem initialization
/🆑
2025-04-03 17:04:30 -04:00

60 lines
2.3 KiB
Plaintext

PROCESSING_SUBSYSTEM_DEF(instruments)
name = "Instruments"
wait = 0.5
flags = SS_KEEP_TIMING
priority = FIRE_PRIORITY_INSTRUMENTS
/// List of all instrument data, associative id = datum
var/static/list/datum/instrument/instrument_data = list()
/// List of all song datums.
var/static/list/datum/song/songs = list()
/// Max lines in songs
var/static/musician_maxlines = 600
/// Max characters per line in songs
var/static/musician_maxlinechars = 300
/// Deciseconds between hearchecks. Too high and instruments seem to lag when people are moving around in terms of who can hear it. Too low and the server lags from this.
var/static/musician_hearcheck_mindelay = 5
/// Maximum instrument channels total instruments are allowed to use. This is so you don't have instruments deadlocking all sound channels.
var/static/max_instrument_channels = MAX_INSTRUMENT_CHANNELS
/// Current number of channels allocated for instruments
var/static/current_instrument_channels = 0
/// Single cached list for synthesizer instrument ids, so you don't have to have a new list with every synthesizer.
var/static/list/synthesizer_instrument_ids
var/static/list/note_sustain_modes = list(
SUSTAIN_LINEAR,
SUSTAIN_EXPONENTIAL,
)
/datum/controller/subsystem/processing/instruments/Initialize()
initialize_instrument_data()
synthesizer_instrument_ids = get_allowed_instrument_ids()
return SS_INIT_SUCCESS
/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S)
songs += S
/datum/controller/subsystem/processing/instruments/proc/on_song_del(datum/song/S)
songs -= S
/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data()
for(var/path in subtypesof(/datum/instrument))
var/datum/instrument/I = path
if(initial(I.abstract_type) == path)
continue
I = new path
I.Initialize()
if(!I.id)
qdel(I)
continue
instrument_data[I.id] = I
CHECK_TICK
/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path)
return instrument_data["[id_or_path]"]
/datum/controller/subsystem/processing/instruments/proc/reserve_instrument_channel(datum/instrument/I)
if(current_instrument_channels > max_instrument_channels)
return
. = SSsounds.reserve_sound_channel(I)
if(!isnull(.))
current_instrument_channels++