25 #ifndef GOBY_MIDDLEWARE_APPLICATION_INTERFACE_H
26 #define GOBY_MIDDLEWARE_APPLICATION_INTERFACE_H
31 #include <sys/types.h>
34 #include <boost/format.hpp>
52 template <
typename App>
61 template <
typename App,
62 typename Configurator = middleware::ProtobufConfigurator<typename App::ConfigType>>
63 int run(
int argc,
char* argv[])
65 return run<App>(Configurator(argc, argv));
93 virtual void run() = 0;
107 void quit(
int return_value = 0)
110 return_value_ = return_value;
122 throw(
goby::Exception(
"No lat_origin and lon_origin defined for requested UTMGeodesy"));
128 std::string
app_name() {
return app3_base_configuration_->name(); }
134 template <
typename App>
140 void configure_logger();
141 void configure_glog_file();
142 void check_rotate_glog_file();
146 static std::unique_ptr<Config> app_cfg_;
147 static std::unique_ptr<protobuf::AppConfig> app3_base_configuration_;
153 static std::unique_ptr<std::ofstream> fout_;
157 std::unique_ptr<goby::util::UTMGeodesy> geodesy_;
163 template <
typename Config>
168 template <
typename Config>
169 std::unique_ptr<goby::middleware::protobuf::AppConfig>
177 if (app3_base_configuration_->has_geodesy())
179 app3_base_configuration_->geodesy().lon_origin_with_units()});
181 if (!app3_base_configuration_->IsInitialized())
184 glog.
is_debug2() &&
glog <<
"Application: constructed with PID: " << getpid() << std::endl;
185 glog.
is_debug1() &&
glog <<
"App name is " << app3_base_configuration_->name() << std::endl;
186 glog.
is_debug2() &&
glog <<
"Configuration is: " << app_cfg_->DebugString() << std::endl;
196 app3_base_configuration_->glog_config().tty_verbosity()),
199 if (app3_base_configuration_->glog_config().show_gui())
202 if (app3_base_configuration_->glog_config().has_file_log())
203 configure_glog_file();
205 if (app3_base_configuration_->glog_config().show_dccl_log())
212 if (app3_base_configuration_->glog_config().has_file_log() &&
213 app3_base_configuration_->glog_config().file_log().has_log_rotate_sec() &&
217 configure_glog_file();
223 const auto& file_log = app3_base_configuration_->glog_config().file_log();
224 std::string file_format_str;
226 if (file_log.has_file_dir() && !file_log.file_dir().empty())
228 auto file_dir = file_log.file_dir();
229 if (file_dir.back() !=
'/')
231 file_format_str = file_dir + file_log.file_name();
235 file_format_str = file_log.file_name();
238 boost::format file_format(file_format_str);
240 if (file_format_str.find(
"%1") == std::string::npos)
242 glog <<
"file_name string must contain \"%1%\" which is expanded to the current "
243 "application start time (e.g. 20190201T184925). Erroneous file_name is: "
244 << file_format_str << std::endl;
246 file_format.exceptions(boost::io::all_error_bits ^
247 (boost::io::too_many_args_bit | boost::io::too_few_args_bit));
249 std::string file_name =
251 std::string file_symlink = (file_format %
"latest" % app3_base_configuration_->name()).
str();
255 fout_.reset(
new std::ofstream(file_name.c_str()));
257 if (!fout_->is_open())
258 glog.
is_die() &&
glog <<
"cannot write glog output to requested file: " << file_name
261 remove(file_symlink.c_str());
262 int result = symlink(realpath(file_name.c_str(), NULL), file_symlink.c_str());
264 glog.
is_warn() &&
glog <<
"Cannot create symlink to latest file. Continuing onwards anyway"
269 if (file_log.has_log_rotate_sec())
270 next_log_rotate_time_ =
274 template <
typename Config>
284 sigset_t signal_mask;
285 sigemptyset(&signal_mask);
286 sigaddset(&signal_mask, SIGWINCH);
287 pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
289 this->pre_initialize();
291 this->post_initialize();
296 this->check_rotate_glog_file();
298 this->pre_finalize();
300 this->post_finalize();
301 return return_value_;
304 template <
typename App>
307 int return_value = 0;
323 std::cout << cfgtor.
str() << std::endl;
328 App::app_cfg_.reset(
new typename App::ConfigType(cfgtor.
cfg()));
329 App::app3_base_configuration_.reset(
333 if (App::app3_base_configuration_->simulation().
time().use_sim_time())
337 App::app3_base_configuration_->simulation().time().warp_factor();
338 if (App::app3_base_configuration_->simulation().
time().has_reference_microtime())
340 std::chrono::system_clock::time_point(std::chrono::microseconds(
341 App::app3_base_configuration_->simulation().
time().reference_microtime()));
346 return_value = app.__run();
348 catch (std::exception&
e)
351 std::cerr <<
"Application:: uncaught exception: " <<
e.what() << std::endl;