Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.

Commit 058de2c

Browse files
committed
Expose entity properties as StringMultiMaps
1 parent 0029a9f commit 058de2c

3 files changed

Lines changed: 237 additions & 118 deletions

File tree

scripting/include/level_keyvalues.inc

Lines changed: 36 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,73 +3,51 @@
33
#endif
44
#define _level_keyvalues_included
55

6-
/**
7-
* Returns a copy of the KeyValues associated with the entity of a specified Hammer ID.
8-
* The KeyValues handle returned by the native is read-only; any changes made do not propagate
9-
* up to the shared plugin.
10-
*/
11-
native KeyValues LevelEntity_GetKeysByHammerID(int iHammerID);
6+
#include <more_adt>
127

13-
/**
14-
* A KeyValues-backed handle that returns and iterates over keys that match the given output
15-
* name, parsing the output value into its components while being iterated.
8+
/**
9+
* Wrapper for StringMultiMap that uses an intermediary parsing step to ensure all values are
10+
* strings.
1611
*/
17-
methodmap LevelEntityOutputIterator < KeyValues {
18-
/**
19-
* Creates an output iterator for a given Hammer ID.
20-
*/
21-
public LevelEntityOutputIterator(int hammerID, const char[] output) {
22-
KeyValues outputs = LevelEntity_GetKeysByHammerID(hammerID);
23-
if (outputs) {
24-
char keyBuffer[128], valueBuffer[128];
25-
outputs.GotoFirstSubKey(false);
26-
bool bNext;
27-
do {
28-
outputs.GetSectionName(keyBuffer, sizeof(keyBuffer));
29-
outputs.GetString(NULL_STRING, valueBuffer, sizeof(valueBuffer));
30-
31-
if (!StrEqual(keyBuffer, output)) {
32-
bNext = outputs.DeleteThis() != -1;
33-
} else {
34-
bNext = outputs.GotoNextKey(false);
35-
}
36-
} while (bNext);
37-
outputs.GotoFirstSubKey(false);
38-
}
39-
return view_as<LevelEntityOutputIterator>(outputs);
12+
methodmap LevelEntityKeyValues < StringMultiMap {
13+
public LevelEntityKeyValues() {
14+
return view_as<LevelEntityKeyValues>(new StringMultiMap());
4015
}
4116

42-
/**
43-
* Returns an output iterator for a given entity (reference), looking it up by its Hammer
44-
* ID.
45-
*/
46-
public static LevelEntityOutputIterator FromEntity(int entref, const char[] output) {
47-
int entity = EntRefToEntIndex(entref);
48-
return new LevelEntityOutputIterator(GetEntProp(entity, Prop_Data, "m_iHammerID"),
49-
output);
50-
}
51-
52-
/**
53-
* Parses the current output string, storing the values by reference and advancing to the
54-
* next key.
55-
*/
56-
public bool Next(char[] targetName, int targetNameLength,
57-
char[] inputName, int inputNameLength, char[] variantValue, int variantValueLength,
58-
float &delay, int &nFireCount) {
59-
char outputString[512];
60-
this.GetString(NULL_STRING, outputString, sizeof(outputString));
61-
62-
// this.GoBack() is a disgusting hack just to make sure it returns true on the last item
63-
return ParseEntityOutputString(outputString, targetName, targetNameLength, inputName,
64-
inputNameLength, variantValue, variantValueLength, delay, nFireCount)
65-
&& (this.GotoNextKey(false) || this.GoBack());
66-
}
17+
// TODO implementation -- for now make sure that you only use the string-related
18+
// getters / setters in StringMultiMap.
6719
}
6820

21+
/**
22+
* Called when a block of entity keys is finished parsing.
23+
* Changes to the StringMultiMap will be reflected in the level.
24+
*
25+
* @return Plugin_Changed to copy back changed values, Plugin_Stop to remove the entity.
26+
*/
27+
forward Action LevelEntity_OnEntityKeysParsed(LevelEntityKeyValues entity);
28+
29+
/**
30+
* Called when the entity string in `OnLevelInit` has been fully parsed out.
31+
* Plugins may call LevelEntity_InsertEntityKeys here to insert new entities into the entity
32+
* string.
33+
*/
34+
forward void LevelEntity_OnAllEntitiesParsed();
35+
36+
/**
37+
* Adds a new entity entry. All values should be strings.
38+
*/
39+
native void LevelEntity_InsertEntityKeys(LevelEntityKeyValues entity);
40+
41+
/**
42+
* Returns a copy of the KeyValues associated with the entity of a specified Hammer ID.
43+
* Any changes to the returned StringMultiMap handle will not be reflected in the level.
44+
*/
45+
native LevelEntityKeyValues LevelEntity_GetKeysByHammerID(int iHammerID);
46+
6947
/**
7048
* Returns a copy of the KeyValues associated with a given entity.
7149
*/
72-
stock KeyValues LevelEntity_GetKeysByEntity(int entref) {
50+
stock LevelEntityKeyValues LevelEntity_GetKeysByEntity(int entref) {
7351
int entity = EntRefToEntIndex(entref);
7452
return LevelEntity_GetKeysByHammerID(GetEntProp(entity, Prop_Data, "m_iHammerID"));
7553
}

scripting/include/more_adt.inc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#if defined __more_adt_ext
2+
#endinput
3+
#endif
4+
5+
/**
6+
* An iterator for the StringMultiMap.
7+
* Call its Next() function before performing any retrievals to ensure that it is valid.
8+
*/
9+
methodmap StringMultiMapIterator < Handle {
10+
public native bool Next();
11+
public native void GetKey(char[] name, int maxlen);
12+
13+
/**
14+
* Returns the string at the current iterator position.
15+
*/
16+
public native bool GetString(char[] value, int max_size, int& size = 0);
17+
public native void SetString(const char[] value);
18+
19+
public native bool GetValue(any &value);
20+
public native void SetValue(any value);
21+
22+
public native bool GetArray(any[] array, int max_size, int& size = 0);
23+
public native void SetArray(const any[] array, int num_items);
24+
25+
/**
26+
* Marks the element at the current iterator position as removed.
27+
* The entry will be removed on the next invocation of Next().
28+
*/
29+
public native void Remove();
30+
}
31+
32+
/**
33+
* Creates a multimap. A multimap is a container that can map keys to arbitrary values.
34+
*
35+
* There can be multiple entries in a multimap for a given key; only the first inerted entry
36+
* will be accessible through the Get*() methods. To retrieve all the entries for a given key,
37+
* use the GetKeyIterator() method to get an iterator over the specified key.
38+
*/
39+
methodmap StringMultiMap < Handle {
40+
public native StringMultiMap();
41+
42+
/**
43+
* Removes all elements with the key equivalent to `key`.
44+
*/
45+
public native void Remove(const char[] key);
46+
47+
/**
48+
* Adds a new value with the specified `key`.
49+
*/
50+
public native void AddValue(const char[] key, any value);
51+
52+
/**
53+
* Returns true iff the first entry associated with a key is a cell value, populating the
54+
* passed-in by-ref `value` argument.
55+
*/
56+
public native bool GetValue(const char[] key, any &value);
57+
58+
/**
59+
* Adds a new string value with the specified key.
60+
*/
61+
public native void AddString(const char[] key, const char[] value);
62+
63+
/**
64+
* Returns true iff the first entry associated with a key is a string value, filling the
65+
* passed-in `value` buffer.
66+
*/
67+
public native bool GetString(const char[] key, char[] value, int max_size, int& size = 0);
68+
69+
public native void AddArray(const char[] key, const any[] array, int num_items);
70+
public native void GetArray(const char[] key, any[] array, int max_size, int& size = 0);
71+
72+
/**
73+
* Returns an interator over all keys. Will still return a valid StringMultiMapIterator
74+
* handle even if the StringMultiMap is empty.
75+
*/
76+
public native StringMultiMapIterator GetIterator();
77+
78+
/**
79+
* Returns an iterator for elements matching a specific key.
80+
* (Wrapper for std::multimap::equal_range.)
81+
*/
82+
public native StringMultiMapIterator GetKeyIterator(const char[] key);
83+
}
84+
85+
public Extension __ext_madt = {
86+
name = "More ADTs",
87+
file = "madt.ext",
88+
#if defined AUTOLOAD_EXTENSIONS
89+
autoload = 1,
90+
#else
91+
autoload = 0,
92+
#endif
93+
#if defined REQUIRE_EXTENSIONS
94+
required = 1,
95+
#else
96+
required = 0,
97+
#endif
98+
};
99+
100+
#if !defined REQUIRE_EXTENSIONS
101+
public void __ext_madt_SetNTVOptional() {
102+
}
103+
#endif

0 commit comments

Comments
 (0)