255 lines
5.9 KiB
C++
255 lines
5.9 KiB
C++
/*!\file
|
||
* \brief \todo Описание файла.
|
||
*/
|
||
/*
|
||
* AppBuilder.cpp
|
||
*
|
||
* Created on: 24 июн. 2019 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#include "AppBuilder.hh"
|
||
|
||
using configuration::software::AppBuilder;
|
||
|
||
AppBuilder::AppBuilder( BuildedItem * items, std::size_t items_size,
|
||
Environment & env ) : size(items_size), setup_list(items), global_env(env) {}
|
||
|
||
bool AppBuilder::addState( application::ISetupStep * state, InitializerStepId id ) {
|
||
|
||
if( step_quantity == size || not state )
|
||
return false;
|
||
|
||
Idx idx = step_quantity;
|
||
setup_list[idx].step = state;
|
||
setup_list[idx].id = id;
|
||
|
||
step_quantity++;
|
||
|
||
return true;
|
||
}
|
||
|
||
void AppBuilder::process() {
|
||
if (finish_quantity >= step_quantity){
|
||
end();
|
||
|
||
if (application_builded){
|
||
return;
|
||
}
|
||
}
|
||
|
||
BuildedItem & builded_item(setup_list[build_index]);
|
||
//DebugP_log((char*)"[AppBuilder::process]index %i. Id: %i (%i/%i)\r\n", build_index, builded_item.id, finish_quantity, step_quantity);
|
||
|
||
switch (builded_item.state) {
|
||
// Если initializer уже собран - пропускаем этапы инициализации.
|
||
case BuildedItem::DONE:
|
||
break;
|
||
case BuildedItem::INPUT: {
|
||
const bool input_status = do_input(global_env, builded_item.step);
|
||
|
||
/* Шаг сборки не выполнен по причине ошибки */
|
||
if (!input_status && global_env.exception.raised()) break;
|
||
|
||
/* Шаг сборки не выполнен по причине неготовности зависимостей */
|
||
if (!input_status) {
|
||
//DebugP_log((char*)"[AppBuilder::process] INPUT: index %i. Id: %i\r\n", build_index, builded_item.id);
|
||
|
||
break;
|
||
}
|
||
|
||
/* Шаг сборки выполнен, перейти к следующему */
|
||
builded_item.state = BuildedItem::PREPARE;
|
||
};
|
||
case BuildedItem::PREPARE: {
|
||
const bool prepare_status = do_prepare(builded_item.step);
|
||
|
||
if (!prepare_status && global_env.exception.raised()) break;
|
||
|
||
if (!prepare_status) break;
|
||
|
||
builded_item.state = BuildedItem::BUILD;
|
||
};
|
||
case BuildedItem::BUILD: {
|
||
|
||
const bool build_status = do_build(global_env, builded_item.step);
|
||
|
||
if (!build_status && global_env.exception.raised()) break;
|
||
|
||
if (!build_status) break;
|
||
|
||
// Если initializer прошел весь цикл - присваиваем ему соответствующий статус и выходим.
|
||
builded_item.state = BuildedItem::DONE;
|
||
finish_quantity += 1;
|
||
//DebugP_log((char*)"[AppBuilder::process] DONE: index %i (%i/%i)\r\n", build_index, finish_quantity, step_quantity);
|
||
|
||
break;
|
||
};
|
||
default:
|
||
case BuildedItem::ERROR: break;
|
||
}
|
||
|
||
build_index = (build_index + 1) % step_quantity;
|
||
|
||
while (setup_list[build_index].state == BuildedItem::DONE) {
|
||
build_index += 1;
|
||
|
||
if (build_index >= step_quantity) {
|
||
build_index = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
bool AppBuilder::isBuilded() const {
|
||
|
||
return application_builded;
|
||
|
||
}
|
||
|
||
bool AppBuilder::do_input( Environment & env, application::ISetupStep * & step ) {
|
||
|
||
if( step )
|
||
return step->input(env);
|
||
else
|
||
return false;
|
||
|
||
}
|
||
|
||
bool AppBuilder::do_prepare( application::ISetupStep * & step) {
|
||
|
||
if( step )
|
||
return step->prepare();
|
||
else
|
||
return false;
|
||
|
||
}
|
||
|
||
bool AppBuilder::do_build( Environment & env, application::ISetupStep * & step ) {
|
||
|
||
if( step ) {
|
||
|
||
step->build(env);
|
||
return true;
|
||
|
||
} else
|
||
return false;
|
||
|
||
}
|
||
|
||
bool AppBuilder::do_end( Environment & env, application::ISetupStep * & step ) {
|
||
|
||
if(step) {
|
||
|
||
step->finalize();
|
||
return true;
|
||
|
||
} else
|
||
return false;
|
||
|
||
}
|
||
|
||
void AppBuilder::end() {
|
||
|
||
bool result = true;
|
||
|
||
//do end:
|
||
for( Idx i = step_quantity; i != 0; i-- ) {
|
||
BuildedItem & setup_item( setup_list[i - 1] );
|
||
|
||
result = do_end( global_env, setup_item.step ) and result;
|
||
setup_item.step = nullptr;
|
||
}
|
||
|
||
step_quantity = 0;
|
||
|
||
application_builded = result;
|
||
}
|
||
|
||
#include <exception>
|
||
|
||
bool configuration::software::AppBuilderSafety::do_input( Environment & env,
|
||
application::ISetupStep * & step ) {
|
||
bool result = false;
|
||
|
||
if(step) try {
|
||
|
||
result = step->input(env);
|
||
|
||
} catch( std::exception & unknow ) {
|
||
|
||
const char * what = unknow.what();
|
||
|
||
while(true);
|
||
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
bool configuration::software::AppBuilderSafety::do_prepare( application::ISetupStep * & step ) {
|
||
bool result = false;
|
||
|
||
if(step) try {
|
||
|
||
result = step->prepare();
|
||
|
||
} catch( std::exception & unknow ) {
|
||
|
||
while(true);
|
||
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
bool configuration::software::AppBuilderSafety::do_build( Environment & env,
|
||
application::ISetupStep * & step ) {
|
||
bool result = true;
|
||
|
||
if(step) try {
|
||
|
||
step->build(env);
|
||
|
||
} catch( std::exception & unknow ) {
|
||
|
||
while(true);
|
||
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
bool configuration::software::AppBuilderSafety::do_end( Environment & env,
|
||
application::ISetupStep * & step ) {
|
||
|
||
bool result = true;
|
||
|
||
if(step) try {
|
||
|
||
step->finalize();
|
||
|
||
} catch( std::exception & unknow ) {
|
||
|
||
while(true);
|
||
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
void configuration::software::AppBuilder::cancel() {
|
||
|
||
for( Idx i = step_quantity; i != 0; i-- ) {
|
||
BuildedItem & setup_item( setup_list[i - 1] );
|
||
|
||
if( setup_item.state == BuildedItem::DONE ) do_end( global_env, setup_item.step );
|
||
|
||
setup_item.step = nullptr;
|
||
}
|
||
|
||
step_quantity = 0;
|
||
application_builded = true;
|
||
|
||
}
|