You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "CommandLineParams.h"
  2. #include "graphics/opengl/Window.h"
  3. #include "environment/Environment.h"
  4. #include "html/HTMLParser.h"
  5. #include "Log.h"
  6. #include "URL.h"
  7. #include "WebResource.h"
  8. #include "scheduler.h"
  9. #include <ctime>
  10. #include <iostream>
  11. #include <sys/stat.h>
  12. const std::unique_ptr<Window> window = std::make_unique<Window>();
  13. // why can't I const this?
  14. std::unique_ptr<Scheduler> scheduler = std::make_unique<Scheduler>();
  15. //URL currentURL;
  16. bool setWindowContent(URL const& url) {
  17. logDebug() << "main::setWindowContent - " << url << std::endl;
  18. // download URL
  19. WebResource res = getWebResource(url);
  20. if (res.resourceType == ResourceType::INVALID) {
  21. logError() << "Invalid resource type: " << res.raw << std::endl;
  22. return false;
  23. }
  24. // parse HTML
  25. if (res.resourceType == ResourceType::HTML) {
  26. HTMLParser parser;
  27. const std::clock_t begin = clock();
  28. std::shared_ptr<Node> rootNode = parser.parse(res.raw);
  29. const std::clock_t end = clock();
  30. logDebug() << "main::setWindowContent - Parsed document in: " << std::fixed << ((static_cast<double>(end - begin)) / CLOCKS_PER_SEC) << std::scientific << " seconds" << std::endl;
  31. // send NodeTree to window
  32. window->setDOM(rootNode);
  33. } else if (res.resourceType == ResourceType::TXT) {
  34. std::cout << "Rendering text document" << std::endl;
  35. std::shared_ptr<Node> rootNode = std::make_shared<Node>(NodeType::ROOT);
  36. std::shared_ptr<TagNode> tagNode = std::make_shared<TagNode>();
  37. tagNode->tag="p";
  38. // bind tag to root
  39. tagNode->parent = rootNode;
  40. rootNode->children.push_back(tagNode);
  41. std::shared_ptr<TextNode> textNode = std::make_shared<TextNode>();
  42. textNode->text = res.raw;
  43. // bind text to tag
  44. textNode->parent = tagNode;
  45. tagNode->children.push_back(textNode);
  46. // send NodeTree to window
  47. window->setDOM(rootNode);
  48. } else {
  49. std::cout << "setWindowContent() - I don't know how to render non-html files" << std::endl;
  50. }
  51. return true;
  52. }
  53. bool isAbsolutePath(const std::string s);
  54. bool isAbsolutePath(const std::string s) {
  55. return (s.length() > 0 && s[0] == '/');
  56. }
  57. bool fileExists(const std::string s);
  58. bool fileExists(const std::string s) {
  59. struct stat buf;
  60. return stat(s.c_str(), &buf) != -1;
  61. }
  62. int main(int argc, char *argv[]) {
  63. // no longer require a URL
  64. /*
  65. if (argc == 1) {
  66. std::cout << "./netrunner [http://host.tld/|/path/to/file.html] [-log <error|warning|notice|info|debug>]" << std::endl;
  67. return 1;
  68. }
  69. */
  70. std::cout << "/g/ntr - NetRunner build " << __DATE__ << std::endl;
  71. Environment::init();
  72. // we need to set up OGL before we can setDOM (because component can't be constructed (currently) without OGL)
  73. // but should be after CommandLineParams incase we need to change some type of window config
  74. window->windowWidth = 1024;
  75. window->windowHeight = 640;
  76. window->init();
  77. if (!window->window) {
  78. return 1;
  79. }
  80. //std::cout << "argc " << argc << std::endl;
  81. if (argc > 1) {
  82. initCLParams(argc, argv);
  83. // this isn't going to work
  84. std::string rawUrl = getCLParamByIndex(1);
  85. // if we do this here, shouldn't we do this in parseUri too?
  86. if (rawUrl.find("://") == rawUrl.npos) {
  87. // Path should always be absolute for file://
  88. if (isAbsolutePath(rawUrl)) {
  89. rawUrl = "file://" + rawUrl;
  90. } else {
  91. auto absolutePath = std::string(getenv("PWD")) + '/' + rawUrl;
  92. if (fileExists(absolutePath)) {
  93. rawUrl = "file://" + absolutePath;
  94. } else {
  95. // Default to http if the file wasn't found
  96. rawUrl = "http://" + rawUrl;
  97. }
  98. }
  99. }
  100. //logDebug() << "pre URL parse [" << url << "]" << std::endl;
  101. window->currentURL = URL(rawUrl);
  102. logDebug() << "loading [" << window->currentURL << "]" << std::endl;
  103. if (!setWindowContent(window->currentURL)) {
  104. return 1;
  105. }
  106. }
  107. while (!glfwWindowShouldClose(window->window)) {
  108. //const std::clock_t begin = clock();
  109. window->render();
  110. scheduler->fireTimers(); // render may have taken some time
  111. double next = scheduler->getNext();
  112. //std::cout << "next timer at " << next << std::endl;
  113. if (next == LONG_MAX) {
  114. glfwWaitEvents(); // block until something changes
  115. } else {
  116. glfwWaitEventsTimeout(next / 1000);
  117. }
  118. scheduler->fireTimers(); // check before we go into render again
  119. //glfwWaitEventsTimeout(1.0 / 60.0); // increase the cpu from 0% to 2% on idle
  120. //const std::clock_t end = clock();
  121. //std::cout << '\r' << std::fixed << (((static_cast<double>(end - begin)) / CLOCKS_PER_SEC) * 1000) << std::scientific << " ms/f " << std::flush;
  122. }
  123. return 0;
  124. }