this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

added libuv support for the future use

Nesbox be5055f0 41c4655c

+242 -2
+6
.gitmodules
··· 49 49 [submodule "vendor/circle-stdlib"] 50 50 path = vendor/circle-stdlib 51 51 url = https://github.com/smuehlst/circle-stdlib.git 52 + [submodule "vendor/libuv"] 53 + path = vendor/libuv 54 + url = https://github.com/libuv/libuv.git 55 + [submodule "vendor/http-parser"] 56 + path = vendor/http-parser 57 + url = https://github.com/nodejs/http-parser.git
+22
CMakeLists.txt
··· 591 591 endif() 592 592 593 593 ################################ 594 + # libuv 595 + ################################ 596 + 597 + if(USE_LIBUV) 598 + add_subdirectory(${THIRDPARTY_DIR}/libuv) 599 + endif() 600 + 601 + ################################ 602 + # HTTP parser 603 + ################################ 604 + 605 + if(USE_LIBUV) 606 + add_library(http_parser STATIC ${THIRDPARTY_DIR}/http-parser/http_parser.c) 607 + target_include_directories(http_parser INTERFACE ${THIRDPARTY_DIR}/http-parser) 608 + endif() 609 + 610 + ################################ 594 611 # TIC-80 studio 595 612 ################################ 596 613 ··· 632 649 633 650 if(USE_CURL) 634 651 target_link_libraries(tic80studio libcurl) 652 + endif() 653 + 654 + if(USE_LIBUV) 655 + target_compile_definitions(tic80studio PRIVATE USE_LIBUV) 656 + target_link_libraries(tic80studio uv_a http_parser) 635 657 endif() 636 658 637 659 if(BUILD_PRO)
+1 -1
build/android/app/build.gradle
··· 4 4 compileSdkVersion 26 5 5 defaultConfig { 6 6 applicationId 'com.nesbox.tic' 7 - minSdkVersion 16 7 + minSdkVersion 21 8 8 targetSdkVersion 26 9 9 versionCode 9000 10 10 versionName '0.90.00'
+1 -1
build/android/app/src/main/AndroidManifest.xml
··· 8 8 android:versionName="0.90.00" 9 9 android:installLocation="auto"> 10 10 11 - <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="26" /> 11 + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26" /> 12 12 13 13 <!-- OpenGL ES 2.0 --> 14 14 <uses-feature android:glEsVersion="0x00020000" />
+212
src/studio/net.c
··· 379 379 void netTickStart(Net *net) {} 380 380 void netTickEnd(Net *net) {} 381 381 382 + #elif defined(USE_LIBUV) 383 + 384 + #include "defines.h" 385 + 386 + #include <uv.h> 387 + #include <http_parser.h> 388 + 389 + struct Net 390 + { 391 + const char* host; 392 + char* path; 393 + 394 + HttpGetCallback callback; 395 + void* calldata; 396 + 397 + uv_tcp_t tcp; 398 + http_parser parser; 399 + 400 + struct 401 + { 402 + u8* data; 403 + s32 size; 404 + s32 total; 405 + } content; 406 + }; 407 + 408 + static s32 onBody(http_parser* parser, const char *at, size_t length) 409 + { 410 + Net* net = parser->data; 411 + 412 + net->content.data = realloc(net->content.data, net->content.size + length); 413 + memcpy(net->content.data + net->content.size, at, length); 414 + 415 + net->content.size += length; 416 + 417 + net->callback(&(HttpGetData) 418 + { 419 + .calldata = net->calldata, 420 + .type = HttpGetProgress, 421 + .progress = {net->content.size, net->content.total}, 422 + .url = net->path 423 + }); 424 + 425 + return 0; 426 + } 427 + 428 + static s32 onMessageComplete(http_parser* parser) 429 + { 430 + Net* net = parser->data; 431 + 432 + if (parser->status_code == HTTP_STATUS_OK) 433 + { 434 + net->callback(&(HttpGetData) 435 + { 436 + .calldata = net->calldata, 437 + .type = HttpGetDone, 438 + .done = { .data = net->content.data, .size = net->content.size }, 439 + .url = net->path 440 + }); 441 + 442 + free(net->content.data); 443 + free(net->path); 444 + } 445 + 446 + uv_close((uv_handle_t*)&net->tcp, NULL); 447 + 448 + return 0; 449 + } 450 + 451 + static s32 onHeadersComplete(http_parser* parser) 452 + { 453 + Net* net = parser->data; 454 + 455 + bool hasBody = parser->flags & F_CHUNKED || (parser->content_length > 0 && parser->content_length != ULLONG_MAX); 456 + 457 + ZEROMEM(net->content); 458 + net->content.total = parser->content_length; 459 + 460 + // !TODO: handle HTTP_STATUS_MOVED_PERMANENTLY here 461 + if (!hasBody || parser->status_code != HTTP_STATUS_OK) 462 + return 1; 463 + 464 + return 0; 465 + } 466 + 467 + static s32 onStatus(http_parser* parser, const char* at, size_t length) 468 + { 469 + return parser->status_code != HTTP_STATUS_OK; 470 + } 471 + 472 + static void onError(Net* net, s32 code) 473 + { 474 + net->callback(&(HttpGetData) 475 + { 476 + .calldata = net->calldata, 477 + .type = HttpGetError, 478 + .error = { .code = code } 479 + }); 480 + 481 + uv_close((uv_handle_t*)&net->tcp, NULL); 482 + free(net->path); 483 + } 484 + 485 + static void allocBuffer(uv_handle_t *handle, size_t size, uv_buf_t *buf) 486 + { 487 + buf->base = malloc(size); 488 + buf->len = size; 489 + } 490 + 491 + static void onResponse(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) 492 + { 493 + Net* net = stream->data; 494 + 495 + if(nread > 0) 496 + { 497 + static const http_parser_settings ParserSettings = 498 + { 499 + .on_status = onStatus, 500 + .on_body = onBody, 501 + .on_message_complete = onMessageComplete, 502 + .on_headers_complete = onHeadersComplete, 503 + }; 504 + 505 + s32 parsed = http_parser_execute(&net->parser, &ParserSettings, buf->base, nread); 506 + 507 + if(parsed != nread) 508 + onError(net, net->parser.status_code); 509 + 510 + free(buf->base); 511 + } 512 + else onError(net, 0); 513 + } 514 + 515 + static void onHeaderSent(uv_write_t *write, s32 status) 516 + { 517 + Net* net = write->data; 518 + http_parser_init(&net->parser, HTTP_RESPONSE); 519 + net->parser.data = net; 520 + 521 + 522 + uv_stream_t* handle = write->handle; 523 + free(write); 524 + 525 + handle->data = net; 526 + uv_read_start(handle, allocBuffer, onResponse); 527 + } 528 + 529 + static void onConnect(uv_connect_t *req, s32 status) 530 + { 531 + Net* net = req->data; 532 + 533 + char httpReq[2048]; 534 + snprintf(httpReq, sizeof httpReq, "GET %s HTTP/1.1\nHost: %s\n\n", net->path, net->host); 535 + 536 + uv_buf_t http = uv_buf_init(httpReq, strlen(httpReq)); 537 + uv_write(OBJCOPY((uv_write_t){.data = net}), req->handle, &http, 1, onHeaderSent); 538 + 539 + free(req); 540 + } 541 + 542 + static void onResolved(uv_getaddrinfo_t *resolver, s32 status, struct addrinfo *res) 543 + { 544 + Net* net = resolver->data; 545 + 546 + if (res) 547 + { 548 + uv_tcp_connect(OBJCOPY((uv_connect_t){.data = net}), &net->tcp, res->ai_addr, onConnect); 549 + uv_freeaddrinfo(res); 550 + } 551 + else onError(net, 0); 552 + 553 + free(resolver); 554 + } 555 + 556 + void netGet(Net* net, const char* path, HttpGetCallback callback, void* calldata) 557 + { 558 + uv_loop_t* loop = uv_default_loop(); 559 + 560 + net->callback = callback; 561 + net->calldata = calldata; 562 + net->path = strdup(path); 563 + 564 + uv_tcp_init(loop, &net->tcp); 565 + uv_getaddrinfo(loop, OBJCOPY((uv_getaddrinfo_t){.data = net}), onResolved, net->host, "80", NULL); 566 + } 567 + 568 + void netTickStart(Net *net) 569 + { 570 + uv_run(uv_default_loop(), UV_RUN_NOWAIT); 571 + } 572 + 573 + void netTickEnd(Net *net) {} 574 + 575 + Net* netCreate(const char* host) 576 + { 577 + Net* net = (Net*)malloc(sizeof(Net)); 578 + memset(net, 0, sizeof(Net)); 579 + 580 + net->host = host; 581 + 582 + static const char Http[] = "http://"; 583 + if(strstr(host, Http) == host) 584 + net->host += sizeof Http - 1; 585 + 586 + return net; 587 + } 588 + 589 + void netClose(Net* net) 590 + { 591 + free(net); 592 + } 593 + 382 594 #else 383 595 384 596 #include <curl/curl.h>