Mercurial > hg > Game > Cerium
view Renderer/Test/send_linda.cc @ 841:8d702fc5d77a draft
dynamic loading demo bug fix
author | kazz <kazz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 02 Jun 2010 01:39:15 +0900 |
parents | 91e2c96be77b |
children | de64695a7f02 |
line wrap: on
line source
#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 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 */