Пример #1
0
	// returns a variable_access that cannot be used to change the game variables
	variable_access_create get_variable_access_write(const std::string& varname)
	{
		assert(this != NULL);
		activate_scope_variable(varname);
		return variable_access_create(varname, variables_);
	}
Пример #2
0
	///Used to delete variables.
	variable_access_throw get_variable_access_throw(const std::string& varname)
	{
		activate_scope_variable(varname);
		return variable_access_throw(varname, variables_);
	}
Пример #3
0
	// returns a variable_access that cannot be used to change the game variables
	variable_access_const get_variable_access_read(const std::string& varname) const
	{
		assert(this != NULL);
		activate_scope_variable(varname);
		return variable_access_const(varname, variables_);
	}
Пример #4
0
variable_info::variable_info(const std::string& varname,
		bool force_valid, TYPE validation_type) :
	vartype(validation_type),
	is_valid(false),
	key(),
	explicit_index(false),
	index(0),
	vars(NULL)
{
	assert(repos != NULL);
	activate_scope_variable(varname);

	vars = &resources::gamedata->variables_;
	key = varname;
	std::string::const_iterator itor = std::find(key.begin(),key.end(),'.');
	int dot_index = key.find('.');

	bool force_length = false;
	// example varname = "unit_store.modifications.trait[0]"
	while(itor != key.end()) { // subvar access
		std::string element=key.substr(0,dot_index);
		key = key.substr(dot_index+1);

		size_t inner_index = 0;
		const std::string::iterator index_start = std::find(element.begin(),element.end(),'[');
		const bool inner_explicit_index = index_start != element.end();
		if(inner_explicit_index) {
			const std::string::iterator index_end = std::find(index_start,element.end(),']');
			const std::string index_str(index_start+1,index_end);
			inner_index = static_cast<size_t>(lexical_cast_default<int>(index_str));
			if(inner_index > game_config::max_loop) {
				ERR_NG << "variable_info: index greater than " << game_config::max_loop
					   << ", truncated\n";
				inner_index = game_config::max_loop;
			}
			element = std::string(element.begin(),index_start);
		}

		size_t size = vars->child_count(element);
		if(size <= inner_index) {
			if(force_valid) {
				// Add elements to the array until the requested size is attained
				if(inner_explicit_index || key != "length") {
					for(; size <= inner_index; ++size) {
						vars->add_child(element);
					}
				}
			} else if(inner_explicit_index) {
				WRN_NG << "variable_info: invalid WML array index, "
					<< varname << std::endl;
				return;
			} else if(varname.length() >= 7 && varname.substr(varname.length()-7) == ".length") {
				// require '.' to avoid matching suffixes -> requires varname over key to always find length
				// return length 0 for non-existent WML array (handled below)
				force_length = true;
			} else {
				WRN_NG << "variable_info: retrieving member of non-existent WML container, "
				<< varname << std::endl;
				return;
			}
		}
		if((!inner_explicit_index && key == "length") || force_length) {
			switch(vartype) {
			case variable_info::TYPE_ARRAY:
			case variable_info::TYPE_CONTAINER:
				WRN_NG << "variable_info: using reserved WML variable as wrong type, "
					<< varname << std::endl;
				is_valid = force_valid || resources::gamedata->temporaries_.child(varname);
				break;
			case variable_info::TYPE_SCALAR:
			default:
				// Store the length of the array as a temporary variable
				resources::gamedata->temporaries_[varname] = int(size);
				is_valid = true;
				break;
			}
			key = varname;
			vars = &resources::gamedata->temporaries_;
			return;
		}

		vars = &vars->child(element, inner_index);
		itor = std::find(key.begin(),key.end(),'.');
		dot_index = key.find('.');
	} // end subvar access

	const std::string::iterator index_start = std::find(key.begin(),key.end(),'[');
	explicit_index = index_start != key.end();
	if(explicit_index) {
		const std::string::iterator index_end = std::find(index_start,key.end(),']');
		const std::string index_str(index_start+1,index_end);
		index = static_cast<size_t>(lexical_cast_default<int>(index_str));
		if(index > game_config::max_loop) {
			ERR_NG << "variable_info: index greater than " << game_config::max_loop
				   << ", truncated\n";
			index = game_config::max_loop;
		}
		key = std::string(key.begin(),index_start);
		size_t size = vars->child_count(key);
		if(size <= index) {
			if(!force_valid) {
				WRN_NG << "variable_info: invalid WML array index, " << varname << std::endl;
				return;
			}
			for(; size <= index; ++size) {
				vars->add_child(key);
			}
		}
		switch(vartype) {
		case variable_info::TYPE_ARRAY:
			vars = &vars->child(key, index);
			key = "__array";
			is_valid = force_valid || vars->child(key);
			break;
		case variable_info::TYPE_SCALAR:
			vars = &vars->child(key, index);
			key = "__value";
			is_valid = force_valid || vars->has_attribute(key);
			break;
		case variable_info::TYPE_CONTAINER:
		case variable_info::TYPE_UNSPECIFIED:
		default:
			is_valid = true;
			return;
		}
		if (force_valid) {
			WRN_NG << "variable_info: using explicitly indexed "
				"container as wrong WML type, " << varname << '\n';
		}
		explicit_index = false;
		index = 0;
	} else {
		// Final variable is not an explicit index [...]
		switch(vartype) {
		case variable_info::TYPE_ARRAY:
		case variable_info::TYPE_CONTAINER:
			is_valid = force_valid || vars->child(key);
			break;
		case variable_info::TYPE_SCALAR:
			is_valid = force_valid || vars->has_attribute(key);
			break;
		case variable_info::TYPE_UNSPECIFIED:
		default:
			is_valid = true;
			break;
		}
	}
}