blender/extern/verse/dist/vs_node_storage.c

246 lines
6.4 KiB
C

/*
**
*/
#include <stdio.h>
#include <stdlib.h>
#include "v_cmd_gen.h"
#if !defined V_GENERATE_FUNC_MODE
#include "verse.h"
#include "vs_server.h"
#define VS_NODE_STORAGE_CHUNK_SIZE 16
static struct {
VSNodeHead **nodes;
unsigned int node_length;
unsigned int node_allocated;
VSSubscriptionList *list[V_NT_NUM_TYPES];
} VSNodeStorage;
extern void callback_send_tag_group_create(void *user, VNodeID node_id, uint16 group_id, const char *name);
void vs_init_node_storage(void)
{
unsigned int i;
VSNodeStorage.nodes = malloc((sizeof *VSNodeStorage.nodes) * VS_NODE_STORAGE_CHUNK_SIZE);
VSNodeStorage.nodes[0] = NULL;
VSNodeStorage.node_length = 0;
VSNodeStorage.node_allocated = VS_NODE_STORAGE_CHUNK_SIZE;
for(i = 0; i < V_NT_NUM_TYPES; i++)
VSNodeStorage.list[i] = vs_create_subscription_list();
}
unsigned int vs_add_new_node(VSNodeHead *node, VNodeType type)
{
unsigned int i, j;
for(i = 0; i < VSNodeStorage.node_length && VSNodeStorage.nodes[i] != NULL; i++);
if(i >= VSNodeStorage.node_allocated)
{
j = VSNodeStorage.node_allocated;
VSNodeStorage.node_allocated += VS_NODE_STORAGE_CHUNK_SIZE;
VSNodeStorage.nodes = realloc(VSNodeStorage.nodes, (sizeof *VSNodeStorage.nodes) * VSNodeStorage.node_allocated);
while(j < VSNodeStorage.node_allocated)
VSNodeStorage.nodes[j++] = NULL;
}
VSNodeStorage.nodes[i] = node;
if(i >= VSNodeStorage.node_length)
VSNodeStorage.node_length = i + 1;
node->id = i;
node->type = type;
return node->id;
}
VSNodeHead *vs_get_node(unsigned int node_id, VNodeType type)
{
if(VSNodeStorage.node_length > node_id)
{
VSNodeHead *node = VSNodeStorage.nodes[node_id];
if(node != NULL && node->type == type)
return node;
}
return NULL;
}
VSNodeHead *vs_get_node_head(unsigned int node_id)
{
if(VSNodeStorage.node_length > node_id)
return VSNodeStorage.nodes[node_id];
return NULL;
}
extern VSNodeHead *vs_o_create_node(unsigned int owner);
extern VSNodeHead *vs_g_create_node(unsigned int owner);
extern VSNodeHead *vs_m_create_node(unsigned int owner);
extern VSNodeHead *vs_b_create_node(unsigned int owner);
extern VSNodeHead *vs_t_create_node(unsigned int owner);
extern VSNodeHead *vs_c_create_node(unsigned int owner);
extern VSNodeHead *vs_p_create_node(unsigned int owner);
extern VSNodeHead *vs_a_create_node(unsigned int owner);
extern void vs_o_destroy_node(VSNodeHead *node);
extern void vs_g_destroy_node(VSNodeHead *node);
extern void vs_m_destroy_node(VSNodeHead *node);
extern void vs_b_destroy_node(VSNodeHead *node);
extern void vs_t_destroy_node(VSNodeHead *node);
extern void vs_c_destroy_node(VSNodeHead *node);
extern void vs_p_destroy_node(VSNodeHead *node);
extern void vs_a_destroy_node(VSNodeHead *node);
VNodeID vs_node_create(VNodeID owner_id, unsigned int type)
{
unsigned int count, i;
VSNodeHead *node;
VNodeID node_id;
printf("vs_node_create(%u, %u)\n", owner_id, type);
switch(type)
{
case V_NT_OBJECT :
node = vs_o_create_node(owner_id);
break;
case V_NT_GEOMETRY :
node = vs_g_create_node(owner_id);
break;
case V_NT_MATERIAL :
node = vs_m_create_node(owner_id);
break;
case V_NT_BITMAP :
node = vs_b_create_node(owner_id);
break;
case V_NT_TEXT :
node = vs_t_create_node(owner_id);
break;
case V_NT_CURVE :
node = vs_c_create_node(owner_id);
break;
case V_NT_AUDIO :
node = vs_a_create_node(owner_id);
break;
default:
fprintf(stderr, "Can't create node of unknown type %u\n", type);
return 0U;
}
node_id = node->id;
count = vs_get_subscript_count(VSNodeStorage.list[type]);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(VSNodeStorage.list[type], i);
if(owner_id != verse_session_get_avatar())
verse_send_node_create(node_id, type, VN_OWNER_OTHER);
else
verse_send_node_create(node_id, type, VN_OWNER_MINE);
}
if(count != 0)
vs_reset_subscript_session();
return node_id;
}
/* Initialize an object node into being an avatar. */
void vs_avatar_init(VNodeID id, const char *name)
{
callback_send_tag_group_create(NULL, id, (short) ~0u, "avatar");
/* FIXME: Populate the group, too. */
}
void vs_reset_owner(VNodeID owner_id)
{
unsigned int i;
for(i = 0; i < VSNodeStorage.node_length; i++)
if(VSNodeStorage.nodes[i] != NULL)
if(VSNodeStorage.nodes[i]->owner == owner_id)
VSNodeStorage.nodes[i]->owner = ~0;
}
static void callback_send_node_create(void *user_data, VNodeID node_id, uint8 type, VNodeOwner owner_id)
{
vs_node_create(vs_get_avatar(), type);
}
void callback_send_node_destroy(void *user_data, VNodeID node_id)
{
unsigned int count, i;
VSNodeHead *node;
VNodeType type;
node = vs_get_node_head(node_id);
if(node == NULL)
return;
VSNodeStorage.nodes[node_id] = NULL;
type = node->type;
switch(type)
{
case V_NT_OBJECT :
vs_o_destroy_node(node);
break;
case V_NT_GEOMETRY :
vs_g_destroy_node(node);
break;
case V_NT_MATERIAL :
vs_m_destroy_node(node);
break;
case V_NT_BITMAP :
vs_b_destroy_node(node);
break;
case V_NT_TEXT :
vs_t_destroy_node(node);
break;
case V_NT_CURVE :
vs_c_destroy_node(node);
break;
case V_NT_AUDIO :
vs_c_destroy_node(node);
break;
default:
fprintf(stderr, __FILE__ " Can't handle node_destroy for type %d--not implemented", type);
return;
}
count = vs_get_subscript_count(VSNodeStorage.list[type]);
for(i = 0; i < count; i++)
{
vs_set_subscript_session(VSNodeStorage.list[type], i);
verse_send_node_destroy(node_id);
}
vs_reset_subscript_session();
}
static void callback_send_node_index_subscribe(void *user_data, uint32 mask)
{
unsigned int i, j, pow = 1;
for(i = 0; i < V_NT_NUM_TYPES; i++, pow <<= 1)
{
if((mask & pow) != 0)
{
for(j = 0; j < VSNodeStorage.node_length; j++)
{
if(VSNodeStorage.nodes[j] != NULL && VSNodeStorage.nodes[j]->type == (VNodeType)i)
{
if(VSNodeStorage.nodes[j]->owner == verse_session_get_avatar())
verse_send_node_create(VSNodeStorage.nodes[j]->id, i, VN_OWNER_MINE);
else
verse_send_node_create(VSNodeStorage.nodes[j]->id, i, VN_OWNER_OTHER);
}
}
vs_add_new_subscriptor(VSNodeStorage.list[i]);
}
else
vs_remove_subscriptor(VSNodeStorage.list[i]);
}
}
void init_callback_node_storage(void)
{
verse_callback_set(verse_send_node_index_subscribe, callback_send_node_index_subscribe, NULL);
verse_callback_set(verse_send_node_create, callback_send_node_create, NULL);
verse_callback_set(verse_send_node_destroy, callback_send_node_destroy, NULL);
}
#endif