Added component class interface, which is needed to support [modify_ai]
This commit is contained in:
parent
2eebb9c0d7
commit
d2ef421454
15 changed files with 324 additions and 28 deletions
|
@ -53,6 +53,8 @@
|
|||
<Unit filename="..\..\src\ai\composite\ai.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\aspect.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\aspect.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\component.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\component.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\contexts.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\contexts.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\engine.cpp" />
|
||||
|
|
|
@ -82,6 +82,8 @@
|
|||
<Unit filename="..\..\src\ai\composite\ai.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\aspect.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\aspect.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\component.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\component.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\contexts.cpp" />
|
||||
<Unit filename="..\..\src\ai\composite\contexts.hpp" />
|
||||
<Unit filename="..\..\src\ai\composite\engine.cpp" />
|
||||
|
|
|
@ -4059,6 +4059,34 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\component.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)\ai\composite\"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)\ai\composite\"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug (fast)|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)\ai\composite\"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\contexts.cpp"
|
||||
>
|
||||
|
@ -5870,6 +5898,10 @@
|
|||
RelativePath="..\..\src\ai\composite\aspect.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\component.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ai\composite\contexts.hpp"
|
||||
>
|
||||
|
|
|
@ -224,6 +224,7 @@ SET(wesnoth-main_SRC
|
|||
ai/actions.cpp
|
||||
ai/composite/ai.cpp
|
||||
ai/composite/aspect.cpp
|
||||
ai/composite/component.cpp
|
||||
ai/composite/contexts.cpp
|
||||
ai/composite/engine.cpp
|
||||
ai/composite/engine_default.cpp
|
||||
|
|
|
@ -45,6 +45,7 @@ wesnoth_source = \
|
|||
ai/actions.cpp \
|
||||
ai/composite/ai.cpp \
|
||||
ai/composite/aspect.cpp \
|
||||
ai/composite/component.cpp \
|
||||
ai/composite/contexts.cpp \
|
||||
ai/composite/engine.cpp \
|
||||
ai/composite/engine_default.cpp \
|
||||
|
|
|
@ -150,6 +150,7 @@ wesnoth_sources = Split("""
|
|||
ai/actions.cpp
|
||||
ai/composite/ai.cpp
|
||||
ai/composite/aspect.cpp
|
||||
ai/composite/component.cpp
|
||||
ai/composite/contexts.cpp
|
||||
ai/composite/engine.cpp
|
||||
ai/composite/engine_default.cpp
|
||||
|
|
144
src/ai/composite/component.cpp
Normal file
144
src/ai/composite/component.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Composite AI component
|
||||
* @file ai/composite/component.cpp
|
||||
*/
|
||||
|
||||
#include "component.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "../formula/ai.hpp"
|
||||
#include "../../log.hpp"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
namespace ai {
|
||||
|
||||
static lg::log_domain log_ai_composite_component("ai/composite/component");
|
||||
#define DBG_AI_COMPOSITE LOG_STREAM(debug, log_ai_composite_component)
|
||||
#define LOG_AI_COMPOSITE LOG_STREAM(info, log_ai_composite_component)
|
||||
#define ERR_AI_COMPOSITE LOG_STREAM(err, log_ai_composite_component)
|
||||
|
||||
/*
|
||||
[modify_ai]
|
||||
component = "aspect['aggression']"
|
||||
property = "facet"
|
||||
action= "add"
|
||||
[cfg]...[/cfg]
|
||||
[/modify_ai]
|
||||
|
||||
[modify_ai]
|
||||
component = "stage['fallback']
|
||||
action = "change"
|
||||
[/modify_ai]
|
||||
|
||||
[modify_ai]
|
||||
component = "aspect['avoid'].facet['zzz']"
|
||||
action = "change"
|
||||
[cfg]...[/cfg]
|
||||
[/modify_ai]
|
||||
|
||||
[modify_ai]
|
||||
component = "aspect['aggression']"
|
||||
property = facet['zzzz']
|
||||
action = "delete"
|
||||
[cfg]...[/cfg]
|
||||
[/modify_ai]
|
||||
|
||||
[modify_ai]
|
||||
component = "aspect['aggression']"
|
||||
action = "add"
|
||||
property = "facet"
|
||||
where="end"
|
||||
[cfg]...[/cfg]
|
||||
[/modify_ai]
|
||||
*/
|
||||
|
||||
|
||||
static component *find_component(component *root, const std::string &path, path_element &tail)
|
||||
{
|
||||
if (root==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//match path elements in [modify_ai] tag
|
||||
boost::regex re("([^\\.^\\[]+)(\\['([^\\]]+)'\\]|\\[(\\d*)\\]|())");
|
||||
boost::sregex_token_iterator i(path.begin(), path.end(), re, 0);
|
||||
boost::sregex_token_iterator j;
|
||||
|
||||
component *c = root;
|
||||
|
||||
std::vector< path_element > elements;
|
||||
while(i != j)
|
||||
{
|
||||
path_element pe;
|
||||
pe.property = *i++;
|
||||
pe.id = *i++;
|
||||
pe.position = *i++;
|
||||
elements.push_back(pe);
|
||||
}
|
||||
if (elements.size()<1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector< path_element >::iterator k_max = elements.end()-1;
|
||||
for (std::vector< path_element >::iterator k = elements.begin(); k!=k_max; ++k) {
|
||||
//not last
|
||||
c = c->get_child(*k);
|
||||
if (c==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
tail = *k_max;
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool component_manager::add_component(component *root, const std::string &path, const config &cfg)
|
||||
{
|
||||
path_element tail;
|
||||
component *c = find_component(root,path,tail);
|
||||
if (c==NULL) {
|
||||
return false;
|
||||
}
|
||||
return c->add_child(tail, cfg);
|
||||
|
||||
}
|
||||
|
||||
bool component_manager::change_component(component *root, const std::string &path, const config &cfg)
|
||||
{
|
||||
path_element tail;
|
||||
component *c = find_component(root,path,tail);
|
||||
if (c==NULL) {
|
||||
return false;
|
||||
}
|
||||
return c->change_child(tail,cfg);
|
||||
}
|
||||
|
||||
bool component_manager::delete_component(component *root, const std::string &path)
|
||||
{
|
||||
path_element tail;
|
||||
component *c = find_component(root,path,tail);
|
||||
if (c==NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return c->delete_child(tail);
|
||||
}
|
||||
|
||||
|
||||
} //end of namespace ai
|
69
src/ai/composite/component.hpp
Normal file
69
src/ai/composite/component.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Yurii Chernyi <terraninfo@terraninfo.net>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ai/composite/component.hpp
|
||||
* A component of the AI framework
|
||||
*/
|
||||
|
||||
#ifndef AI_COMPOSITE_COMPONENT_HPP_INCLUDED
|
||||
#define AI_COMPOSITE_COMPONENT_HPP_INCLUDED
|
||||
|
||||
#include "../../global.hpp"
|
||||
|
||||
#include "../game_info.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
//silence "inherits via dominance" warnings
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
namespace ai {
|
||||
|
||||
|
||||
struct path_element {
|
||||
std::string property;
|
||||
std::string id;
|
||||
std::string position;
|
||||
};
|
||||
|
||||
|
||||
class component {
|
||||
public:
|
||||
component() {};
|
||||
virtual ~component() {};
|
||||
virtual component* get_child(const path_element &child) = 0;
|
||||
virtual bool change_child(const path_element &child, const config &cfg) = 0;
|
||||
virtual bool add_child(const path_element &child, const config &cfg) = 0;
|
||||
virtual bool delete_child(const path_element &child) = 0;
|
||||
};
|
||||
|
||||
class component_manager {
|
||||
public:
|
||||
static bool add_component(component *root, const std::string &path, const config &cfg);
|
||||
static bool change_component(component *root, const std::string &path, const config &cfg);
|
||||
static bool delete_component(component *root, const std::string &path);
|
||||
};
|
||||
|
||||
} //end of namespace ai
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -119,6 +119,7 @@ std::string engine::evaluate(const std::string& /*str*/)
|
|||
}
|
||||
|
||||
|
||||
|
||||
std::string engine::get_name() const
|
||||
{
|
||||
return "null";
|
||||
|
@ -138,4 +139,11 @@ config engine::to_config() const
|
|||
return cfg;
|
||||
}
|
||||
|
||||
|
||||
component* find_component( component */*root*/, const std::string &/*path*/ )
|
||||
{
|
||||
LOG_AI_COMPOSITE_ENGINE << "find_component is not implemented by this engine" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} //end of namespace ai
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace ai {
|
|||
|
||||
class rca_context;
|
||||
class ai_context;
|
||||
class component;
|
||||
|
||||
class engine {
|
||||
public:
|
||||
|
@ -77,7 +78,7 @@ public:
|
|||
//do not override that method in subclasses which cannot create stages
|
||||
virtual void do_parse_stage_from_config( ai_context &context, const config &cfg, std::back_insert_iterator<std::vector< stage_ptr > > b );
|
||||
|
||||
//do not override that method in subclasse which cannot evaluate formulas
|
||||
//do not override that method in subclasses which cannot evaluate formulas
|
||||
virtual std::string evaluate(const std::string& str);
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../serialization/parser.hpp"
|
||||
#include "../serialization/preprocessor.hpp"
|
||||
#include "../team.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
@ -262,13 +263,7 @@ bool configuration::parse_side_config(const config& original_cfg, config &cfg )
|
|||
aspect_cfg.add_child("default",c);
|
||||
}
|
||||
|
||||
LOG_AI_CONFIGURATION << "Finally, applying [modify_ai] tags to configuration"<< std::endl;
|
||||
foreach (const config &mod_ai, parsed_cfg.child_range("modify_ai")){
|
||||
//do ai config modification without redeployement
|
||||
modify_ai_configuration(mod_ai,parsed_cfg);
|
||||
}
|
||||
|
||||
DBG_AI_CONFIGURATION << "After applying [modify_ai] tags, config contains:"<< std::endl << parsed_cfg << std::endl;
|
||||
DBG_AI_CONFIGURATION << "Done parsing side config, it contains:"<< std::endl << parsed_cfg << std::endl;
|
||||
LOG_AI_CONFIGURATION << "Done parsing side config"<< std::endl;
|
||||
|
||||
cfg = parsed_cfg;
|
||||
|
@ -323,12 +318,6 @@ bool configuration::upgrade_side_config_from_1_07_02_to_1_07_03(config &cfg)
|
|||
return cfg;//in boolean context
|
||||
}
|
||||
|
||||
bool configuration::modify_ai_configuration(const config &/*mod_ai*/, config &/*parsed_cfg*/)
|
||||
{
|
||||
//@todo 1.7.4 implement
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void configuration::upgrade_aspect_configs_from_1_07_02_to_1_07_03(const config::const_child_itors &ai_parameters, config &parsed_cfg)
|
||||
{
|
||||
|
|
|
@ -97,17 +97,6 @@ public:
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* modify a config of the ai by applying rules in [modify_ai] tag
|
||||
* @param[in] mod_ai config containing the contents of the [modify_ai] tag
|
||||
* @param[in][out] cfg ai configuration to modify
|
||||
* @return was all ok?
|
||||
* @retval true success, cfg is guaranteed to be valid
|
||||
* @retval false failure
|
||||
*/
|
||||
static bool modify_ai_configuration(const config &mod_ai, config &cfg);
|
||||
|
||||
|
||||
/**
|
||||
* change a bunch of old aspect configs into a new-style [ai] snippet
|
||||
* @param[in] ai_parameters - old [ai] snippets
|
||||
|
|
|
@ -53,6 +53,11 @@ typedef boost::shared_ptr< interface > ai_ptr;
|
|||
class attack_analysis;
|
||||
typedef std::vector<attack_analysis> attacks_vector;
|
||||
|
||||
class readonly_context;
|
||||
class readwrite_context;
|
||||
class default_ai_context;
|
||||
class ai_context;
|
||||
|
||||
class aspect;
|
||||
class candidate_action;
|
||||
class engine;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "../replay.hpp"
|
||||
#include "../serialization/string_utils.hpp"
|
||||
#include "../statistics.hpp"
|
||||
#include "composite/component.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
@ -79,9 +80,16 @@ void holder::init( side_number side )
|
|||
}
|
||||
if (!this->ai_){
|
||||
ai_ = boost::shared_ptr<ai_composite>(new ai_composite(*default_ai_context_,cfg_));
|
||||
ai_->on_create();
|
||||
}
|
||||
if (!this->ai_) {
|
||||
|
||||
if (this->ai_) {
|
||||
ai_->on_create();
|
||||
foreach (const config &mod_ai, cfg_.child_range("modify_ai")) {
|
||||
modify_ai(mod_ai);
|
||||
}
|
||||
cfg_.clear_children("modify_ai");
|
||||
|
||||
} else {
|
||||
ERR_AI_MANAGER << describe_ai()<<"AI lazy initialization error!" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -135,6 +143,31 @@ void holder::modify_ai_config_old( const config::const_child_itors &ai_parameter
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void holder::modify_ai(const config &cfg)
|
||||
{
|
||||
if (this->readonly_context_ == NULL) {
|
||||
// if not initialized, initialize now.
|
||||
get_ai_ref();
|
||||
}
|
||||
|
||||
const std::string &act = cfg["action"];
|
||||
bool res = false;
|
||||
if (act == "add") {
|
||||
res = component_manager::add_component(NULL,cfg["path"],cfg.child("cfg"));
|
||||
} else if (act == "change") {
|
||||
res = component_manager::change_component(NULL,cfg["path"],cfg.child("cfg"));
|
||||
} else if (act == "delete") {
|
||||
res = component_manager::delete_component(NULL,cfg["path"]);
|
||||
} else {
|
||||
ERR_AI_MANAGER << "modify_ai tag has invalid 'action' attribute " << std::endl;
|
||||
}
|
||||
if (!res) {
|
||||
ERR_AI_MANAGER << "[modify_ai] failed"<< std::endl;
|
||||
DBG_AI_MANAGER << "[modify_ai] config is: "<< std::endl << cfg << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
config holder::to_config() const
|
||||
{
|
||||
if (!this->ai_) {
|
||||
|
@ -619,6 +652,13 @@ void manager::modify_active_ai_config_old_for_side ( side_number side, const con
|
|||
get_active_ai_holder_for_side(side).modify_ai_config_old(ai_parameters);
|
||||
}
|
||||
|
||||
|
||||
void manager::modify_active_ai_for_side ( side_number side, const config &cfg )
|
||||
{
|
||||
get_active_ai_holder_for_side(side).modify_ai(cfg);
|
||||
}
|
||||
|
||||
|
||||
std::string manager::get_active_ai_identifier_for_side( side_number side )
|
||||
{
|
||||
return get_active_ai_holder_for_side(side).get_ai_identifier();
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
|
||||
config to_config() const;
|
||||
|
||||
void modify_ai(const config& cfg);
|
||||
|
||||
const std::string get_ai_identifier() const;
|
||||
|
||||
private:
|
||||
|
@ -387,11 +389,21 @@ public:
|
|||
* This function is provided for backward-compatability with [modify_side][ai]...[/ai][/modify_side]
|
||||
* It can only add new facets to aspects
|
||||
* @param side side_number (1-based, as in game_info).
|
||||
* @param ai_parameters AI paramters to be modified.
|
||||
* @param ai_parameters AI parameters to be modified.
|
||||
*/
|
||||
static void modify_active_ai_config_old_for_side ( side_number side, const config::const_child_itors &ai_parameters );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Modifies AI parameters for active AI of the given @a side.
|
||||
* This function is a backend for [modify_ai] tag
|
||||
* @param side side_number (1-based, as in game_info).
|
||||
* @param cfg - content of [modify_ai] tag
|
||||
*/
|
||||
|
||||
static void modify_active_ai_for_side( ai::side_number, const config &cfg );
|
||||
|
||||
// =======================================================================
|
||||
// PROXY
|
||||
// =======================================================================
|
||||
|
|
Loading…
Add table
Reference in a new issue