diff --git a/src/srctools/fgd.py b/src/srctools/fgd.py index 931a28b0..572c9a2c 100644 --- a/src/srctools/fgd.py +++ b/src/srctools/fgd.py @@ -1785,18 +1785,18 @@ def parse( if value_kind == 'input': for tags, io_def in Snippet.lookup_multi(tok.error, 'input', fgd.snippet_input, key): io_tags_map = entity.inputs.setdefault(io_def.name.casefold(), {}) - io_tags_map[tags] = io_def + io_tags_map[tags] = io_def.copy() elif value_kind == 'output': for tags, io_def in Snippet.lookup_multi(tok.error, 'output', fgd.snippet_output, key): io_tags_map = entity.outputs.setdefault(io_def.name.casefold(), {}) - io_tags_map[tags] = io_def + io_tags_map[tags] = io_def.copy() elif value_kind == 'keyvalue': for tags, kv_def in Snippet.lookup_multi(tok.error, 'keyvalue', fgd.snippet_keyvalue, key): kv_tags_map = entity.keyvalues.setdefault(kv_def.name.casefold(), {}) if not kv_tags_map: # New, add to the ordering. entity.kv_order.append(kv_def.name.casefold()) - kv_tags_map[tags] = kv_def + kv_tags_map[tags] = kv_def.copy() else: raise tok.error( 'Unknown snippet type "{}". Valid in this context: ' diff --git a/tests/test_fgd.py b/tests/test_fgd.py index 41840e69..c43a891b 100644 --- a/tests/test_fgd.py +++ b/tests/test_fgd.py @@ -605,6 +605,10 @@ def test_snippet_keyvalues(py_c_token) -> None: start_open(boolean) : "Start Open": 1 height(int) : "Height" : 48 ] + + @PointClass = some_ent [ + #snippet keyvalue InvStartEnabled + ] """}) fgd.parse_file(fsys, fsys['snippets.fgd']) assert fgd.snippet_keyvalue == { @@ -638,6 +642,12 @@ def test_snippet_keyvalues(py_c_token) -> None: ), ] } + # Check it was included, but is not shared. + snip_kv = fgd.snippet_keyvalue['invstartenabled'][0].value[1] + ent_kv = fgd.entities['some_ent'].kv['start_enabled', {'-engine'}] + assert ent_kv == snip_kv + assert ent_kv is not snip_kv + assert ent_kv.val_list is not snip_kv.val_list def test_snippet_io(py_c_token) -> None: @@ -647,6 +657,11 @@ def test_snippet_io(py_c_token) -> None: @snippet input uSer1 = FireUser1[+tag](void) : "Causes this entity's OnUser1 output to be fired." @snippet output uSer1 = OnUser1[-tag](void) : "Fired in response to FireUser1 input." + + @PointClass = some_ent [ + #snippet input User1 + #snippet output User1 + ] """}) fgd.parse_file(fsys, fsys['snippets.fgd']) assert fgd.snippet_input == { @@ -669,6 +684,17 @@ def test_snippet_io(py_c_token) -> None: )) )] } + # Check they were included correctly, but are not shared (since these are mutable). + [tags, snip_in] = fgd.snippet_input['user1'][0].value + [tags, snip_out] = fgd.snippet_output['user1'][0].value + ent = fgd.entities['some_ent'] + ent_inp = ent.inp['fireuser1', {'tag'}] + ent_out = ent.out['onuser1', ()] + assert ent_inp == snip_in + assert ent_inp is not snip_in, 'Shared!' + assert ent_out == snip_out + assert ent_out is not snip_out, 'Shared!' + def test_snippet_no_dup(py_c_token) -> None: """Test duplicating snippets is not allowed."""