1 2 /* 3 Copyright (C) 2009 - 2018 by Yurii Chernyi <terraninfo@terraninfo.net> 4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY. 12 13 See the COPYING file for more details. 14 */ 15 16 /** 17 * AI Support engine - creating specific ai components from config 18 * @file 19 */ 20 21 #pragma once 22 23 #include "ai/composite/component.hpp" 24 #include "ai/contexts.hpp" 25 26 #include <algorithm> 27 #include <iterator> 28 29 //============================================================================ 30 31 namespace ai { 32 33 class rca_context; 34 class ai_context; 35 class component; 36 37 class engine : public component { 38 public: 39 engine( readonly_context &context, const config &cfg ); 40 41 42 virtual ~engine(); 43 44 virtual bool is_ok() const; 45 46 static void parse_aspect_from_config( readonly_context &context, const config &cfg, const std::string &id, std::back_insert_iterator<std::vector< aspect_ptr >> b ); 47 48 49 static void parse_goal_from_config( readonly_context &context, const config &cfg, std::back_insert_iterator<std::vector< goal_ptr >> b ); 50 51 52 static void parse_candidate_action_from_config( rca_context &context, const config &cfg, std::back_insert_iterator<std::vector< candidate_action_ptr >> b ); 53 54 55 static void parse_engine_from_config( readonly_context &context, const config &cfg, std::back_insert_iterator<std::vector< engine_ptr >> b ); 56 57 58 static void parse_stage_from_config( ai_context &context, const config &cfg, std::back_insert_iterator<std::vector< stage_ptr >> b ); 59 60 61 //do not override that method in subclasses which cannot create aspects 62 virtual void do_parse_aspect_from_config( const config &cfg, const std::string &id, std::back_insert_iterator< std::vector< aspect_ptr>> b ); 63 64 65 //do not override that method in subclasses which cannot create candidate_actions 66 virtual void do_parse_candidate_action_from_config( rca_context &context, const config &cfg, std::back_insert_iterator<std::vector< candidate_action_ptr >> b ); 67 68 //do not override that method in subclasses which cannot create goals 69 virtual void do_parse_goal_from_config( const config &cfg, std::back_insert_iterator<std::vector< goal_ptr >> b ); 70 71 //do not override that method in subclasses which cannot create engines 72 virtual void do_parse_engine_from_config( const config &cfg, std::back_insert_iterator<std::vector< engine_ptr >> b ); 73 74 75 //do not override that method in subclasses which cannot create stages 76 virtual void do_parse_stage_from_config( ai_context &context, const config &cfg, std::back_insert_iterator<std::vector< stage_ptr >> b ); 77 78 //do not override that method in subclasses which cannot evaluate formulas 79 virtual std::string evaluate(const std::string& str); 80 81 readonly_context& get_readonly_context(); 82 83 /** 84 * set ai context (which is not available during early initialization) 85 */ 86 virtual void set_ai_context(ai_context_ptr context); 87 88 virtual ai_context_ptr get_ai_context(); 89 /** 90 * serialize 91 */ 92 virtual config to_config() const; 93 94 get_id() const95 virtual std::string get_id() const 96 { return id_; } 97 get_engine() const98 virtual std::string get_engine() const 99 { return engine_; } 100 get_name() const101 virtual std::string get_name() const 102 { return name_; } 103 104 protected: 105 readonly_context &ai_; 106 ai_context_ptr ai_context_; 107 108 /** name of the engine which has created this engine*/ 109 std::string engine_; 110 std::string id_; 111 std::string name_; 112 }; 113 114 115 class engine_factory; 116 117 class engine_factory{ 118 bool is_duplicate(const std::string &name); 119 public: 120 typedef std::shared_ptr< engine_factory > factory_ptr; 121 typedef std::map<std::string, factory_ptr> factory_map; 122 typedef std::pair<const std::string, factory_ptr> factory_map_pair; 123 get_list()124 static factory_map& get_list() { 125 static factory_map *engine_factories; 126 if (engine_factories==nullptr) { 127 engine_factories = new factory_map; 128 } 129 return *engine_factories; 130 } 131 132 virtual engine_ptr get_new_instance( readonly_context &ai, const config &cfg ) = 0; 133 virtual engine_ptr get_new_instance( readonly_context &ai, const std::string& name ) = 0; 134 engine_factory(const std::string & name)135 engine_factory( const std::string &name ) 136 { 137 if (is_duplicate(name)) { 138 return; 139 } 140 factory_ptr ptr_to_this(this); 141 get_list().emplace(name,ptr_to_this); 142 } 143 ~engine_factory()144 virtual ~engine_factory() {} 145 }; 146 147 148 template<class ENGINE> 149 class register_engine_factory : public engine_factory { 150 public: register_engine_factory(const std::string & name)151 register_engine_factory( const std::string &name ) 152 : engine_factory( name ) 153 { 154 } 155 get_new_instance(readonly_context & ai,const config & cfg)156 virtual engine_ptr get_new_instance( readonly_context &ai, const config &cfg ){ 157 engine_ptr e = std::make_shared<ENGINE>(ai, cfg); 158 if (!e->is_ok()) { 159 return engine_ptr(); 160 } 161 return e; 162 } 163 get_new_instance(readonly_context & ai,const std::string & name)164 virtual engine_ptr get_new_instance( readonly_context &ai, const std::string& name ){ 165 config cfg; 166 cfg["name"] = name; 167 cfg["engine"] = "cpp"; // @Crab: what is the purpose of this line(neph) 168 return std::make_shared<ENGINE>(ai, cfg); 169 } 170 }; 171 172 } //end of namespace ai 173