void make_client(Stack* stack) { printf("make_client\n"); Connection* connection = new Connection(); ca_assert(stack->world->libuvWorld->uv_loop != NULL); uv_tcp_init(stack->world->libuvWorld->uv_loop, &connection->uv_tcp); connection->uv_tcp.data = connection; Value* ip = circa_input(stack, 0); Value* port = circa_input(stack, 1); sockaddr_in bind_addr = uv_ip4_addr(circa_string(ip), circa_int(port)); #if 0 if (uv_ip4_addr(circa_string(ip), circa_int(port), &bind_addr)) { printf("error from uv_ip4_addr\n"); return; } #endif uv_connect_t* uv_connect = (uv_connect_t*) malloc(sizeof(*uv_connect)); uv_connect->data = connection; if (uv_tcp_connect(uv_connect, &connection->uv_tcp, bind_addr, client_on_connect)) { printf("uv_tcp_connect error\n"); } Value* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), connection, ConnectionRelease); printf("make_client fin\n"); }
void test_sneaky_equals() { Value val1, val2; set_string(&val1, "Hello"); set_string(&val2, "Hello"); // initial: strings are stored differently. test_assert(circa_string(&val1) != circa_string(&val2)); test_assert(circa_equals(&val1, &val2)); // after equality check: strings are stored with same object. test_assert(circa_string(&val1) == circa_string(&val2)); }
void compile_shader(GLenum type, caValue* contents, caValue* shaderOut) { GLint status; GLuint shader; shader = glCreateShader(type); const char* source = circa_string(contents); glShaderSource(shader, 1, &source, NULL); glCompileShader(shader); check_gl_error(); #if defined(DEBUG) GLint logLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetShaderInfoLog(shader, logLength, &logLength, log); printf("Shader compile log: %s\n", log); free(log); } #endif glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == 0) { glDeleteShader(shader); circa_set_error(shaderOut, "Failed to compile"); return; } check_gl_error(); circa_set_int(shaderOut, shader); Log("successfully compiled shader, index: ", shaderOut); }
void load_font(caStack* stack) { caValue* filename = circa_input(stack, 0); FontFace* font = new FontFace(); circa_read_file_with_stack(stack, circa_string(filename), &font->rawData); if (circa_is_null(&font->rawData)) return circa_output_error(stack, "Failed to load file"); if (!g_ftLibraryInitialized) { FT_Init_FreeType(&g_ftLibrary); g_ftLibraryInitialized = true; } int error = FT_New_Memory_Face(g_ftLibrary, (FT_Byte*) circa_blob(&font->rawData), circa_blob_size(&font->rawData), 0, &font->ftFace); if (error) return circa_output_error(stack, "FT_New_Memory_Face failed"); font->cairoFace = cairo_ft_font_face_create_for_ft_face(font->ftFace, 0); caValue* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), font, FontFaceRelease); }
static void try_parse(Value* str, Value* msgList) { int msgStart = 0; for (int i=0; i < circa_string_length(str); i++) { if (circa_string(str)[i] == 0) { if (i > msgStart) { Value* msg = circa_append(msgList); circa_parse_string_len(circa_string(str), i - msgStart, msg); } msgStart = i + 1; } } if (msgStart > 0) string_slice(str, msgStart, -1); }
void make_server(Stack* stack) { Value* ip = circa_input(stack, 0); Value* port = circa_input(stack, 1); Value* type = circa_input(stack, 2); Server* server = new Server(); if (circa_string_equals(type, ":tcp")) { server->serverType = TCP; } else if (circa_string_equals(type, ":websock")) { server->serverType = WEBSOCK; memset(&server->parser_settings, 0, sizeof(server->parser_settings)); server->parser_settings.on_message_begin = http_on_message_begin; server->parser_settings.on_url = http_on_url; server->parser_settings.on_status = http_on_status; server->parser_settings.on_header_field = http_on_header_field; server->parser_settings.on_header_value = http_on_header_value; server->parser_settings.on_headers_complete = http_on_headers_complete; server->parser_settings.on_body = http_on_body; server->parser_settings.on_message_complete = http_on_message_complete; } else { Value msg; circa_set_string(&msg, "Unrecognized server type: "); circa_string_append_val(&msg, type); circa_output_error_val(stack, &msg); delete server; return; } uv_loop_t* loop = get_uv_loop(stack->world); circa_set_list(&server->connections, 0); uv_tcp_init(stack->world->libuvWorld->uv_loop, &server->uv_tcp); struct sockaddr_in bind_addr = uv_ip4_addr(circa_string(ip), circa_int(port)); uv_tcp_bind(&server->uv_tcp, bind_addr); int err = uv_listen((uv_stream_t*) &server->uv_tcp, 128, server_on_connect); server->uv_tcp.data = server; if (err) { Value msg; circa_set_string(&msg, "Listen error: "); circa_string_append(&msg, uv_err_name(uv_last_error(loop))); circa_output_error_val(stack, &msg); return; } Value* out = circa_set_default_output(stack, 0); circa_set_native_ptr(circa_index(out, 0), server, ServerRelease); }
// Send 'msg' to the stream. 'msg' must be a string value. This function takes ownership // of 'msg'. static void circa_uv_write(uv_stream_t* stream, Value* msg, bool addNull) { uv_write_t *wr = (uv_write_t*) malloc(sizeof *wr); wr->data = msg; uv_buf_t outgoing_buf; outgoing_buf.base = (char*) circa_string(msg); outgoing_buf.len = circa_string_length(msg); if (addNull) outgoing_buf.len++; if (uv_write(wr, stream, &outgoing_buf, 1, after_write)) { printf("uv_write failed\n"); } }
bool fix_current_directory() { // Find the "ca" directory. If we're running from a Mac bundle, then we might need to // walk up a few directories. while (true) { if (file_exists("ca")) return true; // chdir to parent circa::Value currentDir, parentDir; improv_getcwd(¤tDir); circa_get_parent_directory(¤tDir, &parentDir); // If we reached the top, then fatal. if (circa_equals(¤tDir, &parentDir)) { printf("fatal: Couldn't find the 'ca' directory"); exit(-1); } chdir(circa_string(&parentDir)); } }
bool load_shaders(ResourceManager* resources, const char* baseFilename, Program* programStruct) { Log("Loading shader: %s", baseFilename); check_gl_error(); // Create shader program. GLuint program = glCreateProgram(); programStruct->program = program; // Load vertex shader. circa::Value vertShaderPathname; circa_set_string(&vertShaderPathname, baseFilename); circa_string_append(&vertShaderPathname, ".vsh"); circa::Value vertShader; resources->loadAsText(circa_string(&vertShaderPathname), &vertShader); if (circa_is_error(&vertShader) || !circa_is_string(&vertShader)) { Log("Failed to load vertex shader: %v", &vertShaderPathname); return false; } // Compile vertex shader circa::Value vertShaderIndex; compile_shader(GL_VERTEX_SHADER, &vertShader, &vertShaderIndex); if (circa_is_error(&vertShaderIndex)) { Log("Failed to compile vertex shader:", &vertShaderPathname); return false; } // Load fragment shader circa::Value fragShaderPathname; circa_set_string(&fragShaderPathname, baseFilename); circa_string_append(&fragShaderPathname, ".fsh"); circa::Value fragShader; resources->loadAsText(circa_string(&fragShaderPathname), &fragShader); if (circa_is_error(&fragShader) || !circa_is_string(&fragShader)) { Log("Failed to load fragment shader:", &fragShaderPathname); return false; } // Compile fragment shader circa::Value fragShaderIndex; compile_shader(GL_FRAGMENT_SHADER, &fragShader, &fragShaderIndex); check_gl_error(); if (circa_is_error(&fragShaderIndex)) { Log("Failed to compile frag shader: %v", &fragShaderPathname); return false; } int vertShaderHandle = circa_int(&vertShaderIndex); int fragShaderHandle = circa_int(&fragShaderIndex); // Attach vertex shader to program. glAttachShader(program, vertShaderHandle); check_gl_error(); // Attach fragment shader to program. glAttachShader(program, fragShaderHandle); check_gl_error(); // Link program. if (!link_program(program)) { Log("Failed to link shaders: %s", baseFilename); glDeleteShader(vertShaderHandle); glDeleteShader(fragShaderHandle); if (program) { glDeleteProgram(program); program = 0; } check_gl_error(); return false; } check_gl_error(); // Get attribute locations programStruct->attributes.vertex = glGetAttribLocation(program, "vertex"); programStruct->attributes.tex_coord = glGetAttribLocation(program, "tex_coord"); check_gl_error(); // Get uniform locations. programStruct->uniforms.modelViewProjectionMatrix = glGetUniformLocation(program, "modelViewProjectionMatrix"); programStruct->uniforms.normalMatrix = glGetUniformLocation(program, "normalMatrix"); programStruct->uniforms.sampler = glGetUniformLocation(program, "sampler"); programStruct->uniforms.sampler2 = glGetUniformLocation(program, "sampler2"); programStruct->uniforms.color = glGetUniformLocation(program, "color"); programStruct->uniforms.blend = glGetUniformLocation(program, "blend"); check_gl_error(); return true; }