This commit is contained in:
parent
f84f21ae9d
commit
7cf190e692
11
Makefile
11
Makefile
|
@ -111,7 +111,10 @@ PUR_OBJS= \
|
||||||
build$(PS)main.obj \
|
build$(PS)main.obj \
|
||||||
build$(PS)error.obj \
|
build$(PS)error.obj \
|
||||||
build$(PS)stats.obj \
|
build$(PS)stats.obj \
|
||||||
build$(PS)systray.obj
|
build$(PS)systray.obj \
|
||||||
|
build$(PS)ms_sleep.obj \
|
||||||
|
build$(PS)taskmgr.obj \
|
||||||
|
build$(PS)userpaths.obj
|
||||||
|
|
||||||
build$(PS)main.obj: build Makefile main.c api.h include$(PS)SDL.h include$(PS)SDL_image.h
|
build$(PS)main.obj: build Makefile main.c api.h include$(PS)SDL.h include$(PS)SDL_image.h
|
||||||
$(CCOBJ) main.c $(OBJOUT)$@
|
$(CCOBJ) main.c $(OBJOUT)$@
|
||||||
|
@ -121,6 +124,12 @@ build$(PS)error.obj: build Makefile api.h error.c
|
||||||
$(CCOBJ) error.c $(OBJOUT)$@
|
$(CCOBJ) error.c $(OBJOUT)$@
|
||||||
build$(PS)systray.obj: build pf.ico pf.png api.h tray$(PS)tray.h
|
build$(PS)systray.obj: build pf.ico pf.png api.h tray$(PS)tray.h
|
||||||
$(CCOBJ) systray.c $(OBJOUT)$@
|
$(CCOBJ) systray.c $(OBJOUT)$@
|
||||||
|
build$(PS)ms_sleep.obj: build ms_sleep.c
|
||||||
|
$(CCOBJ) ms_sleep.c $(OBJOUT)$@
|
||||||
|
build$(PS)taskmgr.obj: build api.h taskmgr.c
|
||||||
|
$(CCOBJ) taskmgr.c $(OBJOUT)$@
|
||||||
|
build$(PS)userpaths.obj: build api.h userpaths.c
|
||||||
|
$(CCOBJ) userpaths.c $(OBJOUT)$@
|
||||||
|
|
||||||
build:
|
build:
|
||||||
mkdir build
|
mkdir build
|
||||||
|
|
18
api.h
18
api.h
|
@ -1,8 +1,26 @@
|
||||||
#ifndef api_h
|
#ifndef api_h
|
||||||
#define api_h
|
#define api_h
|
||||||
|
|
||||||
|
extern int app_is_live;
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
void reportError(const char *fmt,...);
|
void reportError(const char *fmt,...);
|
||||||
enum ps { ps_startup,ps_shutdown};
|
enum ps { ps_startup,ps_shutdown};
|
||||||
void print_stats(enum ps ps);
|
void print_stats(enum ps ps);
|
||||||
|
|
||||||
|
unsigned taskmgr_ms_till_next(void);
|
||||||
|
void taskmgr_run(unsigned for_max_ms);
|
||||||
|
|
||||||
|
|
||||||
|
void ms_sleep(unsigned ms);
|
||||||
|
/**designed for relative time keeping, not recommended for use for absolute times*/
|
||||||
|
unsigned gettime_ms(void);
|
||||||
|
|
||||||
|
|
||||||
|
const char * get_config_file_path(void);
|
||||||
|
const char * get_app_dir(void);
|
||||||
|
|
||||||
|
int path_exists(const char *folder_or_file_path);
|
||||||
|
void make_dir(const char *folderpath);
|
||||||
|
|
||||||
#endif//api_h
|
#endif//api_h
|
||||||
|
|
11
main.c
11
main.c
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
|
||||||
|
int app_is_live=0;
|
||||||
|
|
||||||
SDL_Window * purrwin;
|
SDL_Window * purrwin;
|
||||||
void purrer(void) {
|
void purrer(void) {
|
||||||
SDL_Init(SDL_INIT_TIMER|SDL_INIT_EVENTS|SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_TIMER|SDL_INIT_EVENTS|SDL_INIT_VIDEO);
|
||||||
|
@ -20,10 +22,17 @@ void purrer(void) {
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
int main(int argc,char**argv){
|
int main(int argc,char**argv){
|
||||||
|
app_is_live=1;
|
||||||
puts("hello world");
|
puts("hello world");
|
||||||
SDL_SetMainReady();
|
SDL_SetMainReady();
|
||||||
print_stats(ps_startup);
|
print_stats(ps_startup);
|
||||||
purrer();
|
systray_initialscan();
|
||||||
|
//purrer();
|
||||||
|
while(app_is_live) {
|
||||||
|
unsigned ms_to_next_run = taskmgr_ms_till_next();
|
||||||
|
ms_sleep(ms_to_next_run);
|
||||||
|
taskmgr_run(0);
|
||||||
|
}
|
||||||
print_stats(ps_shutdown);
|
print_stats(ps_shutdown);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <Windows.h>
|
||||||
|
void ms_sleep(unsigned ms) {
|
||||||
|
Sleep(ms);
|
||||||
|
}
|
||||||
|
unsigned gettime_ms(void){
|
||||||
|
SYSTEMTIME st;
|
||||||
|
FILETIME ft={0,0};
|
||||||
|
GetSystemTime(&st);
|
||||||
|
SystemTimeToFileTime(&st,&ft);
|
||||||
|
return ft.dwLowDateTime;
|
||||||
|
}
|
||||||
|
#endif
|
18
systray.c
18
systray.c
|
@ -1,4 +1,22 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include "tray/tray.h"
|
#include "tray/tray.h"
|
||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
|
||||||
|
void systray_initialscan(void){
|
||||||
|
FILE *cfg;
|
||||||
|
if(!path_exists(get_app_dir())){
|
||||||
|
/*--create directory--*/
|
||||||
|
make_dir(get_app_dir());
|
||||||
|
}
|
||||||
|
/*--load list of tracked files--*/
|
||||||
|
cfg = fopen(get_config_file_path(),"rb");
|
||||||
|
if(!cfg) {
|
||||||
|
perror(get_config_file_path());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fclose(cfg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "api.h"
|
||||||
|
|
||||||
|
#ifndef TASKMGR_MAX_TASKS
|
||||||
|
#define TASKMGR_MAX_TASKS 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned taskmgr_ms_till_next(void){
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned right_here=0;
|
||||||
|
|
||||||
|
struct run_tag {
|
||||||
|
int oneshot;/**<if true, free slot after first use (so setTimeout() rather than setInterval() basically)*/
|
||||||
|
int stack_up;/**<if true, run multiple times (max once per taskmgr_run() though) to catch up if we fall behind, else it is like dropframes*/
|
||||||
|
unsigned frequency_ms;
|
||||||
|
unsigned awaiting;/**<countdown*/
|
||||||
|
void(*cb)(void*ud);/**< this not being null means in use, if null, slot is free*/
|
||||||
|
void*ud;
|
||||||
|
char brief_descr[15+1];
|
||||||
|
unsigned deficit;/**<deposit left over change during stack_up logic*/
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned time_passed(unsigned before,unsigned now){
|
||||||
|
unsigned timepassed=0;
|
||||||
|
if(now<before) {
|
||||||
|
timepassed = 0xfffffffful - before;
|
||||||
|
before=0;
|
||||||
|
}
|
||||||
|
timepassed += now-before;
|
||||||
|
return timepassed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct run_tag run_tab[TASKMGR_MAX_TASKS];
|
||||||
|
/**@return true if there are stacked/immidiates left*/
|
||||||
|
static int one_loop(unsigned for_max_ms){
|
||||||
|
unsigned right_now = gettime_ms();
|
||||||
|
unsigned passed=0;
|
||||||
|
int i;
|
||||||
|
unsigned effective_passed;
|
||||||
|
int backed_up=0;
|
||||||
|
if(for_max_ms==0)for_max_ms=0xfffffffful;//0 means run at least once no matter what
|
||||||
|
/*--calc time passed--*/
|
||||||
|
if(right_now < right_here) {
|
||||||
|
/*--wrap around--*/
|
||||||
|
passed = right_now + (0xfffffffful - right_here);
|
||||||
|
} else passed = right_now - right_here;
|
||||||
|
/*--process all slots (active/inactive), some might be awaiting==0 so even if passed==0, still run--*/
|
||||||
|
for(i=0;i<TASKMGR_MAX_TASKS;++i){
|
||||||
|
if(run_tab[i].cb == NULL)continue;
|
||||||
|
effective_passed= passed + run_tab[i].deficit;
|
||||||
|
if(run_tab[i].awaiting < effective_passed) {
|
||||||
|
void(*task2run)(void*)=run_tab[i].cb;
|
||||||
|
void *taskParam = run_tab[i].ud;
|
||||||
|
effective_passed -= run_tab[i].awaiting;
|
||||||
|
if(effective_passed > 0 && effective_passed < run_tab[i].frequency_ms) {
|
||||||
|
run_tab[i].awaiting = run_tab[i].frequency_ms - effective_passed;
|
||||||
|
} else if(effective_passed > 0) {
|
||||||
|
backed_up=1;
|
||||||
|
if(run_tab[i].stack_up) {
|
||||||
|
/*--stack up logic--*/
|
||||||
|
run_tab[i].awaiting=0;
|
||||||
|
run_tab[i].deficit = effective_passed - run_tab[i].frequency_ms;
|
||||||
|
} else {
|
||||||
|
run_tab[i].awaiting=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(run_tab[i].oneshot) {
|
||||||
|
run_tab[i].cb = NULL;
|
||||||
|
run_tab[i].ud = NULL;
|
||||||
|
}
|
||||||
|
task2run(run_tab[i].ud);
|
||||||
|
} else {
|
||||||
|
run_tab[i].awaiting -= effective_passed;
|
||||||
|
}
|
||||||
|
/*--deal with SLOW,LONG running callbacks vs for_max_ms "run for" issue--*/
|
||||||
|
if(time_passed(right_now,gettime_ms())>for_max_ms)break;
|
||||||
|
}
|
||||||
|
return backed_up;
|
||||||
|
}
|
||||||
|
void taskmgr_run(unsigned for_max_ms){
|
||||||
|
unsigned total_passed=0;
|
||||||
|
unsigned initial_moment = gettime_ms();
|
||||||
|
int backed_up = one_loop(for_max_ms);
|
||||||
|
if(for_max_ms > 0) {
|
||||||
|
while(backed_up) {
|
||||||
|
total_passed=time_passed(initial_moment,gettime_ms());
|
||||||
|
if(total_passed>=for_max_ms) break;
|
||||||
|
backed_up=one_loop(total_passed < for_max_ms ? for_max_ms - total_passed : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char servers_ini_buf[260+1];
|
||||||
|
char app_path_buf[260+1];
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <io.h>
|
||||||
|
const char * get_app_dir(void){
|
||||||
|
const char *appdata = getenv("APPDATA");
|
||||||
|
snprintf(app_path_buf,sizeof app_path_buf,"%s",appdata?appdata:".");
|
||||||
|
return app_path_buf;
|
||||||
|
}
|
||||||
|
const char * get_config_file_path(void){
|
||||||
|
snprintf(servers_ini_buf,sizeof servers_ini_buf,"%s\\purforce\\servers.ini",get_app_dir());
|
||||||
|
return servers_ini_buf;
|
||||||
|
}
|
||||||
|
int path_exists(const char *folder_or_file_path){
|
||||||
|
int ret = _access(folder_or_file_path,00);//Existence only
|
||||||
|
return ret==0;
|
||||||
|
}
|
||||||
|
void make_dir(const char *folderpath){
|
||||||
|
_mkdir(folderpath);
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue