Mercurial > hg > Members > e085722 > Cerium
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 */ +