v1.3 : added auto file reloading
+ Files now auto reload when changes are detected + Added --no-reload option to disable auto reloading * Internal cleanups
This commit is contained in:
parent
8486fa3984
commit
1c8c3ac9d2
5 changed files with 147 additions and 58 deletions
|
|
@ -8,8 +8,6 @@
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include <ztd/filedat.hpp>
|
#include <ztd/filedat.hpp>
|
||||||
|
|
||||||
void sh(std::string const& string);
|
|
||||||
|
|
||||||
class Device
|
class Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -34,7 +32,6 @@ public:
|
||||||
std::vector<ConnectCommand> connectCommands;
|
std::vector<ConnectCommand> connectCommands;
|
||||||
std::vector<DisconnectCommand> disconnectCommands;
|
std::vector<DisconnectCommand> disconnectCommands;
|
||||||
|
|
||||||
std::thread thread;
|
|
||||||
pid_t thread_pid;
|
pid_t thread_pid;
|
||||||
private:
|
private:
|
||||||
static void loop(Device* dev);
|
static void loop(Device* dev);
|
||||||
|
|
@ -42,4 +39,6 @@ private:
|
||||||
|
|
||||||
extern std::vector<Device*> device_list;
|
extern std::vector<Device*> device_list;
|
||||||
|
|
||||||
|
void clean_devices();
|
||||||
|
|
||||||
#endif //DEVICE_HPP
|
#endif //DEVICE_HPP
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,16 @@
|
||||||
#define LIST_COMMAND "aseqdump -l | tail -n +2 | cut -c10-42 | tr -s ' '"
|
#define LIST_COMMAND "aseqdump -l | tail -n +2 | cut -c10-42 | tr -s ' '"
|
||||||
#define LIST_EXTENDED_COMMAND "aseqdump -l | tail -n +2 | cut -c-42"
|
#define LIST_EXTENDED_COMMAND "aseqdump -l | tail -n +2 | cut -c-42"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
extern int announce_thread_pid;
|
extern int announce_thread_pid;
|
||||||
|
|
||||||
|
void kill_all();
|
||||||
|
|
||||||
void device_check();
|
void device_check();
|
||||||
|
|
||||||
void announce_loop();
|
void announce_loop();
|
||||||
|
|
||||||
|
void filetime_loop(std::string filepath);
|
||||||
|
|
||||||
#endif //SYSTEM_HPP
|
#endif //SYSTEM_HPP
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <ztd/shell.hpp>
|
#include <ztd/shell.hpp>
|
||||||
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
|
@ -40,11 +41,6 @@ static bool _isNum(char a)
|
||||||
return (a>='0' && a<='9');
|
return (a>='0' && a<='9');
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh(std::string const& string)
|
|
||||||
{
|
|
||||||
system(string.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
Device::Device()
|
Device::Device()
|
||||||
{
|
{
|
||||||
busy=false;
|
busy=false;
|
||||||
|
|
@ -63,8 +59,7 @@ bool Device::start_loop()
|
||||||
if(this->busy)
|
if(this->busy)
|
||||||
return false;
|
return false;
|
||||||
this->busy = true;
|
this->busy = true;
|
||||||
this->thread = std::thread(Device::loop, this);
|
std::thread(Device::loop, this).detach();
|
||||||
this->thread.detach();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,7 +290,7 @@ void Device::run_signal(char* buff)
|
||||||
{
|
{
|
||||||
std::string command="code=" + strval + ";";
|
std::string command="code=" + strval + ";";
|
||||||
command += dequote(it.shell);
|
command += dequote(it.shell);
|
||||||
std::thread(sh, command).detach();
|
std::thread(ztd::sh, command, true).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -372,7 +367,7 @@ void Device::run_signal(char* buff)
|
||||||
+ ";channel=" + std::to_string(channel)
|
+ ";channel=" + std::to_string(channel)
|
||||||
+ ";velocity=" + std::to_string(value) + ";";
|
+ ";velocity=" + std::to_string(value) + ";";
|
||||||
command += dequote(it.shell);
|
command += dequote(it.shell);
|
||||||
std::thread(sh, command).detach();
|
std::thread(ztd::sh, command, true).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,7 +394,7 @@ void Device::run_signal(char* buff)
|
||||||
else
|
else
|
||||||
command += std::to_string((long int) result);
|
command += std::to_string((long int) result);
|
||||||
command += ";" + dequote(it.shell);
|
command += ";" + dequote(it.shell);
|
||||||
std::thread(sh, command).detach();
|
std::thread(ztd::sh, command, true).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +420,7 @@ void Device::run_signal(char* buff)
|
||||||
else
|
else
|
||||||
command += std::to_string((long int) result);
|
command += std::to_string((long int) result);
|
||||||
command += ";" + dequote(it.shell);
|
command += ";" + dequote(it.shell);
|
||||||
std::thread(sh, command).detach();
|
std::thread(ztd::sh, command, true).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // if type
|
} // if type
|
||||||
|
|
@ -447,7 +442,7 @@ void Device::loop(Device* dev)
|
||||||
|
|
||||||
for( auto it : dev->connectCommands )
|
for( auto it : dev->connectCommands )
|
||||||
{
|
{
|
||||||
std::thread(sh, dequote(it.shell)).detach();
|
std::thread(ztd::sh, dequote(it.shell), true).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (getline(&buff, &buff_size, stream) > 0)
|
while (getline(&buff, &buff_size, stream) > 0)
|
||||||
|
|
@ -457,7 +452,7 @@ void Device::loop(Device* dev)
|
||||||
|
|
||||||
for( auto it : dev->disconnectCommands )
|
for( auto it : dev->disconnectCommands )
|
||||||
{
|
{
|
||||||
std::thread(sh, dequote(it.shell)).detach();
|
std::thread(ztd::sh, dequote(it.shell), true).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Device '" + dev->name + "' disconnected\n");
|
log("Device '" + dev->name + "' disconnected\n");
|
||||||
|
|
@ -466,3 +461,12 @@ void Device::loop(Device* dev)
|
||||||
dev->thread_pid=-1;
|
dev->thread_pid=-1;
|
||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clean_devices()
|
||||||
|
{
|
||||||
|
for(auto it : device_list)
|
||||||
|
{
|
||||||
|
delete it;
|
||||||
|
}
|
||||||
|
device_list.clear();
|
||||||
|
}
|
||||||
|
|
|
||||||
132
src/main.cpp
132
src/main.cpp
|
|
@ -14,7 +14,7 @@
|
||||||
#include <ztd/options.hpp>
|
#include <ztd/options.hpp>
|
||||||
#include <ztd/shell.hpp>
|
#include <ztd/shell.hpp>
|
||||||
|
|
||||||
#define VERSION_STRING "v1.2"
|
#define VERSION_STRING "v1.3"
|
||||||
|
|
||||||
ztd::option_set options;
|
ztd::option_set options;
|
||||||
|
|
||||||
|
|
@ -59,8 +59,7 @@ void cleanup()
|
||||||
|
|
||||||
void stop(int ret)
|
void stop(int ret)
|
||||||
{
|
{
|
||||||
if(announce_thread_pid>0)
|
kill_all();
|
||||||
kill(announce_thread_pid, SIGINT);
|
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,12 +68,59 @@ void inthandler(int dummy)
|
||||||
stop(0);
|
stop(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_filedat(ztd::filedat& file, bool from_stdin, std::string const& path)
|
||||||
|
{
|
||||||
|
if(from_stdin)
|
||||||
|
{
|
||||||
|
log("Loading map from stdin\n");
|
||||||
|
file.import_stdin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.setFilePath(path);
|
||||||
|
log("Loading map file '" + path + "'\n");
|
||||||
|
if(options.find("zfd")->activated)
|
||||||
|
{
|
||||||
|
file.import_file();
|
||||||
|
}
|
||||||
|
else if(options.find("mim")->activated)
|
||||||
|
{
|
||||||
|
file.data() = mimtochk(file_strimport(path));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string filestr=file_strimport(path);
|
||||||
|
if(is_mim(filestr))
|
||||||
|
{
|
||||||
|
file.data() = mimtochk(filestr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.import_file();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_commands(ztd::chunkdat const& data)
|
||||||
|
{
|
||||||
|
clean_devices();
|
||||||
|
for(int i=0 ; i<data.listSize() ; i++)
|
||||||
|
{
|
||||||
|
Device *newDevice = new Device;
|
||||||
|
newDevice->import_chunk(data[i]);
|
||||||
|
device_list.push_back(newDevice);
|
||||||
|
log("Loaded "+std::to_string(newDevice->nb_command)+" commands for device '"+newDevice->name+"'\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
signal(SIGINT, inthandler);
|
signal(SIGINT, inthandler);
|
||||||
signal(SIGCHLD, SIG_IGN); //not expecting returns from child processes
|
signal(SIGCHLD, SIG_IGN); //not expecting returns from child processes
|
||||||
|
|
||||||
bool piped=false;
|
bool piped=false;
|
||||||
|
bool autoreload=true;
|
||||||
if (!isatty(fileno(stdin)))
|
if (!isatty(fileno(stdin)))
|
||||||
piped = true;
|
piped = true;
|
||||||
|
|
||||||
|
|
@ -98,6 +144,7 @@ int main(int argc, char* argv[])
|
||||||
options.add(ztd::option('z',"zfd", false, "Read file in zfd format"));
|
options.add(ztd::option('z',"zfd", false, "Read file in zfd format"));
|
||||||
options.add(ztd::option('o',"output", true, "Output the resulting zfd map to file. - for stdout", "file"));
|
options.add(ztd::option('o',"output", true, "Output the resulting zfd map to file. - for stdout", "file"));
|
||||||
options.add(ztd::option("aligner", true, "String to use for aligning output map format. Default \\t", "string"));
|
options.add(ztd::option("aligner", true, "String to use for aligning output map format. Default \\t", "string"));
|
||||||
|
options.add(ztd::option("no-reload", false, "Disable auto reloading when file changes are detected"));
|
||||||
options.add(ztd::option("\rIf no file format is specified, the program will try to guess the format"));
|
options.add(ztd::option("\rIf no file format is specified, the program will try to guess the format"));
|
||||||
// options.add(ztd::option('i',"interactive", false, "Start in interactive mode"));
|
// options.add(ztd::option('i',"interactive", false, "Start in interactive mode"));
|
||||||
|
|
||||||
|
|
@ -146,12 +193,12 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
if( options.find('L')->activated )
|
if( options.find('L')->activated )
|
||||||
{
|
{
|
||||||
sh("aseqdump -l");
|
ztd::sh("aseqdump -l", true);
|
||||||
stop(0);
|
stop(0);
|
||||||
}
|
}
|
||||||
if( options.find('l')->activated )
|
if( options.find('l')->activated )
|
||||||
{
|
{
|
||||||
sh(LIST_COMMAND);
|
ztd::sh(LIST_COMMAND, true);
|
||||||
stop(0);
|
stop(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,6 +215,10 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
//behavioral options
|
//behavioral options
|
||||||
|
if( options.find("no-reload")->activated )
|
||||||
|
{
|
||||||
|
autoreload=false;
|
||||||
|
}
|
||||||
if( options.find("no-log")->activated )
|
if( options.find("no-log")->activated )
|
||||||
{
|
{
|
||||||
log_on=false;
|
log_on=false;
|
||||||
|
|
@ -181,6 +232,7 @@ int main(int argc, char* argv[])
|
||||||
//no argument: display help
|
//no argument: display help
|
||||||
ztd::filedat file;
|
ztd::filedat file;
|
||||||
bool no_arg=false;
|
bool no_arg=false;
|
||||||
|
std::string filepath;
|
||||||
if (arg.size() <= 0 || arg[0] == "")
|
if (arg.size() <= 0 || arg[0] == "")
|
||||||
{
|
{
|
||||||
no_arg=true;
|
no_arg=true;
|
||||||
|
|
@ -192,42 +244,16 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file.setFilePath(arg[0]);
|
filepath=arg[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//main processing
|
//main processing
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(no_arg)
|
//load
|
||||||
{
|
load_filedat(file, no_arg, filepath);
|
||||||
log("Loading map from stdin\n");
|
//output
|
||||||
file.import_stdin();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log("Loading map file '" + arg[0] + "'\n");
|
|
||||||
if(options.find("zfd")->activated)
|
|
||||||
{
|
|
||||||
file.import_file();
|
|
||||||
}
|
|
||||||
else if(options.find("mim")->activated)
|
|
||||||
{
|
|
||||||
file.data() = mimtochk(file_strimport(arg[0]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string filestr=file_strimport(arg[0]);
|
|
||||||
if(is_mim(filestr))
|
|
||||||
{
|
|
||||||
file.data() = mimtochk(filestr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file.import_file();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(options.find('o')->activated)
|
if(options.find('o')->activated)
|
||||||
{
|
{
|
||||||
if(options.find('o')->argument == "-") {
|
if(options.find('o')->argument == "-") {
|
||||||
|
|
@ -240,17 +266,39 @@ int main(int argc, char* argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//create commands
|
//create commands
|
||||||
for(int i=0 ; i<file.data().listSize() ; i++)
|
load_commands(file.data());
|
||||||
{
|
|
||||||
Device *newDevice = new Device;
|
autoreload = autoreload && !no_arg;
|
||||||
newDevice->import_chunk(file[i]);
|
|
||||||
device_list.push_back(newDevice);
|
|
||||||
log("Loaded "+std::to_string(newDevice->nb_command)+" commands for device '"+newDevice->name+"'\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//main loop
|
//main loop
|
||||||
log("Starting scan for devices\n");
|
log("Starting scan for devices\n");
|
||||||
|
if(autoreload)
|
||||||
|
std::thread(filetime_loop, filepath).detach();
|
||||||
announce_loop();
|
announce_loop();
|
||||||
|
ztd::chunkdat bak_data = file.data();
|
||||||
|
while(autoreload)
|
||||||
|
{
|
||||||
|
log("Reloading file\n");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
load_filedat(file, false, filepath);
|
||||||
|
load_commands(file.data());
|
||||||
|
bak_data = file.data();
|
||||||
|
}
|
||||||
|
catch (ztd::format_error& e)
|
||||||
|
{
|
||||||
|
ztd::printFormatException(e);
|
||||||
|
log("Reloading old config\n");
|
||||||
|
load_commands(bak_data);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Exception: " << e.what() << std::endl;
|
||||||
|
log("Reloading old config\n");
|
||||||
|
load_commands(bak_data);
|
||||||
|
}
|
||||||
|
announce_loop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ztd::format_error& e)
|
catch (ztd::format_error& e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -13,6 +17,17 @@
|
||||||
|
|
||||||
int announce_thread_pid = 0;
|
int announce_thread_pid = 0;
|
||||||
|
|
||||||
|
void kill_all()
|
||||||
|
{
|
||||||
|
if(announce_thread_pid>0)
|
||||||
|
kill(announce_thread_pid, SIGINT);
|
||||||
|
for(auto it : device_list)
|
||||||
|
{
|
||||||
|
if(it->thread_pid>0)
|
||||||
|
kill(it->thread_pid, SIGINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void device_check()
|
void device_check()
|
||||||
{
|
{
|
||||||
char* buff = NULL;
|
char* buff = NULL;
|
||||||
|
|
@ -86,3 +101,20 @@ void announce_loop()
|
||||||
if(buff != NULL)
|
if(buff != NULL)
|
||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void filetime_loop(std::string filepath)
|
||||||
|
{
|
||||||
|
struct stat attrib;
|
||||||
|
stat(filepath.c_str(), &attrib);
|
||||||
|
time_t last_time=attrib.st_ctime;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
stat(filepath.c_str(), &attrib);
|
||||||
|
if(attrib.st_ctime > last_time)
|
||||||
|
{
|
||||||
|
kill_all();
|
||||||
|
last_time = attrib.st_ctime;
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue