shithub: renderfs

Download patch

ref: c45f21c3defa4951c50518dcc72b3eb32f8ce124
parent: 139309e7c5cb445df58e3f3f252e3545d59558bd
author: rodri <[email protected]>
date: Wed Apr 3 15:19:38 EDT 2024

fix client management.

--- a/fs.c
+++ b/fs.c
@@ -21,8 +21,8 @@
 
 struct Client
 {
+	Ref;
 	ulong slot;
-	int inuse;
 	Camera *cam;
 };
 
@@ -78,6 +78,8 @@
 
 static LightSource light = {{0,100,100,1}, {1,1,1,1}, LIGHT_POINT};
 
+static Client *getclient(ulong);
+
 static Point3
 vshader(VSparams *sp)
 {
@@ -85,7 +87,7 @@
 	Point3 pos, lightdir;
 	double intens;
 
-	c = &clients[0];	/* TODO figure out a way to address the correct client */
+	c = getclient(0);	/* TODO figure out a way to address the correct client */
 
 	pos = model2world(sp->su->entity, sp->v->p);
 	lightdir = normvec3(subpt3(light.p, pos));
@@ -149,6 +151,20 @@
 	return cw*nc;
 }
 
+static void
+resetcamera(Camera *c)
+{
+	rmviewport(c->vp);
+	c->vp = mkviewport(Rect(0,0,320,200));
+	c->fov = 40*DEG;
+	c->clip.n = 0.01;
+	c->clip.f = 1000;
+	c->projtype = PERSPECTIVE;
+	c->rctl = renderer;
+	placecamera(c, Pt3(0,0,100,1), Pt3(0,0,0,1), Vec3(0,1,0));
+	reloadcamera(c);
+}
+
 static ulong
 newclient(void)
 {
@@ -156,25 +172,18 @@
 	int i;
 
 	for(i = 0; i < nclients; i++)
-		if(!clients[i].inuse)
+		if(clients[i].ref == 0)
 			return i;
 
 	if(nclients%16 == 0)
 		clients = erealloc9p(clients, (nclients+16)*sizeof(*clients));
 
-	c = &clients[nclients++];
+	c = getclient(nclients++);
+	memset(c, 0, sizeof *c);
 	c->slot = c-clients;
-	c->inuse = 1;
 	c->cam = emalloc9p(sizeof *c->cam);
-	c->cam->vp = mkviewport(Rect(0,0,320,200));
-	c->cam->fov = 40*DEG;
-	c->cam->clip.n = 0.01;
-	c->cam->clip.f = 1000;
-	c->cam->projtype = PERSPECTIVE;
-	c->cam->rctl = renderer;
+	resetcamera(c->cam);
 	c->cam->s = newscene(nil);
-	placecamera(c->cam, Pt3(0,0,100,1), Pt3(0,0,0,1), Vec3(0,1,0));
-	reloadcamera(c->cam);
 	return c->slot;
 }
 
@@ -189,7 +198,11 @@
 static void
 closeclient(Client *c)
 {
-	c->inuse = 0;
+	if(decref(c))
+		return;
+
+	clearscene(c->cam->s);
+	resetcamera(c->cam);
 }
 
 static void
@@ -365,6 +378,8 @@
 		r->fid->qid.path = path;
 		r->ofcall.qid.path = path;
 	}
+	if(QTYPE(path) >= Qn)
+		incref(getclient(SLOT(path)));
 	respond(r, nil);
 }
 
@@ -382,7 +397,7 @@
 	path = r->fid->qid.path;
 	off = r->ifcall.offset;
 	cnt = r->ifcall.count;
-	c = &clients[SLOT(path)];
+	c = getclient(SLOT(path));
 
 	switch(QTYPE(path)){
 	default:
@@ -393,7 +408,7 @@
 		respond(r, nil);
 		break;
 	case Qn:
-		dirread9p(r, clientgen, &clients[SLOT(path)]);
+		dirread9p(r, clientgen, getclient(SLOT(path)));
 		respond(r, nil);
 		break;
 	case Qctl:
@@ -449,7 +464,8 @@
 		n += snprint(buf+n, sizeof(buf)-n, "pos %V\n", c->cam->p);
 		n += snprint(buf+n, sizeof(buf)-n, "fov %g°\n", c->cam->fov/DEG);
 		n += snprint(buf+n, sizeof(buf)-n, "clip [%g %g]\n", c->cam->clip.n, c->cam->clip.f);
-		snprint(buf+n, sizeof(buf)-n, "proj %s\n", c->cam->projtype == PERSPECTIVE? "persp": "ortho");
+		n += snprint(buf+n, sizeof(buf)-n, "proj %s\n", c->cam->projtype == PERSPECTIVE? "persp": "ortho");
+		snprint(buf+n, sizeof(buf)-n, "ents %lud\n", c->cam->s->nents);
 		readstr(r, buf);
 		respond(r, nil);
 		break;
@@ -474,7 +490,7 @@
 
 	path = r->fid->qid.path;
 	cnt = r->ifcall.count;
-	c = &clients[SLOT(path)];
+	c = getclient(SLOT(path));
 
 	switch(QTYPE(path)){
 	default:
@@ -595,7 +611,7 @@
 
 	path = f->qid.path;
 	if(f->omode != -1 && QTYPE(path) >= Qn)
-		closeclient(&clients[SLOT(path)]);
+		closeclient(getclient(SLOT(path)));
 }
 
 void