diff Renderer/Test/send_linda.cc @ 0:04e28d8d3c6f

first commit
author Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
date Mon, 08 Nov 2010 01:23:25 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test/send_linda.cc	Mon Nov 08 01:23:25 2010 +0900
@@ -0,0 +1,262 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "SceneGraphRoot.h"
+#include "lindaapi.h"
+#include "send_linda.h"
+
+#define HOSTNAME "localhost"
+#define PORT_NUM 10000
+#define LISTEN_PORT 1
+#define MULTI_NUM 10
+#define SEND_DATA_SIZE sizeof(float) * 6
+
+void
+send_position(SceneGraphPtr node)
+{
+	char *data;
+	if (node->seq == 0) {
+	} else if ((data = (char *)psx_reply(node->seq)) != NULL) {
+		psx_free(data);
+	} else {
+		node->resend_flag = 1;
+		return;
+	}
+	node->resend_flag = 0;
+	
+	//float send_data[6]; // xyz[3] and angle[3]
+	int tapleid = node->id * 10 + 1;
+	int fd = *(int*)node->propertyptr;
+
+	// XDRの準備
+	XDR xdrs;
+	char send_data[SEND_DATA_SIZE];
+	xdrmem_create(&xdrs, send_data, SEND_DATA_SIZE, XDR_ENCODE);
+		
+	for (int i = 0; i < 3; i ++) {
+		xdr_float(&xdrs, &node->xyz[i]);
+	}
+	for (int i = 0; i < 3; i ++) {
+		xdr_float(&xdrs, &node->angle[i]);
+	}
+	node->seq = psx_in(fd, tapleid);
+	psx_out(fd, tapleid, (unsigned char *)send_data, SEND_DATA_SIZE);
+}
+
+void
+root_move(SceneGraphPtr node, void *sgroot_, int w, int h)
+{
+    SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
+    Pad *pad = sgroot->getController();
+	int flag = 0;
+    if (pad->right.isHold() || pad->left.isHold()) {
+		if (pad->right.isHold()) {
+			node->xyz[0] += 5.0f;
+			flag = 1;
+		} else if (pad->left.isHold()) {
+			node->xyz[0] -= 5.0f;
+			flag = 1;
+		}
+    }
+    
+    if (pad->down.isHold() || pad->up.isHold() ) {
+		if (pad->down.isHold()) {
+			node->xyz[1] += 5.0f;
+			flag = 1;
+		} else if (pad->up.isHold()) {
+			node->xyz[1] -= 5.0f;
+			flag = 1;
+		}
+    }
+
+	/*
+      ここでキー入力を向こうに送る
+	*/
+	if (flag || node->resend_flag) {
+		send_position(node);
+	}
+}
+
+void
+root_collision(SceneGraphPtr node, void *sgroot_, int w, int h, SceneGraphPtr tree)
+{
+}
+
+void
+move(SceneGraphPtr node, void *sgroot_, int w, int h)
+{
+}
+
+void
+collision(SceneGraphPtr node, void *sgroot_, int w, int h, SceneGraphPtr tree)
+{
+}
+
+void *
+file_map(const char *filename, int *size) {
+    int fd;
+    void *addr;
+    struct stat sb;
+
+    if ((fd = open(filename, O_RDONLY)) == -1) {
+		fprintf(stderr, "Can't open %s\n", filename);
+		perror(NULL);
+    }
+    if (fstat(fd, &sb) == -1) {
+		fprintf(stderr, "Can't fstat %s\n", filename);
+		perror(NULL);
+    }
+    *size = sb.st_size;
+    addr = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (addr == MAP_FAILED) {
+		perror("mmap error\n");
+		exit(EXIT_FAILURE);
+    }
+    close(fd);
+
+    return addr;
+}
+
+
+
+int get_serial_id(int fd) {
+    char *data;
+    int serial;
+    int seq;
+    
+    seq = psx_in(fd, 65535);
+	do {
+		psx_sync_n();
+		data = (char *)psx_reply(seq);
+	} while (data == 0);
+    serial = atoi(data + LINDA_HEADER_SIZE);
+    psx_free(data);
+	printf("serial id = %d\n", serial);
+    return serial;
+}
+
+
+void
+send_xml(int tspace, int xml_id, void *addr, int size) {
+    psx_out(tspace, xml_id, (unsigned char *)addr, size);
+    psx_sync_n();
+}
+
+static char *xml;
+static const char *linda = HOSTNAME;
+
+MainLoopPtr 
+send_linda::init(Viewer *sgr, int screen_w, int screen_h)
+{
+    void *addr;
+    int size;
+    int tspace;
+    int serial;
+    int xml_id;
+
+
+	// ここら辺長ったるいから、関数で分けるべきか...
+	
+	// root オブジェクト作成
+    SceneGraphPtr root = sgr->createSceneGraph();
+	// root_moveはコントローラーの入力で動き、座標をLinda Serverにout
+    root->set_move_collision(root_move, root_collision);
+
+	// XMLをメモリにmapして、オブジェクト生成
+    addr = file_map(xml, &size);
+    SceneGraphPtr sgp = sgr->createSceneGraph();
+    sgr->createFromXMLmemory(sgp, (char *)addr, size);
+    sgp->set_move_collision(move, collision);
+
+	// rootに接続
+    root->addChild(sgp);
+
+    // Linda Serverに接続
+    tspace = open_linda_java(linda, PORT_NUM);
+    // rootにLindaのfdを持たせる
+    root->propertyptr = (void*)malloc(sizeof(int));
+    int *p = (int*)root->propertyptr;
+    root->property_size = sizeof(int);
+    *p = tspace;
+
+    // このclientのserial_idを取得
+    serial = get_serial_id(tspace);
+    root->id = serial;
+
+	// ここから先の処理は、裏で何か動かせないかを考える
+	// とりあえず、関数に分けようか
+	
+    // serial_idを十倍したところにXMLを送信
+    xml_id = serial * 10;
+    send_xml(tspace, xml_id, addr, size); // ここのpsx_sync_n()は仕方ない
+
+	// XMLの送信が終了してから、serial_idをLindaに送信する
+	int client_id = htonl(serial);
+    psx_out(tspace, LISTEN_PORT, (unsigned char *)&client_id, sizeof(int));
+
+	// serial_idを十倍して1足したところに座標データを送る
+	// 初期化のout()
+	int pos_id = serial * 10 + 1;
+	char pos_data[SEND_DATA_SIZE] = {0};
+
+	// init seq
+	// send_position()でinの終了を確認する分岐が最初にあるため
+    psx_out(tspace, pos_id, (unsigned char *)pos_data, SEND_DATA_SIZE);
+	root->seq = 0;
+	root->resend_flag = 0;
+    sgr->setSceneData(root);
+	
+    return sgr;
+}
+
+extern Application *
+application() {
+    return new send_linda();
+}
+
+
+const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n";
+
+extern int init(TaskManager *manager, int argc, char *argv[]);
+extern void task_initialize();
+static void TMend(TaskManager *manager);
+
+int
+TMmain(TaskManager *manager, int argc, char *argv[])
+{
+    task_initialize();
+    manager->set_TMend(TMend);
+
+    for(int i=0;i<argc;i++) {
+		if (strcmp(argv[i],"-xml") == 0 && i+1<=argc) {
+			xml = argv[i+1];
+		} else if (strcmp(argv[i],"-linda") == 0 && i+1<=argc) {
+			linda = argv[i+1];
+		}
+    }
+
+    if (xml==0) {
+	printf("-xml xml-file is required\n");
+        exit(0);
+    }
+
+    return init(manager, argc, argv);
+
+}
+
+void
+TMend(TaskManager *manager)
+{
+    printf("test_nogl end\n");
+}
+
+/* end */
+