Mercurial > hg > Members > kono > Cerium
view Renderer/Test/dynamic_create.cc @ 575:0f13810d4492
Linda API worked. (slightly unreliable)
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 23 Oct 2009 15:53:24 +0900 |
parents | 6289230fe821 |
children | cc989924f469 |
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 "SceneGraphRoot.h" #include "lindaapi.h" #include "dynamic_create.h" #define PORT 10000 #define SERIAL_REGIST_TUPLE_NO 1 /* typedef struct { caddr_t file_mmap; off_t size; } st_mmap_t; */ typedef struct client_ { int id; SceneGraphPtr sgp; struct client_ *next; } client_t; typedef struct { int tid; int sid; int read_id; SceneGraphPtr node; TaskManager *manager; client_t *clist; } callback_arg; void client_list_init(TaskManager* manager, client_t *clist) { clist->id = -1; clist->next = clist; } void client_list_update(TaskManager *manager, client_t *clist, int id, SceneGraphPtr sgp) { //client_t *c; // for (c = clist->next; c != clist; c = c->next) { // if (c->id == id) { // c->sgp = sgp; // return; // } // } // c->next = (client_t *)manager->allocate(sizeof(client_t)); // c->next->id = id; // c->next->sgp = sgp; // c->next->next = clist; } void client_list_delete(TaskManager *manager, client_t *clist, int id) { client_t *c, *prev; for (c = clist->next, prev = clist; c->next != clist; c = c->next) { if (c->id == id) { prev->next = c->next; return; } prev = clist; } if (c->id == id) { prev->next = c->next; return; } } int fix_byte(int size,int fix_byte_size) { size = (size/fix_byte_size)*fix_byte_size + ((size%fix_byte_size)!= 0)*fix_byte_size; return size; } st_mmap_t my_mmap(char *filename) { int fd = -1; int map = MAP_PRIVATE; st_mmap_t st_mmap; struct stat sb; if ((fd = open(filename, O_RDONLY, 0666)) == 0 ) { fprintf(stderr, "Can't open %s\n", filename); } if (fstat(fd, &sb)) { fprintf(stderr, "Can't fstat %s\n", filename); } printf("file size %d\n", (int)sb.st_size); st_mmap.size = fix_byte(sb.st_size, 4096); printf("fix 4096byte file size %d\n", (int)st_mmap.size); st_mmap.file_mmap = (char *)mmap(NULL, st_mmap.size, PROT_READ, map, fd, (off_t)0); if (st_mmap.file_mmap == (caddr_t)-1) { fprintf(stderr, "Can't mmap file\n"); perror(NULL); exit(0); } return st_mmap; } static void earth_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree) { } static void moon_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree) { } static void moon_move(SceneGraphPtr node, int screen_w, int screen_h) { //node->angle[0] += 3.0f; node->xyz[1] += 1.0f; } static void earth_move(SceneGraphPtr node, int screen_w, int screen_h) { // psx_sync_n(); in viewer::MainLoop } SceneGraphPtr create_sg(TaskManager *manager, SceneGraphPtr node, unsigned char *data, int len, int serial_id) { SceneGraphPtr object; sgroot->createFromXMLmemory(sgroot->tmanager, (char *)data, len); object = sgroot->createSceneGraph(sgroot->getLast()); object->id = serial_id; object->set_move_collision(moon_move, moon_collision); node->addChild(object); return object; } // void // del_callback(unsigned char *data, void *arg) // { // free(data); // } // void // psx_del(int t, int id) // { // psx_callback_in(t, id, del_callback, NULL); // } static void callback_get_xml(unsigned char *xml_tuple, void *arg) { int xml_len = psx_get_datalength(xml_tuple); callback_arg *carg = (callback_arg *)arg; unsigned char *xml_data = xml_tuple+LINDA_HEADER_SIZE; SceneGraphPtr sgp; // ここで create fwrite(xml_data, 1, 10, stdout); sgp = create_sg(carg->manager, carg->node, xml_data, xml_len, carg->sid); client_list_update(carg->manager, carg->clist, carg->sid, sgp); free(arg); free(xml_tuple); } static void callbacker(unsigned char *tuple, void *arg) { int serial_id, xml_id; unsigned char *data; callback_arg *carg = (callback_arg *)arg; // 最初の4byteデータは使わない data = tuple+LINDA_HEADER_SIZE; // clientのSerialIDを取得 serial_id = ntohl(*(int *)data); printf("serial id = %d\n", serial_id); // タプルを解放 //psx_del(carg->tid, SERIAL_REGIST_TUPLE_NO); // xml fileを取得する もうすでにxml fileが送信済みである事を期待 // つまり、送信者がserial_idを送る前にxml fileを送信していなくてはならない xml_id = serial_id * 10; callback_arg *copy_arg = (callback_arg *)carg->manager->allocate(sizeof(callback_arg)); *copy_arg = *carg; copy_arg->sid = serial_id; psx_callback_in(carg->tid, xml_id, callback_get_xml, (void *)copy_arg); /* dataは'\0'で終わっている事を期待 (writerで保証する) */ //printf("get data[%d]: `%s'\n", len, data); free(tuple); psx_callback_in(carg->tid, carg->read_id, callbacker, arg); } void linda_init(TaskManager *manager, client_t *clist, SceneGraphPtr node) { init_linda(); callback_arg *carg = (callback_arg *)manager->allocate(sizeof(callback_arg)); carg->tid = open_linda_java("localhost", PORT); carg->read_id = SERIAL_REGIST_TUPLE_NO; carg->node = node; carg->manager = manager; carg->clist = clist; psx_callback_in(carg->tid, carg->read_id, callbacker, carg); } MainLoopPtr dynamic_create::init(Viewer *sgroot, int screen_w, int screen_h) { //SceneGraphPtr earth; client_t *clist; clist = (client_t *)sgroot->manager->allocate(sizeof(client_t)); client_list_init(sgroot->manager, clist); SceneGraphPtr parent; parent = sgroot->createSceneGraph(); parent->set_move_collision(earth_move, earth_collision); parent->xyz[0] += 300; linda_init(sgroot->manager, clist, parent); // SceneGraphRoot に、使用する SceneGraph を設定する // このとき、ユーザーが記述した SceneGraph の root を渡す。 sgroot->setSceneData(parent); return sgroot; } extern Application * application() { return new dynamic_create(); } 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); return init(manager, argc, argv); } void TMend(TaskManager *manager) { printf("test_nogl end\n"); } /* end */