Recusrive mkdir; delete files; path replacers

This commit is contained in:
John Alanbrook 2024-03-03 05:34:41 +00:00
parent f948dac73f
commit 83f5019f3e
7 changed files with 257 additions and 123 deletions

View file

@ -320,6 +320,7 @@ json.encode = function(value, space, replacer, whitelist)
json.decode = function(text, reviver) json.decode = function(text, reviver)
{ {
if (!text) return undefined;
return JSON.parse(text,reviver); return JSON.parse(text,reviver);
} }
@ -859,7 +860,7 @@ Object.defineProperty(String.prototype, 'dir', {
}); });
Object.defineProperty(String.prototype, 'splice', { Object.defineProperty(String.prototype, 'splice', {
value: function(index, str, ) { value: function(index, str) {
return this.slice(0,index) + str + this.slice(index); return this.slice(0,index) + str + this.slice(index);
} }
}); });
@ -881,6 +882,28 @@ Object.defineProperty(String.prototype, 'updir', {
} }
}); });
Object.defineProperty(String.prototype, 'trimchr', {
value: function(chars) {
var start = this.length;
var end = 0;
for (var i = 0; i < this.length; i++) {
if (!chars.includes(this[i])) {
start = i;
break;
}
}
for (var i = this.length-1; i >= 0; i--) {
if (!chars.includes(this[i])) {
end = i+1;
break;
}
}
return this.substring(start,end);
}
});
Object.defineProperty(String.prototype, 'startswith', { Object.defineProperty(String.prototype, 'startswith', {
value: function(val) { value: function(val) {
if (!val) return false; if (!val) return false;
@ -1573,4 +1596,3 @@ return {
Vector, Vector,
bbox bbox
}; };

View file

@ -52,7 +52,85 @@ var load = use;
Object.assign(global, use("scripts/base.js")); Object.assign(global, use("scripts/base.js"));
global.obscure('global'); global.obscure('global');
global.mixin("scripts/render.js");
global.Game = {
engine_start(fn) {
cmd(257, fn);
},
native: render.device.pc,
object_count() {
return cmd(214);
},
all_objects(fn) {
/* Wind down from Primum */
},
/* Returns a list of objects by name */
find(name) {
},
/* Return a list of objects derived from a specific prototype */
find_proto(proto) {
},
/* List of all objects spawned that have a specific tag */
find_tag(tag){
},
quit() {
sys_cmd(0);
return;
},
pause() { sys_cmd(3); },
stop() { Game.pause(); },
step() { sys_cmd(4);},
editor_mode(m) { sys_cmd(10, m); },
playing() { return sys_cmd(5); },
paused() { return sys_cmd(6); },
stepping() { return cmd(79); },
play() { sys_cmd(1); },
wait_fns: [],
wait_exec(fn) {
if (!phys_stepping())
fn();
else
this.wait_fns.push(fn);
},
exec() {
this.wait_fns.forEach(function(x) { x(); });
this.wait_fns = [];
},
};
Game.gc = function() { cmd(259); }
Game.gc.doc = "Force the garbage collector to run.";
Game.doc = {};
Game.doc.object = "Returns the entity belonging to a given id.";
Game.doc.quit = "Immediately quit the game.";
Game.doc.pause = "Pause game simulation.";
Game.doc.stop = "Stop game simulation. This does the same thing as 'pause', and if the game is a debug build, starts its editor.";
Game.doc.play = "Resume or start game simulation.";
Game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame.";
Game.doc.dt = "Current frame dt.";
Game.doc.view_camera = "Set the camera for the current view.";
Game.doc.camera = "Current camera.";
global.mixin("scripts/input.js");
global.mixin("scripts/std.js"); global.mixin("scripts/std.js");
global.mixin("scripts/diff.js"); global.mixin("scripts/diff.js");
console.level = 1; console.level = 1;
@ -140,9 +218,9 @@ var timer = {
}; };
global.mixin("scripts/tween.js"); global.mixin("scripts/tween.js");
global.mixin("scripts/render.js");
global.mixin("scripts/physics.js"); global.mixin("scripts/physics.js");
global.mixin("scripts/input.js");
global.mixin("scripts/ai.js"); global.mixin("scripts/ai.js");
global.mixin("scripts/geometry.js"); global.mixin("scripts/geometry.js");
@ -297,78 +375,6 @@ global.mixin("scripts/debug.js");
global.mixin("scripts/spline.js"); global.mixin("scripts/spline.js");
global.mixin("scripts/components.js"); global.mixin("scripts/components.js");
var Game = {
engine_start(fn) {
cmd(257, fn);
},
native: render.device.pc,
object_count() {
return cmd(214);
},
all_objects(fn) {
/* Wind down from Primum */
},
/* Returns a list of objects by name */
find(name) {
},
/* Return a list of objects derived from a specific prototype */
find_proto(proto) {
},
/* List of all objects spawned that have a specific tag */
find_tag(tag){
},
quit() {
sys_cmd(0);
return;
},
pause() { sys_cmd(3); },
stop() { Game.pause(); },
step() { sys_cmd(4);},
editor_mode(m) { sys_cmd(10, m); },
playing() { return sys_cmd(5); },
paused() { return sys_cmd(6); },
stepping() { return cmd(79); },
play() { sys_cmd(1); },
wait_fns: [],
wait_exec(fn) {
if (!phys_stepping())
fn();
else
this.wait_fns.push(fn);
},
exec() {
this.wait_fns.forEach(function(x) { x(); });
this.wait_fns = [];
},
};
Game.gc = function() { cmd(259); }
Game.gc.doc = "Force the garbage collector to run.";
Game.doc = {};
Game.doc.object = "Returns the entity belonging to a given id.";
Game.doc.quit = "Immediately quit the game.";
Game.doc.pause = "Pause game simulation.";
Game.doc.stop = "Stop game simulation. This does the same thing as 'pause', and if the game is a debug build, starts its editor.";
Game.doc.play = "Resume or start game simulation.";
Game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame.";
Game.doc.dt = "Current frame dt.";
Game.doc.view_camera = "Set the camera for the current view.";
Game.doc.camera = "Current camera.";
Window.doc = {}; Window.doc = {};
Window.doc.width = "Width of the game window."; Window.doc.width = "Width of the game window.";

View file

@ -461,8 +461,8 @@ var gameobject = {
alive() { return this.body >= 0; }, alive() { return this.body >= 0; },
in_air() { return q_body(7, this.body);}, in_air() { return q_body(7, this.body);},
hide() { this.components.forEach(x=>x.hide()); this.objects.forEach(x=>x.hide());}, hide() { this.components.forEach(x=>x.hide?.()); this.objects.forEach(x=>x.hide?.());},
show() { this.components.forEach(function(x) { x.show(); }); this.objects.forEach(function(x) { x.show(); }); }, show() { this.components.forEach(function(x) { x.show?.(); }); this.objects.forEach(function(x) { x.show?.(); }); },
width() { width() {
var bb = this.boundingbox(); var bb = this.boundingbox();
@ -817,11 +817,15 @@ function apply_ur(u, e)
return; return;
} }
if (topur.text) if (topur.text) {
feval_env(topur.text, e); var script = Resources.replstrs(topur.text);
eval_env(script, e, topur.text);
}
if (topur.data) if (topur.data) {
Object.merge(config, json.decode(io.slurp(topur.data))); var jss = Resources.replstrs(topur.data);
Object.merge(config, json.decode(jss));
}
} }
Object.merge(e, config); Object.merge(e, config);

View file

@ -1,5 +1,32 @@
os.cwd.doc = "Get the absolute path of the current working directory."; os.cwd.doc = "Get the absolute path of the current working directory.";
os.env.doc = "Return the value of the environment variable v."; os.env.doc = "Return the value of the environment variable v.";
os.platform = "steam";
if (os.sys === 'windows')
os.user = os.env("USERNAME");
else
os.user = os.env("USER");
var steam = {};
steam.appid = 480;
steam.userid = 8437843;
os.home = os.env("HOME");
steam.path = {
windows: `C:/Program Files (x86)/Steam/userdata/${steam.userid}/${steam.appid}`,
macos: `${os.home}/Library/Application Support/Steam/userdata/${steam.userid}/${steam.appid}`,
linux: `${os.home}/.local/share/Steam/userdata/${steam.userid}/${steam.appid}`
};
var otherpath = {
windows:`C:/Users/${os.user}/Saved Games`,
macos: `${os.home}/Library/Application Support`,
linux: `${os.home}/.local/share`
}
os.prefpath = function() {
return otherpath[os.sys()] + "/" + (Game.title ? Game.title : "Untitled Prosperon Game");
}
var projectfile = ".prosperon/project.json"; var projectfile = ".prosperon/project.json";
@ -25,12 +52,37 @@ Resources.is_animation = function(path)
return false; return false;
} }
Resources.is_path = function(str)
{
return !/[\\\/:*?"<>|]/.test(str);
}
Resources.texture = {}; Resources.texture = {};
Resources.texture.dimensions = function(path) { return cmd(64,path); } Resources.texture.dimensions = function(path) { return cmd(64,path); }
Resources.gif = {}; Resources.gif = {};
Resources.gif.frames = function(path) { return cmd(139,path); } Resources.gif.frames = function(path) { return cmd(139,path); }
Resources.replpath = function(str, path)
{
if (str[0] === "/")
return str.rm(0);
if (str[0] === "@")
return os.prefpath() + "/" + str.rm(0);
if (!path) return str;
var stem = path.dir();
while (stem) {
var tr = stem + "/" +str;
if (io.exists(tr)) return tr;
stem = steam.updir();
}
return str;
}
Resources.replstrs = function(path) Resources.replstrs = function(path)
{ {
var script = io.slurp(path); var script = io.slurp(path);
@ -38,13 +90,8 @@ Resources.replstrs = function(path)
var stem = path.dir(); var stem = path.dir();
script = script.replace(regexp,function(str) { script = script.replace(regexp,function(str) {
if (str[1] === "/") var newstr = Resources.replpath(str.trimchr('"'), path);
return str.rm(1); return `"${newstr}"`;
if (str[1] === "@")
return str.rm(1).splice(1, "playerpath/");
return str.splice(1, stem + "/");
}); });
return script; return script;
@ -146,12 +193,63 @@ console.doc = {
/* /*
io path rules. Starts with, meaning: io path rules. Starts with, meaning:
"@": user path "@": user path
"/": game path "/": root game path
"" : relative game path
*/ */
var tmp = io.chmod; var tmpchm = io.chmod;
io.chmod = function(file,mode) { io.chmod = function(file,mode) {
return tmp(file,parseInt(mode,8)); return tmpchm(file,parseInt(mode,8));
}
var tmpslurp = io.slurp;
io.slurp = function(path)
{
path = Resources.replpath(path);
return tmpslurp(path);
}
var tmpslurpb = io.slurpbytes;
io.slurpbytes = function(path)
{
path = Resources.replpath(path);
return tmpslurpb(path);
}
io.mkpath = function(dir)
{
var mkstack = [];
while (!io.exists(dir)) {
mkstack.push(dir.fromlast('/'));
dir = dir.dir();
}
for (var d of mkstack) {
dir = dir + "/" + d;
say(`making ${dir}`);
io.mkdir(dir);
}
}
var tmpslurpw = io.slurpwrite;
io.slurpwrite = function(path, c)
{
path = Resources.replpath(path);
io.mkpath(path.dir());
return tmpslurpw(path, c);
}
var tmpcp = io.cp;
io.cp = function(f1,f2)
{
io.mkpath(f2.dir());
tmpcp(f1,f2);
}
var tmprm = io.rm;
io.rm = function(f)
{
tmprm(Resources.replpath(f));
} }
io.mixin({ io.mixin({
@ -226,7 +324,7 @@ Cmdline.register_order("edit", function() {
}, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?"); }, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?");
Cmdline.register_order("init", function() { Cmdline.register_order("init", function() {
if (io.exists(".prosperon")) { if (io.exists(projectfile)) {
say("Already a game here."); say("Already a game here.");
return; return;
} }
@ -255,6 +353,7 @@ Cmdline.register_order("play", function() {
} }
var project = json.decode(io.slurp(projectfile)); var project = json.decode(io.slurp(projectfile));
Game.title = project.title;
global.mixin("config.js"); global.mixin("config.js");
if (project.title) Window.title(project.title); if (project.title) Window.title(project.title);
@ -490,7 +589,7 @@ return {
console, console,
Resources, Resources,
say, say,
io,
Cmdline, Cmdline,
cmd_args cmd_args,
steam
}; };

View file

@ -1909,9 +1909,22 @@ JSValue js_os_env(JSContext *js, JSValueConst this, int argc, JSValue *argv)
return ret; return ret;
} }
JSValue js_os_sys(JSContext *js, JSValueConst this)
{
#ifdef __linux__
return str2js("linux");
#elif defined(_WIN32) || defined(_WIN64)
return str2js("windows");
#elif defined(__APPLE__)
return str2js("macos");
#endif
return JS_UNDEFINED;
}
static const JSCFunctionListEntry js_os_funcs[] = { static const JSCFunctionListEntry js_os_funcs[] = {
MIST_CFUNC_DEF("cwd", 0, js_os_cwd), MIST_CFUNC_DEF("cwd", 0, js_os_cwd),
MIST_CFUNC_DEF("env", 1, js_os_env), MIST_CFUNC_DEF("env", 1, js_os_env),
MIST_CFUNC_DEF("sys", 0, js_os_sys),
}; };
JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv) JSValue js_io_exists(JSContext *js, JSValueConst this, int argc, JSValue *argv)
@ -1952,6 +1965,7 @@ JSValue js_io_mv(JSContext *js, JSValueConst this, int argc, JSValue *argv)
JSValue js_io_rm(JSContext *js, JSValueConst this, int argc, JSValue *argv) JSValue js_io_rm(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
char *file = JS_ToCString(js, argv[0]); char *file = JS_ToCString(js, argv[0]);
JSValue ret = int2js(remove(file));
JS_FreeCString(js,file); JS_FreeCString(js,file);
return JS_UNDEFINED; return JS_UNDEFINED;
} }
@ -1979,6 +1993,7 @@ JSValue js_io_slurp(JSContext *js, JSValueConst this, int argc, JSValue *argv)
{ {
char *f = js2str(argv[0]); char *f = js2str(argv[0]);
size_t len; size_t len;
char *s = slurp_text(f,&len); char *s = slurp_text(f,&len);
JS_FreeCString(js,f); JS_FreeCString(js,f);

View file

@ -207,7 +207,7 @@ int cp(const char *p1, const char *p2)
size_t len; size_t len;
void *data = slurp_file(p1, &len); void *data = slurp_file(p1, &len);
FILE *f = fopen_mkdir(p2, "w"); FILE *f = fopen(p2, "w");
if (!f) return 1; if (!f) return 1;
fwrite(data, len, 1, f); fwrite(data, len, 1, f);
free(data); free(data);
@ -215,34 +215,23 @@ int cp(const char *p1, const char *p2)
return 0; return 0;
} }
void rek_mkdir(char *path) { int mkpath(char *dir, mode_t mode)
char *sep = strrchr(path, '/'); {
if(sep != NULL) { if (!dir) {
*sep = 0; errno = EINVAL;
rek_mkdir(path); return 1;
*sep = '/';
}
#if defined __WIN32
if(mkdir(path) && errno != EEXIST)
#else
if (mkdir(path, 0777) && errno != EEXIST)
#endif
printf("error while trying to create '%s'\n%m\n", path);
} }
FILE *fopen_mkdir(const char *path, const char *mode) { if (strlen(dir) == 1 && dir[0] == '/')
char *sep = strrchr(path, '/'); return 0;
if(sep) {
char *path0 = strdup(path); // mkpath(dirname(strdupa(dir)), mode);
path0[ sep - path ] = 0;
rek_mkdir(path0); return mkdir(dir, mode);
free(path0);
}
return fopen(path,mode);
} }
int slurp_write(const char *txt, const char *filename, size_t len) { int slurp_write(const char *txt, const char *filename, size_t len) {
FILE *f = fopen_mkdir(filename, "w"); FILE *f = fopen(filename, "w");
if (!f) return 1; if (!f) return 1;
if (len < 0) len = strlen(txt); if (len < 0) len = strlen(txt);

View file

@ -16,7 +16,6 @@ FILE *path_open(const char *tag, const char *fmt, ...);
char **ls(const char *path); char **ls(const char *path);
int cp(const char *p1, const char *p2); int cp(const char *p1, const char *p2);
int fexists(const char *path); int fexists(const char *path);
FILE *fopen_mkdir(const char *path, const char *mode);
char *dirname(const char *path); char *dirname(const char *path);