Example #1
0
File: main.c Project: emilis/Craft
void ensure_chunks(Chunk *chunks, int *chunk_count, int p, int q, int force) {
    int count = *chunk_count;
    for (int i = 0; i < count; i++) {
        Chunk *chunk = chunks + i;
        if (chunk_distance(chunk, p, q) >= DELETE_CHUNK_RADIUS) {
            map_free(&chunk->map);
            glDeleteBuffers(1, &chunk->position_buffer);
            glDeleteBuffers(1, &chunk->normal_buffer);
            glDeleteBuffers(1, &chunk->uv_buffer);
            Chunk *other = chunks + (--count);
            memcpy(chunk, other, sizeof(Chunk));
        }
    }
    int n = CREATE_CHUNK_RADIUS;
    for (int i = -n; i <= n; i++) {
        for (int j = -n; j <= n; j++) {
            int a = p + i;
            int b = q + j;
            if (!find_chunk(chunks, count, a, b)) {
                make_chunk(chunks + count, a, b);
                count++;
                if (!force) {
                    *chunk_count = count;
                    return;
                }
            }
        }
    }
    *chunk_count = count;
}
Example #2
0
void ensure_chunks(Chunk *chunks, int *chunk_count, int p, int q, int force) {
    int count = *chunk_count;
    for (int i = 0; i < count; i++) {
        Chunk *chunk = chunks + i;
        if (chunk_distance(chunk, p, q) >= DELETE_CHUNK_RADIUS) {
            map_free(&chunk->map);
            glDeleteBuffers(1, &chunk->position_buffer);
            glDeleteBuffers(1, &chunk->normal_buffer);
            glDeleteBuffers(1, &chunk->uv_buffer);
            Chunk *other = chunks + (--count);
            memcpy(chunk, other, sizeof(Chunk));
        }
    }
    int n = force ? 1 : CREATE_CHUNK_RADIUS;
    for (int i = 0; i <= n; i++) {
        for (int dp = -n; dp <= n; dp++) {
            for (int dq = -n; dq <= n; dq++) {
                int j = MAX(ABS(dp), ABS(dq));
                if (i != j) {
                    continue;
                }
                int a = p + dp;
                int b = q + dq;
                if (!find_chunk(chunks, count, a, b)) {
                    make_chunk(chunks + count, a, b);
                    count++;
                    if (!force) {
                        *chunk_count = count;
                        return;
                    }
                }
            }
        }
    }
    *chunk_count = count;
}
Example #3
0
void fxx() {

    boost::asio::io_context ioc;
    auto work = boost::asio::make_work_guard(ioc);
    std::thread t{[&](){ ioc.run(); }};
    boost::asio::ip::tcp::socket sock{ioc};

{
//[http_snippet_2

    request<empty_body> req;
    req.version(11);   // HTTP/1.1
    req.method(verb::get);
    req.target("/index.htm");
    req.set(field::accept, "text/html");
    req.set(field::user_agent, "Beast");

//]
}

{
//[http_snippet_3

    response<string_body> res;
    res.version(11);   // HTTP/1.1
    res.result(status::ok);
    res.set(field::server, "Beast");
    res.body() = "Hello, world!";
    res.prepare_payload();

//]
}

{
//[http_snippet_4

    flat_buffer buffer;         // (The parser is optimized for flat buffers)
    request<string_body> req;
    read(sock, buffer, req);

//]
}

{
//[http_snippet_5

    flat_buffer buffer;
    response<string_body> res;
    async_read(sock, buffer, res,
        [&](error_code ec, std::size_t bytes_transferred)
        {
            boost::ignore_unused(bytes_transferred);
            std::cerr << ec.message() << std::endl;
        });

//]
}

{
//[http_snippet_6

    // This buffer's max size is too small for much of anything
    flat_buffer buffer{10};

    // Try to read a request
    error_code ec;
    request<string_body> req;
    read(sock, buffer, req, ec);
    if(ec == error::buffer_overflow)
        std::cerr << "Buffer limit exceeded!" << std::endl;

//]
}

{
//[http_snippet_7

    response<string_body> res;
    res.version(11);
    res.result(status::ok);
    res.set(field::server, "Beast");
    res.body() = "Hello, world!";
    res.prepare_payload();

    error_code ec;
    write(sock, res, ec);
//]

//[http_snippet_8
    async_write(sock, res,
        [&](error_code ec, std::size_t bytes_transferred)
        {
            boost::ignore_unused(bytes_transferred);
            if(ec)
                std::cerr << ec.message() << std::endl;
        });
//]
}

{
//[http_snippet_10

    response<string_body> res;

    response_serializer<string_body> sr{res};

//]
}

{
//[http_snippet_18
    // Prepare an HTTP/1.1 response with a chunked body
    response<empty_body> res{status::ok, 11};
    res.set(field::server, "Beast");

    // Set Transfer-Encoding to "chunked".
    // If a Content-Length was present, it is removed.
    res.chunked(true);

    // Set up the serializer
    response_serializer<empty_body> sr{res};

    // Write the header first
    write_header(sock, sr);

    // Now manually emit three chunks:
    boost::asio::write(sock, make_chunk(get_next_chunk_body()));
    boost::asio::write(sock, make_chunk(get_next_chunk_body()));
    boost::asio::write(sock, make_chunk(get_next_chunk_body()));

    // We are responsible for sending the last chunk:
    boost::asio::write(sock, make_chunk_last());
//]
}

{
//[http_snippet_19
    // Prepare a set of chunk extension to emit with the body
    chunk_extensions ext;
    ext.insert("mp3");
    ext.insert("title", "Beale Street Blues");
    ext.insert("artist", "W.C. Handy");

    // Write the next chunk with the chunk extensions
    // The implementation will make a copy of the extensions object,
    // so the caller does not need to manage lifetime issues.
    boost::asio::write(sock, make_chunk(get_next_chunk_body(), ext));

    // Write the next chunk with the chunk extensions
    // The implementation will make a copy of the extensions object, storing the copy
    // using the custom allocator, so the caller does not need to manage lifetime issues.
    boost::asio::write(sock, make_chunk(get_next_chunk_body(), ext, std::allocator<char>{}));

    // Write the next chunk with the chunk extensions
    // The implementation allocates memory using the default allocator and takes ownership
    // of the extensions object, so the caller does not need to manage lifetime issues.
    // Note: ext is moved
    boost::asio::write(sock, make_chunk(get_next_chunk_body(), std::move(ext)));
//]
}

{
//[http_snippet_20
    // Manually specify the chunk extensions.
    // Some of the strings contain spaces and a period and must be quoted
    boost::asio::write(sock, make_chunk(get_next_chunk_body(),
        ";mp3"
        ";title=\"Danny Boy\""
        ";artist=\"Fred E. Weatherly\""
        ));
//]
}

{
//[http_snippet_21
    // Prepare a chunked HTTP/1.1 response with some trailer fields
    response<empty_body> res{status::ok, 11};
    res.set(field::server, "Beast");

    // Inform the client of the trailer fields we will send
    res.set(field::trailer, "Content-MD5, Expires");

    res.chunked(true);

    // Serialize the header and two chunks
    response_serializer<empty_body> sr{res};
    write_header(sock, sr);
    boost::asio::write(sock, make_chunk(get_next_chunk_body()));
    boost::asio::write(sock, make_chunk(get_next_chunk_body()));

    // Prepare the trailer
    fields trailer;
    trailer.set(field::content_md5, "f4a5c16584f03d90");
    trailer.set(field::expires, "never");

    // Emit the trailer in the last chunk.
    // The implementation will use the default allocator to create the storage for holding
    // the serialized fields.
    boost::asio::write(sock, make_chunk_last(trailer));
//]
}

{
//[http_snippet_22
    // Use a custom allocator for serializing the last chunk
    fields trailer;
    trailer.set(field::approved, "yes");
    boost::asio::write(sock, make_chunk_last(trailer, std::allocator<char>{}));
//]
}

{
//[http_snippet_23
    // Manually emit a trailer.
    // We are responsible for ensuring that the trailer format adheres to the specification.
    string_view ext =
        "Content-MD5: f4a5c16584f03d90\r\n"
        "Expires: never\r\n"
        "\r\n";
    boost::asio::write(sock, make_chunk_last(boost::asio::const_buffer{ext.data(), ext.size()}));
//]
}

{
//[http_snippet_24
    // Prepare a chunked HTTP/1.1 response and send the header
    response<empty_body> res{status::ok, 11};
    res.set(field::server, "Beast");
    res.chunked(true);
    response_serializer<empty_body> sr{res};
    write_header(sock, sr);

    // Obtain three body buffers up front
    auto const cb1 = get_next_chunk_body();
    auto const cb2 = get_next_chunk_body();
    auto const cb3 = get_next_chunk_body();

    // Manually emit a chunk by first writing the chunk-size header with the correct size
    boost::asio::write(sock, chunk_header{
        boost::asio::buffer_size(cb1) +
        boost::asio::buffer_size(cb2) +
        boost::asio::buffer_size(cb3)});

    // And then output the chunk body in three pieces ("chunk the chunk")
    boost::asio::write(sock, cb1);
    boost::asio::write(sock, cb2);
    boost::asio::write(sock, cb3);

    // When we go this deep, we are also responsible for the terminating CRLF
    boost::asio::write(sock, chunk_crlf{});
//]
}

} // fxx()