Recusrive mkdir; delete files; path replacers
This commit is contained in:
parent
f948dac73f
commit
83f5019f3e
|
@ -320,6 +320,7 @@ json.encode = function(value, space, replacer, whitelist)
|
|||
|
||||
json.decode = function(text, reviver)
|
||||
{
|
||||
if (!text) return undefined;
|
||||
return JSON.parse(text,reviver);
|
||||
}
|
||||
|
||||
|
@ -859,7 +860,7 @@ Object.defineProperty(String.prototype, 'dir', {
|
|||
});
|
||||
|
||||
Object.defineProperty(String.prototype, 'splice', {
|
||||
value: function(index, str, ) {
|
||||
value: function(index, str) {
|
||||
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', {
|
||||
value: function(val) {
|
||||
if (!val) return false;
|
||||
|
@ -1573,4 +1596,3 @@ return {
|
|||
Vector,
|
||||
bbox
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ globalThis.global = globalThis;
|
|||
function use(file)
|
||||
{
|
||||
if (use.files[file]) return use.files[file];
|
||||
|
||||
|
||||
var c = io.slurp(file);
|
||||
|
||||
var script = `(function() { ${c} })();`;
|
||||
|
@ -52,7 +52,85 @@ var load = use;
|
|||
|
||||
Object.assign(global, use("scripts/base.js"));
|
||||
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/diff.js");
|
||||
|
||||
console.level = 1;
|
||||
|
@ -140,9 +218,9 @@ var timer = {
|
|||
};
|
||||
|
||||
global.mixin("scripts/tween.js");
|
||||
global.mixin("scripts/render.js");
|
||||
|
||||
global.mixin("scripts/physics.js");
|
||||
global.mixin("scripts/input.js");
|
||||
|
||||
|
||||
global.mixin("scripts/ai.js");
|
||||
global.mixin("scripts/geometry.js");
|
||||
|
@ -297,78 +375,6 @@ global.mixin("scripts/debug.js");
|
|||
global.mixin("scripts/spline.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.width = "Width of the game window.";
|
||||
|
|
|
@ -461,8 +461,8 @@ var gameobject = {
|
|||
alive() { return this.body >= 0; },
|
||||
in_air() { return q_body(7, this.body);},
|
||||
|
||||
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(); }); },
|
||||
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?.(); }); },
|
||||
|
||||
width() {
|
||||
var bb = this.boundingbox();
|
||||
|
@ -817,11 +817,15 @@ function apply_ur(u, e)
|
|||
return;
|
||||
}
|
||||
|
||||
if (topur.text)
|
||||
feval_env(topur.text, e);
|
||||
if (topur.text) {
|
||||
var script = Resources.replstrs(topur.text);
|
||||
eval_env(script, e, topur.text);
|
||||
}
|
||||
|
||||
if (topur.data)
|
||||
Object.merge(config, json.decode(io.slurp(topur.data)));
|
||||
if (topur.data) {
|
||||
var jss = Resources.replstrs(topur.data);
|
||||
Object.merge(config, json.decode(jss));
|
||||
}
|
||||
}
|
||||
|
||||
Object.merge(e, config);
|
||||
|
|
127
scripts/std.js
127
scripts/std.js
|
@ -1,5 +1,32 @@
|
|||
os.cwd.doc = "Get the absolute path of the current working directory.";
|
||||
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";
|
||||
|
||||
|
@ -25,12 +52,37 @@ Resources.is_animation = function(path)
|
|||
return false;
|
||||
}
|
||||
|
||||
Resources.is_path = function(str)
|
||||
{
|
||||
return !/[\\\/:*?"<>|]/.test(str);
|
||||
}
|
||||
|
||||
Resources.texture = {};
|
||||
Resources.texture.dimensions = function(path) { return cmd(64,path); }
|
||||
|
||||
Resources.gif = {};
|
||||
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)
|
||||
{
|
||||
var script = io.slurp(path);
|
||||
|
@ -38,13 +90,8 @@ Resources.replstrs = function(path)
|
|||
var stem = path.dir();
|
||||
|
||||
script = script.replace(regexp,function(str) {
|
||||
if (str[1] === "/")
|
||||
return str.rm(1);
|
||||
|
||||
if (str[1] === "@")
|
||||
return str.rm(1).splice(1, "playerpath/");
|
||||
|
||||
return str.splice(1, stem + "/");
|
||||
var newstr = Resources.replpath(str.trimchr('"'), path);
|
||||
return `"${newstr}"`;
|
||||
});
|
||||
|
||||
return script;
|
||||
|
@ -146,14 +193,65 @@ console.doc = {
|
|||
/*
|
||||
io path rules. Starts with, meaning:
|
||||
"@": user path
|
||||
"/": game path
|
||||
"/": root game path
|
||||
"" : relative game path
|
||||
*/
|
||||
|
||||
var tmp = io.chmod;
|
||||
var tmpchm = io.chmod;
|
||||
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({
|
||||
extensions(ext) {
|
||||
var paths = io.ls();
|
||||
|
@ -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?");
|
||||
|
||||
Cmdline.register_order("init", function() {
|
||||
if (io.exists(".prosperon")) {
|
||||
if (io.exists(projectfile)) {
|
||||
say("Already a game here.");
|
||||
return;
|
||||
}
|
||||
|
@ -255,6 +353,7 @@ Cmdline.register_order("play", function() {
|
|||
}
|
||||
|
||||
var project = json.decode(io.slurp(projectfile));
|
||||
Game.title = project.title;
|
||||
global.mixin("config.js");
|
||||
if (project.title) Window.title(project.title);
|
||||
|
||||
|
@ -490,7 +589,7 @@ return {
|
|||
console,
|
||||
Resources,
|
||||
say,
|
||||
io,
|
||||
Cmdline,
|
||||
cmd_args
|
||||
cmd_args,
|
||||
steam
|
||||
};
|
||||
|
|
|
@ -1909,9 +1909,22 @@ JSValue js_os_env(JSContext *js, JSValueConst this, int argc, JSValue *argv)
|
|||
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[] = {
|
||||
MIST_CFUNC_DEF("cwd", 0, js_os_cwd),
|
||||
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)
|
||||
|
@ -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)
|
||||
{
|
||||
char *file = JS_ToCString(js, argv[0]);
|
||||
JSValue ret = int2js(remove(file));
|
||||
JS_FreeCString(js,file);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
@ -1979,6 +1993,7 @@ JSValue js_io_slurp(JSContext *js, JSValueConst this, int argc, JSValue *argv)
|
|||
{
|
||||
char *f = js2str(argv[0]);
|
||||
size_t len;
|
||||
|
||||
char *s = slurp_text(f,&len);
|
||||
JS_FreeCString(js,f);
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ int cp(const char *p1, const char *p2)
|
|||
size_t len;
|
||||
void *data = slurp_file(p1, &len);
|
||||
|
||||
FILE *f = fopen_mkdir(p2, "w");
|
||||
FILE *f = fopen(p2, "w");
|
||||
if (!f) return 1;
|
||||
fwrite(data, len, 1, f);
|
||||
free(data);
|
||||
|
@ -215,34 +215,23 @@ int cp(const char *p1, const char *p2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void rek_mkdir(char *path) {
|
||||
char *sep = strrchr(path, '/');
|
||||
if(sep != NULL) {
|
||||
*sep = 0;
|
||||
rek_mkdir(path);
|
||||
*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);
|
||||
}
|
||||
int mkpath(char *dir, mode_t mode)
|
||||
{
|
||||
if (!dir) {
|
||||
errno = EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *fopen_mkdir(const char *path, const char *mode) {
|
||||
char *sep = strrchr(path, '/');
|
||||
if(sep) {
|
||||
char *path0 = strdup(path);
|
||||
path0[ sep - path ] = 0;
|
||||
rek_mkdir(path0);
|
||||
free(path0);
|
||||
}
|
||||
return fopen(path,mode);
|
||||
if (strlen(dir) == 1 && dir[0] == '/')
|
||||
return 0;
|
||||
|
||||
// mkpath(dirname(strdupa(dir)), mode);
|
||||
|
||||
return mkdir(dir, mode);
|
||||
}
|
||||
|
||||
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 (len < 0) len = strlen(txt);
|
||||
|
|
|
@ -16,7 +16,6 @@ FILE *path_open(const char *tag, const char *fmt, ...);
|
|||
char **ls(const char *path);
|
||||
int cp(const char *p1, const char *p2);
|
||||
int fexists(const char *path);
|
||||
FILE *fopen_mkdir(const char *path, const char *mode);
|
||||
|
||||
char *dirname(const char *path);
|
||||
|
||||
|
|
Loading…
Reference in a new issue