Raised This Month: $12 Target: $400
 3% 

[SP] ConfigMap: StringMap & SMCParser


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
nergal
Veteran Member
Join Date: Apr 2012
Old 11-18-2019 , 20:47   [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #1

presenting ConfigMap which is a StringMap Tree very much similar to KeyValues.

Difference is that it only works with strings as values and stringmaps as sections.


API:
Code:
ConfigMap(const char[] filename);

int GetSize(const char[] key_path);

int Get(const char[] key_path, char[] buffer, int buf_size);

ConfigMap GetSection(const char[] key_path);

KeyValType GetKeyValType(const char[] key_path);

int GetInt(const char[] key_path, int& i, int base=10);

int GetFloat(const char[] key_path, float& f);

stock void DeleteCfg(ConfigMap& cfg, bool clear_only=false);
Accessing values and sections is easy:

assume this config:
Code:
"root" {
    "value1"    "howdy"
    "section1" {
        "value1"    "hi"
    }
    
    "section2" {
        "subsection1" {
            "value1"    "bonjour"
        }
    }
}
to access the value "howdy", use the key path string: "root.value1"
to access the value "hi", use the key path string: "root.section1.value1"
to access the value "bonjour", use the key path string: "root.section2.subsection1.value1"

to reduce having to use these key path strings all the time on frequently used subsections, use `GetSection` to save the ConfigMap of a subsection, there is no need to free the instance to the subsection.

Download Link
Tutorial on how to use it.

Features:
Iterating key-values by number.
Retrieving keys in a performant manner.
Partial string interpolation.
Math parsing with custom variables.
__________________

Last edited by nergal; 08-26-2023 at 17:03. Reason: new version.
nergal is offline
MAGNAT2645
Senior Member
Join Date: Nov 2015
Location: AlliedMods.net
Old 11-21-2019 , 10:13   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #2

Is there any way to include ConfigMap to Voice Changer? I just don't want to use KeyValues loop every time NormalSoundHook is called.
__________________
MAGNAT2645 is offline
nergal
Veteran Member
Join Date: Apr 2012
Old 06-29-2020 , 13:55   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #3

Quote:
Originally Posted by MAGNAT2645 View Post
Is there any way to include ConfigMap to Voice Changer? I just don't want to use KeyValues loop every time NormalSoundHook is called.
yes! you gotta compile it with Voice Changer. I also want to add that ConfigMap is loop-friendlier than KeyValues since all you need to do get a specific section and iterate that section, here's an example of what I mean from VSH2 which uses ConfigMap:

Code:
	static char download_keys[][] = {
		"downloads.sounds",
		"downloads.models",
		"downloads.materials"
	};
	
	for( int i; i<sizeof(download_keys); i++ ) {
		ConfigMap download_map = g_vsh2.m_hCfg.GetSection(download_keys[i]);
		if( download_map != null ) {
			for( int n; n<download_map.Size; n++ ) {
				char index[10];
				Format(index, sizeof(index), "%i", n);
				int value_size = download_map.GetSize(index);
				char[] filepath = new char[value_size];
				if( download_map.Get(index, filepath, value_size) ) {
					switch( i ) {
						case 0: PrepareSound(filepath);
						case 1: PrepareModel(filepath);
						case 2: PrepareMaterial(filepath);
					}
				}
			}
		}
	}
Have it iterate over an array of keys that map to a section, grab that section, and iterate over it as needed
__________________

Last edited by nergal; 06-29-2020 at 13:56.
nergal is offline
nergal
Veteran Member
Join Date: Apr 2012
Old 09-24-2020 , 14:38   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #4

I've updated the OP with the latest code and even converted the library into an include file.
I've also provided a tutorial link on all the capabilities of ConfigMap and how to use it.
__________________
nergal is offline
MAGNAT2645
Senior Member
Join Date: Nov 2015
Location: AlliedMods.net
Old 09-25-2020 , 07:59   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #5

You can put __nullable__ into methodmap definition like
Code:
methodmap ConfigMap < StringMap __nullable__ {
and then you are able to use
ConfigMap hCfg = new ConfigMap();

EDIT: Nevermind, it seems that Handle-typed methodmaps can use new keyword without __nullable__.
PLS add GetBool method (at least as wrapper around GetInt)
__________________

Last edited by MAGNAT2645; 09-26-2020 at 06:02.
MAGNAT2645 is offline
nergal
Veteran Member
Join Date: Apr 2012
Old 09-26-2020 , 18:23   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #6

Quote:
Originally Posted by MAGNAT2645 View Post
PLS add GetBool method (at least as wrapper around GetInt)
Sounds good, have it work from a number (1 and 0) or the words 'true' and 'false?
__________________
nergal is offline
MAGNAT2645
Senior Member
Join Date: Nov 2015
Location: AlliedMods.net
Old 09-27-2020 , 02:34   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #7

I have this stock:
Code:
#define _BOOL(%1) view_as< bool >( %1 )

stock bool StringToBool(const char[] str, bool simple=true) {
	if ( simple )
		return _BOOL( StringToInt( str ) );

	if ( strcmp( str, "true", false ) == 0 || strcmp( str, "yes", false ) == 0 || strcmp( str , "on", false ) == 0 || str[0] == '1' )
		return true;

	return false;
}
Sometimes i use words like "true" in my configs, sometimes only "0" and "1". You can use same method if you want.
__________________

Last edited by MAGNAT2645; 09-27-2020 at 02:37. Reason: Added _BOOL define
MAGNAT2645 is offline
nergal
Veteran Member
Join Date: Apr 2012
Old 09-27-2020 , 18:21   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #8

Quote:
Originally Posted by MAGNAT2645 View Post
I have this stock:
Code:
#define _BOOL(%1) view_as< bool >( %1 )

stock bool StringToBool(const char[] str, bool simple=true) {
	if ( simple )
		return _BOOL( StringToInt( str ) );

	if ( strcmp( str, "true", false ) == 0 || strcmp( str, "yes", false ) == 0 || strcmp( str , "on", false ) == 0 || str[0] == '1' )
		return true;

	return false;
}
Sometimes i use words like "true" in my configs, sometimes only "0" and "1". You can use same method if you want.
it's not bad but what would I return if there's a failure? I guess I could have it pass something like a reference to a bool and the method itself returns an int.

Another thing is that your method just checks if the word is "true" or something synonymous and returns false otherwise, which means someone could just put "peanut butter" as a value and trying to make that as a bool would return a value of false lol.

Treating a string value as a bool would require the value of the key to actually represent something that makes sense as a boolean value as opposed to having specific words being able to be treated as a boolean value while everything else is just assumed boolean false.
__________________
nergal is offline
MAGNAT2645
Senior Member
Join Date: Nov 2015
Location: AlliedMods.net
Old 09-28-2020 , 07:09   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #9

That's just a stock which returns true (only if string treated as true) or false (in any other case), you don't have to use it. It was just an example of simple/advanced conversion.
__________________

Last edited by MAGNAT2645; 09-28-2020 at 07:11.
MAGNAT2645 is offline
nergal
Veteran Member
Join Date: Apr 2012
Old 09-28-2020 , 13:09   Re: [SP] ConfigMap: StringMap & SMCParser
Reply With Quote #10

Quote:
Originally Posted by MAGNAT2645 View Post
That's just a stock which returns true (only if string treated as true) or false (in any other case), you don't have to use it. It was just an example of simple/advanced conversion.
alright, put this code in your cfgmap.inc and test out how it goes:

Code:
	public int GetBool(const char[] key_path, bool& b, bool simple=true) {
		if( this==null ) {
			return 0;
		}
		PackVal val;
		bool result = this.GetVal(key_path, val);
		if( result && val.tag==KeyValType_Value ) {
			val.data.Reset();
			char[] strval = new char[val.size];
			val.data.ReadString(strval, val.size);
			if( simple ) {
				b = StringToInt(strval) != 0;
			} else {
				if( !strcmp(strval, "true", false) || !strcmp(strval, "1", false) ) {
					b = true;
				} else if( !strcmp(strval, "false", false) || !strcmp(strval, "0", false) ) {
					b = false;
				} else {
					return 0;
				}
			}
			return val.size - 1;
		}
		return 0;
	}
__________________

Last edited by nergal; 09-28-2020 at 13:10.
nergal is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 05:26.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode