diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..eff78aac --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,340 @@ +--- +# Taken from Suven-p/Pacman_OpenGL +Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,bugprone-*,-bugprone-narrowing-conversions,cppcoreguidelines-*,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-avoid-magic-numbers,modernize-*,-modernize-use-trailing-return-type,-modernize-avoid-c-arrays,performance-*,-performance-no-int-to-ptr,readability-*,-readability-magic-numbers,portability-*,clang-analyzer-*' +WarningsAsErrors: '' +# The following seeems to filter out headers. I'll leave it in case we need it +# HeaderFilterRegex: '.*\.h+(pp)?' +AnalyzeTemporaryDtors: false +FormatStyle: file +CheckOptions: + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: cppcoreguidelines-no-malloc.Reallocations + value: '::realloc' + - key: cppcoreguidelines-owning-memory.LegacyResourceConsumers + value: '::free;::realloc;::freopen;::fclose' + - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold + value: '3' + - key: readability-function-size.VariableThreshold + value: '4294967295' + - key: modernize-use-auto.MinTypeNameLength + value: '5' + - key: bugprone-reserved-identifier.Invert + value: 'false' + - key: performance-move-const-arg.CheckTriviallyCopyableMove + value: 'true' + - key: cert-dcl16-c.NewSuffixes + value: 'L;LL;LU;LLU' + - key: cppcoreguidelines-macro-usage.CheckCapsOnly + value: 'false' + - key: readability-identifier-naming.GetConfigPerFile + value: 'true' + - key: readability-inconsistent-declaration-parameter-name.Strict + value: 'false' + - key: bugprone-unused-return-value.CheckedFunctions + value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname' + - key: modernize-use-default-member-init.UseAssignment + value: 'false' + - key: readability-function-size.NestingThreshold + value: '4294967295' + - key: modernize-use-override.AllowOverrideAndFinal + value: 'false' + - key: readability-function-size.ParameterThreshold + value: '4294967295' + - key: modernize-pass-by-value.ValuesOnly + value: 'false' + - key: modernize-loop-convert.IncludeStyle + value: llvm + - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons + value: '0' + - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison + value: 'false' + - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal + value: 'false' + - key: readability-redundant-smartptr-get.IgnoreMacros + value: 'true' + - key: readability-identifier-naming.AggressiveDependentMemberLookup + value: 'false' + - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison + value: 'true' + - key: modernize-use-emplace.TupleTypes + value: '::std::pair;::std::tuple' + - key: modernize-use-emplace.TupleMakeFunctions + value: '::std::make_pair;::std::make_tuple' + - key: cppcoreguidelines-owning-memory.LegacyResourceProducers + value: '::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile' + - key: bugprone-argument-comment.CommentNullPtrs + value: '0' + - key: bugprone-argument-comment.StrictMode + value: '0' + - key: cppcoreguidelines-init-variables.IncludeStyle + value: llvm + - key: modernize-use-nodiscard.ReplacementString + value: '[[nodiscard]]' + - key: modernize-replace-random-shuffle.IncludeStyle + value: llvm + - key: modernize-loop-convert.MakeReverseRangeHeader + value: '' + - key: modernize-use-bool-literals.IgnoreMacros + value: 'true' + - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField + value: 'true' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions + value: '' + - key: modernize-avoid-bind.PermissiveParameterList + value: 'false' + - key: modernize-use-override.FinalSpelling + value: final + - key: performance-move-constructor-init.IncludeStyle + value: llvm + - key: modernize-loop-convert.UseCxx20ReverseRanges + value: 'true' + - key: modernize-use-noexcept.ReplacementString + value: '' + - key: modernize-use-using.IgnoreMacros + value: 'true' + - key: performance-type-promotion-in-math-fn.IncludeStyle + value: llvm + - key: cppcoreguidelines-explicit-virtual-functions.FinalSpelling + value: final + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: bugprone-suspicious-include.ImplementationFileExtensions + value: 'c;cc;cpp;cxx' + - key: cppcoreguidelines-pro-type-member-init.UseAssignment + value: 'false' + - key: modernize-loop-convert.MakeReverseRangeFunction + value: '' + - key: bugprone-suspicious-include.HeaderFileExtensions + value: ';h;hh;hpp;hxx' + - key: performance-no-automatic-move.AllowedTypes + value: '' + - key: performance-for-range-copy.WarnOnAllAutoCopies + value: 'false' + - key: bugprone-argument-comment.CommentIntegerLiterals + value: '0' + - key: bugprone-suspicious-missing-comma.SizeThreshold + value: '5' + - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros + value: 'true' + - key: readability-identifier-naming.IgnoreFailedSplit + value: 'false' + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: bugprone-sizeof-expression.WarnOnSizeOfThis + value: 'true' + - key: bugprone-argument-comment.CommentFloatLiterals + value: '0' + - key: bugprone-string-constructor.WarnOnLargeLength + value: 'true' + - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit + value: '16' + - key: readability-qualified-auto.AddConstToQualified + value: 'true' + - key: cppcoreguidelines-explicit-virtual-functions.OverrideSpelling + value: override + - key: readability-simplify-boolean-expr.ChainedConditionalReturn + value: 'false' + - key: readability-else-after-return.WarnOnConditionVariables + value: 'true' + - key: readability-uppercase-literal-suffix.IgnoreMacros + value: 'true' + - key: modernize-use-nullptr.NullMacros + value: 'NULL' + - key: modernize-make-shared.IgnoreMacros + value: 'true' + - key: bugprone-dynamic-static-initializers.HeaderFileExtensions + value: ';h;hh;hpp;hxx' + - key: bugprone-suspicious-enum-usage.StrictMode + value: 'false' + - key: performance-unnecessary-copy-initialization.AllowedTypes + value: '' + - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens + value: '5' + - key: modernize-use-transparent-functors.SafeMode + value: 'false' + - key: cppcoreguidelines-macro-usage.AllowedRegexp + value: '^DEBUG_*' + - key: modernize-make-shared.IgnoreDefaultInitialization + value: 'true' + - key: bugprone-argument-comment.CommentCharacterLiterals + value: '0' + - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions + value: 'true' + - key: modernize-make-shared.IncludeStyle + value: llvm + - key: bugprone-string-constructor.LargeLengthThreshold + value: '8388608' + - key: readability-simplify-boolean-expr.ChainedConditionalAssignment + value: 'false' + - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions + value: 'false' + - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField + value: '0' + - key: bugprone-exception-escape.FunctionsThatShouldNotThrow + value: '' + - key: performance-inefficient-vector-operation.EnableProto + value: 'false' + - key: readability-function-size.LineThreshold + value: '4294967295' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: bugprone-argument-comment.CommentStringLiterals + value: '0' + - key: modernize-make-shared.MakeSmartPtrFunction + value: 'std::make_shared' + - key: bugprone-signed-char-misuse.CharTypdefsToIgnore + value: '' + - key: portability-simd-intrinsics.Suggest + value: 'false' + - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader + value: '' + - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors + value: 'true' + - key: modernize-make-unique.IgnoreMacros + value: 'true' + - key: performance-for-range-copy.AllowedTypes + value: '' + - key: modernize-make-shared.MakeSmartPtrFunctionHeader + value: '' + - key: modernize-use-override.IgnoreDestructors + value: 'false' + - key: bugprone-sizeof-expression.WarnOnSizeOfConstant + value: 'true' + - key: readability-redundant-string-init.StringNames + value: '::std::basic_string_view;::std::basic_string' + - key: modernize-make-unique.IgnoreDefaultInitialization + value: 'true' + - key: modernize-use-emplace.ContainersWithPushBack + value: '::std::vector;::std::list;::std::deque' + - key: modernize-make-unique.IncludeStyle + value: llvm + - key: readability-braces-around-statements.ShortStatementLines + value: '0' + - key: bugprone-argument-comment.CommentUserDefinedLiterals + value: '0' + - key: bugprone-argument-comment.CommentBoolLiterals + value: '0' + - key: modernize-use-override.OverrideSpelling + value: override + - key: performance-inefficient-string-concatenation.StrictMode + value: 'false' + - key: readability-implicit-bool-conversion.AllowPointerConditions + value: 'false' + - key: readability-redundant-declaration.IgnoreMacros + value: 'true' + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: modernize-make-unique.MakeSmartPtrFunction + value: 'std::make_unique' + - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays + value: 'false' + - key: readability-else-after-return.WarnOnUnfixable + value: 'true' + - key: bugprone-reserved-identifier.AllowedIdentifiers + value: '' + - key: modernize-use-emplace.IgnoreImplicitConstructors + value: 'false' + - key: modernize-make-unique.MakeSmartPtrFunctionHeader + value: '' + - key: portability-restrict-system-includes.Includes + value: '*' + - key: modernize-use-equals-delete.IgnoreMacros + value: 'true' + - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle + value: llvm + - key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros + value: 'true' + - key: bugprone-misplaced-widening-cast.CheckImplicitCasts + value: 'false' + - key: readability-uppercase-literal-suffix.NewSuffixes + value: '' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: performance-unnecessary-value-param.AllowedTypes + value: '' + - key: bugprone-suspicious-missing-comma.RatioThreshold + value: '0.200000' + - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted + value: 'false' + - key: modernize-use-noexcept.UseNoexceptFalse + value: 'true' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: readability-function-cognitive-complexity.Threshold + value: '25' + - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: '1' + - key: bugprone-argument-comment.IgnoreSingleArgument + value: '0' + - key: cppcoreguidelines-no-malloc.Allocations + value: '::malloc;::calloc' + - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression + value: 'false' + - key: performance-faster-string-find.StringLikeClasses + value: '::std::basic_string;::std::basic_string_view' + - key: bugprone-assert-side-effect.CheckFunctionCalls + value: 'false' + - key: readability-function-size.BranchThreshold + value: '4294967295' + - key: bugprone-string-constructor.StringNames + value: '::std::basic_string;::std::basic_string_view' + - key: bugprone-assert-side-effect.AssertMacros + value: assert + - key: bugprone-exception-escape.IgnoredExceptions + value: '' + - key: readability-function-size.StatementThreshold + value: '800' + - key: modernize-use-default-member-init.IgnoreMacros + value: 'true' + - key: llvm-qualified-auto.AddConstToQualified + value: '0' + - key: bugprone-signed-char-misuse.DiagnoseSignedUnsignedCharComparisons + value: 'true' + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 'false' + - key: readability-implicit-bool-conversion.AllowIntegerConditions + value: 'false' + - key: cppcoreguidelines-init-variables.MathHeader + value: '' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: llvm-else-after-return.WarnOnConditionVariables + value: '0' + - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant + value: 'true' + - key: bugprone-reserved-identifier.AggressiveDependentMemberLookup + value: 'false' + - key: modernize-raw-string-literal.DelimiterStem + value: lit + - key: modernize-use-equals-default.IgnoreMacros + value: 'true' + - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor + value: 'false' + - key: modernize-raw-string-literal.ReplaceShorterLiterals + value: 'false' + - key: modernize-use-emplace.SmartPointers + value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' + - key: cppcoreguidelines-no-malloc.Deallocations + value: '::free' + - key: modernize-use-auto.RemoveStars + value: 'false' + - key: bugprone-dangling-handle.HandleClasses + value: 'std::basic_string_view;std::experimental::basic_string_view' + - key: performance-inefficient-vector-operation.VectorLikeClasses + value: '::std::vector' + - key: portability-simd-intrinsics.Std + value: '' + - key: performance-unnecessary-value-param.IncludeStyle + value: llvm + - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors + value: 'false' + - key: modernize-replace-disallow-copy-and-assign-macro.MacroName + value: DISALLOW_COPY_AND_ASSIGN + - key: llvm-else-after-return.WarnOnUnfixable + value: '0' + - key: readability-simplify-subscript-expr.Types + value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' +... \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..c2dbd15e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,13 @@ +# Allow custom line endings during checkout, but enforce LF on checkin +*.cc text +*.c text +*.hh text +*.h text + +*.py text +*.md text + +*.txt text + +*.bml binary + diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 74186349..8e94749f 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -4,7 +4,6 @@ on: push: branches: [main] pull_request: - branches: [main] workflow_dispatch: jobs: diff --git a/.gitignore b/.gitignore index f9a81a5c..d2a29791 100644 --- a/.gitignore +++ b/.gitignore @@ -53,8 +53,9 @@ libs/ *~ \#* -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# Source: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # User-specific stuff .idea/**/workspace.xml @@ -63,6 +64,9 @@ libs/ .idea/**/dictionaries .idea/**/shelf +# AWS User-specific +.idea/**/aws.xml + # Generated files .idea/**/contentModel.xml @@ -83,12 +87,52 @@ libs/ # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml # .idea/modules.xml # .idea/*.iml # .idea/modules # *.iml # *.ipr +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + + # CMake cmake-build-*/ cmake_install.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a4c0d94..601a6058 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,11 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libs) set(CMAKE_FILES_DIRECTORY build) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/modules) +set(CMAKE_C_STANDARD 17) set(CMAKE_CXX_STANDARD 20) +option(CMAKE_C_STANDARD_REQUIRED ON) option(CMAKE_CXX_STANDARD_REQUIRED ON) +option(CMAKE_C_EXTENSIONS OFF) option(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON @@ -82,6 +85,11 @@ if(GRAIL_WERROR) endif() endif() +if(GRAIL_TIDY) + message(STATUS "clang-tidy modern checks enabled") + set(CMAKE_CXX_CLANG_TIDY clang-tidy -extra-arg=-std=c++20) +endif() + include(FetchContent) include(GrailFunctions) diff --git a/proj/codestats.dat b/proj/codestats.dat index 68a232fd..82b834b7 100644 --- a/proj/codestats.dat +++ b/proj/codestats.dat @@ -228,6 +228,56 @@ 1627307838 xdl 16 2622 74483 1627307838 xp 10 996 28702 1627307838 total proj 265 23920 708059 + 1637736091 audio 2 355 9586 + 1637736091 csp 65 3419 93090 + 1637736091 data 13 1490 45643 + 1637736091 opengl 128 12775 409267 + 1637736091 util 44 4100 112694 + 1637736091 video 2 535 18206 + 1637736091 visualcs 5 303 8650 + 1637736091 xdl 19 3735 116146 + 1637736091 xp 10 939 23845 + 1637736091 total proj 288 27651 837127 + 1640003220 audio 2 355 9586 + 1640003220 csp 65 3414 93042 + 1640003220 data 13 1490 45643 + 1640003220 opengl 124 12651 406169 + 1640003220 util 44 4114 113111 + 1640003220 video 2 535 18206 + 1640003220 visualcs 5 303 8650 + 1640003220 xdl 19 3757 117202 + 1640003220 xp 8 821 20958 + 1640003220 total proj 282 27440 832567 + 1640060389 audio 2 355 9586 + 1640060389 csp 65 3414 93042 + 1640060389 data 13 1490 45643 + 1640060389 opengl 124 12651 406169 + 1640060389 util 44 4114 113111 + 1640060389 video 2 535 18206 + 1640060389 visualcs 5 303 8650 + 1640060389 xdl 19 3757 117202 + 1640060389 xp 8 821 20958 + 1640060389 total proj 282 27440 832567 + 1640132855 audio 2 355 9586 + 1640132855 csp 65 3414 93042 + 1640132855 data 13 1490 45643 + 1640132855 opengl 124 12653 406228 + 1640132855 util 45 4142 113563 + 1640132855 video 2 535 18206 + 1640132855 visualcs 5 303 8650 + 1640132855 xdl 19 3757 117250 + 1640132855 xp 8 821 20958 + 1640132855 total proj 283 27470 833126 + 1640199563 audio 2 355 9586 + 1640199563 csp 65 3414 93042 + 1640199563 data 13 1490 45643 + 1640199563 opengl 124 12653 406228 + 1640199563 util 45 4142 113563 + 1640199563 video 2 535 18206 + 1640199563 visualcs 5 303 8650 + 1640199563 xdl 19 3757 117250 + 1640199563 xp 8 821 20958 + 1640199563 total proj 283 27470 833126 1653633773 audio 2 355 9586 1653633773 CAD 42 2234 62229 1653633773 csp 65 3419 93901 diff --git a/src/CAD/RectangularPrism.cc b/src/CAD/RectangularPrism.cc index e673ec7b..bf97523f 100644 --- a/src/CAD/RectangularPrism.cc +++ b/src/CAD/RectangularPrism.cc @@ -1,123 +1,123 @@ -#include "CAD/RectangularPrism.hh" -// #include "opengl/GLMath.hh" -#include "glad/glad.h" -#include "opengl/Canvas.hh" -#include "opengl/GLWin.hh" -#include "opengl/Shader.hh" -#include "opengl/Style.hh" - -RectangularPrism::RectangularPrism(Canvas* c, const Style* s, float xsize, - float ysize, float zsize, float x, float y, - float z) - : Shape(c), - style(s), - xsize(xsize), - ysize(ysize), - zsize(zsize), - x(x), - y(y), - z(z) {} -RectangularPrism::~RectangularPrism() {} -inline void RectangularPrism::addVert(float x, float y, float z) { - vert.push_back(x); - vert.push_back(y); - vert.push_back(z); -} -// Best for GL_TRIANGLES -// inline void RectangularPrism::addRect(uint32_t i1, uint32_t i2, uint32_t i3, -// uint32_t i4) { -// ind.push_back(i1); ind.push_back(i2); ind.push_back(i3); -// ind.push_back(i1); ind.push_back(i3); ind.push_back(i4); -// } - -// Best for GL_LINES -inline void RectangularPrism::addRect(uint32_t i1, uint32_t i2, uint32_t i3, - uint32_t i4) { - ind.push_back(i1); - ind.push_back(i2); - ind.push_back(i2); - ind.push_back(i3); - ind.push_back(i3); - ind.push_back(i4); - ind.push_back(i4); - ind.push_back(i1); -} - -inline void RectangularPrism::addTri(uint32_t i1, uint32_t i2, uint32_t i3) { - ind.push_back(i1); - ind.push_back(i2); - ind.push_back(i3); -} - -void RectangularPrism::init() { - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - // Width = xsize - - addVert(x, y, z); // 0 - addVert(x + xsize, y, z); // 1 - addVert(x + xsize, y + ysize, z); // 2 - addVert(x, y + ysize, z); // 3 - addVert(x, y, z + zsize); // 4 - addVert(x + xsize, y, z + zsize); // 5 - addVert(x + xsize, y + ysize, z + zsize); // 6 - addVert(x, y + ysize, z + zsize); // 7 - - // front - addRect(0, 1, 2, 3); - - // back - addRect(4, 5, 6, 7); - - // sides - addRect(1, 5, 6, 2); - - addRect(4, 0, 3, 7); - - // Top - addRect(3, 2, 6, 7); - - // Bottom - addRect(0, 1, 5, 4); - - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vert.size(), &vert[0], - GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - - glGenBuffers(1, &lbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * ind.size(), &ind[0], - GL_STATIC_DRAW); - - // use if you want points to be drawn as well - // glGenBuffers(1,&pbo); - // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,pbo); - // glBufferData(GL_ELEMENT_ARRAY_BUFFER, - // sizeof(GLuint)*ind.size(),&ind[0],GL_STATIC_DRAW); -} - -void RectangularPrism::render() { - // const Shader* shader = Shader::useShader(style->getShaderIndex()); - // shader->setMat4("projection",*(parentCanvas->getProjection())); - // shader->setVec4("solidColor",style->getFgColor()); - - // glDrawArrays(GL_LINE_LOOP, 0, vert.size()); - glBindVertexArray(vao); - glEnableVertexAttribArray(0); - glLineWidth(style->getLineWidth()); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lbo); - glDrawElements(GL_LINES, ind.size(), GL_UNSIGNED_INT, 0); - // for points - // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pbo); - // glDrawElements(GL_POINTS, ind.size(), GL_UNSIGNED_INT, 0); - - glDisableVertexAttribArray(0); - glBindVertexArray(0); -} - -void RectangularPrism::cleanup() {} - -void RectangularPrism::update() {} +#include "CAD/RectangularPrism.hh" +// #include "opengl/GLMath.hh" +#include "glad/glad.h" +#include "opengl/Canvas.hh" +#include "opengl/GLWin.hh" +#include "opengl/Shader.hh" +#include "opengl/Style.hh" + +RectangularPrism::RectangularPrism(Canvas* c, const Style* s, float xsize, + float ysize, float zsize, float x, float y, + float z) + : Shape(c), + style(s), + xsize(xsize), + ysize(ysize), + zsize(zsize), + x(x), + y(y), + z(z) {} +RectangularPrism::~RectangularPrism() {} +inline void RectangularPrism::addVert(float x, float y, float z) { + vert.push_back(x); + vert.push_back(y); + vert.push_back(z); +} +// Best for GL_TRIANGLES +// inline void RectangularPrism::addRect(uint32_t i1, uint32_t i2, uint32_t i3, +// uint32_t i4) { +// ind.push_back(i1); ind.push_back(i2); ind.push_back(i3); +// ind.push_back(i1); ind.push_back(i3); ind.push_back(i4); +// } + +// Best for GL_LINES +inline void RectangularPrism::addRect(uint32_t i1, uint32_t i2, uint32_t i3, + uint32_t i4) { + ind.push_back(i1); + ind.push_back(i2); + ind.push_back(i2); + ind.push_back(i3); + ind.push_back(i3); + ind.push_back(i4); + ind.push_back(i4); + ind.push_back(i1); +} + +inline void RectangularPrism::addTri(uint32_t i1, uint32_t i2, uint32_t i3) { + ind.push_back(i1); + ind.push_back(i2); + ind.push_back(i3); +} + +void RectangularPrism::init() { + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + // Width = xsize + + addVert(x, y, z); // 0 + addVert(x + xsize, y, z); // 1 + addVert(x + xsize, y + ysize, z); // 2 + addVert(x, y + ysize, z); // 3 + addVert(x, y, z + zsize); // 4 + addVert(x + xsize, y, z + zsize); // 5 + addVert(x + xsize, y + ysize, z + zsize); // 6 + addVert(x, y + ysize, z + zsize); // 7 + + // front + addRect(0, 1, 2, 3); + + // back + addRect(4, 5, 6, 7); + + // sides + addRect(1, 5, 6, 2); + + addRect(4, 0, 3, 7); + + // Top + addRect(3, 2, 6, 7); + + // Bottom + addRect(0, 1, 5, 4); + + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vert.size(), &vert[0], + GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + + glGenBuffers(1, &lbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * ind.size(), &ind[0], + GL_STATIC_DRAW); + + // use if you want points to be drawn as well + // glGenBuffers(1,&pbo); + // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,pbo); + // glBufferData(GL_ELEMENT_ARRAY_BUFFER, + // sizeof(GLuint)*ind.size(),&ind[0],GL_STATIC_DRAW); +} + +void RectangularPrism::render() { + // const Shader* shader = Shader::useShader(style->getShaderIndex()); + // shader->setMat4("projection",*(parentCanvas->getProjection())); + // shader->setVec4("solidColor",style->getFgColor()); + + // glDrawArrays(GL_LINE_LOOP, 0, vert.size()); + glBindVertexArray(vao); + glEnableVertexAttribArray(0); + glLineWidth(style->getLineWidth()); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lbo); + glDrawElements(GL_LINES, ind.size(), GL_UNSIGNED_INT, 0); + // for points + // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pbo); + // glDrawElements(GL_POINTS, ind.size(), GL_UNSIGNED_INT, 0); + + glDisableVertexAttribArray(0); + glBindVertexArray(0); +} + +void RectangularPrism::cleanup() {} + +void RectangularPrism::update() {} diff --git a/src/CAD/Transformation.cc b/src/CAD/Transformation.cc index 5b8dbd6c..82e578d5 100644 --- a/src/CAD/Transformation.cc +++ b/src/CAD/Transformation.cc @@ -1,7 +1,8 @@ #include "CAD/Transformation.hh" + #include -// DO NOT REMOVE THIS COMMENT. IDIOTIC SORTING FORMAT WILL MOVE glad.h after glfw3 and screw up the build. -// What genius made the headers order-dependent? +// DO NOT REMOVE THIS COMMENT. IDIOTIC SORTING FORMAT WILL MOVE glad.h after +// glfw3 and screw up the build. What genius made the headers order-dependent? #include diff --git a/src/csp/IPV4Socket.cc b/src/csp/IPV4Socket.cc index f72601a6..722a15aa 100644 --- a/src/csp/IPV4Socket.cc +++ b/src/csp/IPV4Socket.cc @@ -1,15 +1,10 @@ #include "IPV4Socket.hh" -#include -#include #include /* All encapsulation for different operating systems networking code is done here */ -#include -#include - //#include "csp/HTTPRequest.hh" #include "csp/SocketIO.hh" #include "csp/csp.hh" @@ -41,7 +36,6 @@ void Socket::classInit() { testResult(WSAStartup(MAKEWORD(2, 2), &wsaData), __FILE__, __LINE__, Errcode::SOCKET); #endif - return; } // Takes care of allocations made by Winsock @@ -61,7 +55,7 @@ IPV4Socket::IPV4Socket(uint16_t port) : Socket(port) { sizeof(yes)), __FILE__, __LINE__, Errcode::SETSOCKOPT); memset(sockaddress, 0, sizeof(sockaddress)); - sockaddr_in *sockAddr = (sockaddr_in *)sockaddress; + auto *sockAddr = (sockaddr_in *)sockaddress; sockAddr->sin_family = AF_INET; sockAddr->sin_addr.s_addr = INADDR_ANY; sockAddr->sin_port = htons(port); @@ -80,7 +74,7 @@ IPV4Socket::IPV4Socket(const char *addr, uint16_t port) : Socket(addr, port) { throw Ex(__FILE__, __LINE__, Errcode::SERVER_INVALID); } - sockaddr_in *sockAddr = (sockaddr_in *)sockaddress; + auto *sockAddr = (sockaddr_in *)sockaddress; sockAddr->sin_family = AF_INET; // bcopy((char *)server->h_addr, (char *)&sockaddress.sin_addr.s_addr, // server->h_length); diff --git a/src/csp/SocketIO.cc b/src/csp/SocketIO.cc index d223c642..a49571fa 100644 --- a/src/csp/SocketIO.cc +++ b/src/csp/SocketIO.cc @@ -6,20 +6,26 @@ // TODO: Look into logging WSAGetLastError and strerror(errno) // Using the logging object in csp.hh? -int SocketIO::send(socket_t sckt, const char *buf, int size, int flags) { - uint32_t bytesSent; - if ((bytesSent = ::send(sckt, (char *)buf, size, 0)) == err_code) { - if (errno != EBADF) throw Ex1(Errcode::SOCKET_SEND); +namespace SocketIO { +ssize_t send(socket_t sckt, const char *buf, int size, int flags) { + ssize_t bytesSent = 0; + if ((bytesSent = ::send(sckt, buf, size, flags)) == err_code) { + if (errno != EBADF) { + throw Ex1(Errcode::SOCKET_SEND); + } perror("Warning on send(): "); } return bytesSent; } -int SocketIO::recv(socket_t sckt, const char *buf, int size, int flags) { - uint32_t bytesRecv; - if ((bytesRecv = ::recv(sckt, (char *)buf, size, 0)) == err_code) { - if (errno != EBADF) throw Ex1(Errcode::SOCKET_SEND); +ssize_t recv(socket_t sckt, char *buf, int size, int flags) { + ssize_t bytesRecv = 0; + if ((bytesRecv = ::recv(sckt, buf, size, flags)) == err_code) { + if (errno != EBADF) { + throw Ex1(Errcode::SOCKET_SEND); + } perror("Warning on recv()"); } return bytesRecv; -} \ No newline at end of file +} +} // namespace SocketIO \ No newline at end of file diff --git a/src/csp/SocketIO.hh b/src/csp/SocketIO.hh index 57b73d43..630ff740 100644 --- a/src/csp/SocketIO.hh +++ b/src/csp/SocketIO.hh @@ -25,14 +25,15 @@ using socket_t = decltype(socket(0, 0, 0)); -class SocketIO { - private: +namespace SocketIO { +namespace { #ifdef __linux__ - const static int err_code = -1; +constexpr int err_code = -1; #elif _WIN32 - const static int err_code = SOCKET_ERROR; +constexpr int err_code = SOCKET_ERROR; #endif - public: - static int send(socket_t sckt, const char *buf, int size, int flags); - static int recv(socket_t sckt, const char *buf, int size, int flags); -}; \ No newline at end of file +} // namespace + +ssize_t send(socket_t sckt, const char *buf, int size, int flags); +ssize_t recv(socket_t sckt, char *buf, int size, int flags); +}; // namespace SocketIO \ No newline at end of file diff --git a/src/csp/XDLRequest.cc b/src/csp/XDLRequest.cc index b4f6efbb..0bfcf5d0 100644 --- a/src/csp/XDLRequest.cc +++ b/src/csp/XDLRequest.cc @@ -6,7 +6,6 @@ #include #include -#include #include //#include "util/TypeAlias.hh" @@ -19,7 +18,7 @@ using namespace std; // base case -void buildData(Buffer& out, char meta[]) {} +// void buildData(Buffer& out, char meta[]) {} // template // void buildData(Buffer& out, Buffer& meta, T first, const Args&... args) { @@ -43,10 +42,10 @@ void buildData2(ArrayOfBytes* a, const T& arg) { } template -void buildData(DynArray a, const Args&... args) { +void buildData(DynArray data, const Args&... args) { ArrayOfBytes* bytes = new ArrayOfBytes(); (buildData2(bytes, args), ...); - a.add(bytes); + data.add(bytes); } #if 0 template diff --git a/src/opengl/.vscode/settings.json b/src/opengl/.vscode/settings.json deleted file mode 100644 index c6cea3a4..00000000 --- a/src/opengl/.vscode/settings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "files.associations": { - "array": "cpp", - "deque": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "string_view": "cpp", - "initializer_list": "cpp", - "utility": "cpp" - } -} \ No newline at end of file diff --git a/src/opengl/GLWin.hh b/src/opengl/GLWin.hh index d9bdc860..6afdf67d 100644 --- a/src/opengl/GLWin.hh +++ b/src/opengl/GLWin.hh @@ -160,7 +160,10 @@ Shape* pick(int x, int y, Shape*); // click on (x,y), get Shape behind void mainLoop(); void setUpdate() { needsUpdate = true; } void setRender() { needsRender = true; } - const Style* getDefaultStyle() const { return defaultStyle; } + const Style* getDefaultStyle() const { + auto a = new int[10]; + return defaultStyle; + } const Style* getGuiStyle() const { return guiStyle; } const Style* getGuiTextStyle() const { return guiTextStyle; } const Style* getMenuStyle() const { return menuStyle; } diff --git a/src/opengl/GLWinFonts.cc b/src/opengl/GLWinFonts.cc index 032beb8f..0d5efb0a 100644 --- a/src/opengl/GLWinFonts.cc +++ b/src/opengl/GLWinFonts.cc @@ -88,7 +88,7 @@ Font* Font::getDefault() { // TODO: can be made a private method of font static uint32_t hashGlyph(const uint8_t glyphBuffer[], uint32_t len) { uint32_t hash = len; - for (int i = 0; i < len; i++) + for (uint32_t i = 0; i < len; i++) hash = ((hash << 17) | (hash >> 13)) ^ ((hash << 5) | (hash >> 27)) ^ glyphBuffer[i]; return hash; @@ -367,7 +367,7 @@ Font::Font(istream& fastfont) { uint32_t numGlyphs = glyphs.size(); fastfont.read((char*)&numGlyphs, sizeof(uint32_t)); glyphs.reserve(numGlyphs); - for (int i = 0; i < numGlyphs; i++) { + for (uint32_t i = 0; i < numGlyphs; i++) { Glyph g; fastfont.read((char*)&g, sizeof(Glyph)); glyphs.push_back(g); @@ -515,25 +515,25 @@ void FontFace::initAll() { maxFontSize, bitmap, sizeX, sizeY, currX, currY, rowSize); } } - for (int i = 1400; i < sizeY; i++) { + for (uint32_t i = 1400; i < sizeY; i++) { int r = i * sizeX; - for (int j = 0; j < sizeX / 4; j += 2) { + for (uint32_t j = 0; j < sizeX / 4; j += 2) { bitmap[r + j] = 255; bitmap[r + j + 1] = 0; } - for (int j = sizeX / 4; j < sizeX / 2; j += 4) { + for (uint32_t j = sizeX / 4; j < sizeX / 2; j += 4) { bitmap[r + j] = 255; bitmap[r + j + 1] = 255; bitmap[r + j + 2] = 255; bitmap[r + j + 3] = 255; } - for (int j = sizeX / 2; j < sizeX * 3 / 4; j += 8) { + for (uint32_t j = sizeX / 2; j < sizeX * 3 / 4; j += 8) { bitmap[r + j] = 255; bitmap[r + j + 1] = 0; bitmap[r + j + 2] = 0; bitmap[r + j + 3] = 0; } - for (int j = sizeX * 3 / 4; j < sizeX; j++) { + for (uint32_t j = sizeX * 3 / 4; j < sizeX; j++) { bitmap[r + j] = 255; } } diff --git a/src/opengl/Member.cc b/src/opengl/Member.cc index 0dd6b3ad..b4af6ff3 100644 --- a/src/opengl/Member.cc +++ b/src/opengl/Member.cc @@ -1,4 +1,6 @@ +#include "Member.hh" + #include "opengl/GrailGUI.hh" using namespace std; @@ -25,4 +27,26 @@ void Member::render() {} void Member::update() {} Tab* Member::getParentTab() { return tab; } -MainCanvas* Member::getParentCanvas() { return c; } \ No newline at end of file +MainCanvas* Member::getParentCanvas() { return c; } +Member::Member(const Member& orig) = default; +Member::Member(Member&& orig) noexcept : tab(orig.tab), c(orig.c) { + orig.tab = nullptr; + orig.c = nullptr; +} +Member& Member::operator=(Member orig) { + swap(*this, orig); + return *this; +} +Member& Member::operator=(Member&& orig) noexcept { + if (this != &orig) { + tab = orig.tab; + c = orig.c; + } + return *this; +} + +void swap(Member& a, Member& b) { + using std::swap; + swap(a.tab, b.tab); + swap(a.c, b.c); +} diff --git a/src/opengl/Member.hh b/src/opengl/Member.hh index e5a14802..9301ccf5 100644 --- a/src/opengl/Member.hh +++ b/src/opengl/Member.hh @@ -13,7 +13,15 @@ class Member { MainCanvas* c; public: - Member(Tab* tab, double frameRate = -1, double dt = 0.0001); + explicit Member(Tab* tab, double frameRate = -1, double dt = 0.0001); + Member(const Member& orig); + Member(Member&& orig) noexcept; + + Member& operator=(Member orig); + Member& operator=(Member&& orig) noexcept; + + virtual ~Member() = default; + friend void swap(Member& a, Member& b); void setFrameRate(double frameRate); void setModelDt(double dt, double defaultDt); diff --git a/src/util/Callbacks.cc b/src/util/Callbacks.cc index 77f0e213..7103cfd2 100644 --- a/src/util/Callbacks.cc +++ b/src/util/Callbacks.cc @@ -5,15 +5,17 @@ using namespace std; CallbackHandler::CallbackHandler() { - for (int i = 0; i < 3; i++) numActions[i] = 1; + for (uint8_t i = 0; i < 3; i++) { + numActions[i] = 1; + } } HashMap CallbackHandler::actionNameMap(64, 4096); std::array inputMap(); -uint32_t CallbackHandler::internalRegisterAction(const char name[], Security s, - function action) { - uint32_t securityIndex = uint32_t(s); +uint32_t CallbackHandler::internalRegisterAction( + const char name[], const Security s, const function action) { + auto securityIndex = uint32_t(s); // SAFE = 0..999, RESTRICTED=1000.1999, ASK=2000..2999 uint32_t actNum = 1000 * securityIndex + numActions[securityIndex]++; // TODO: do something if 1000 action functions exceeded. For now, completely @@ -23,14 +25,16 @@ uint32_t CallbackHandler::internalRegisterAction(const char name[], Security s, << '\n'; } // cout << "Setting action " << actNum << " for action " << name << '\n'; - setAction(actNum, action); + setAction(actNum, move(action)); actionNameMap.add(name, actNum); return actNum; } -uint32_t CallbackHandler::lookupAction(const char actionName[]) { +auto CallbackHandler::lookupAction(const char actionName[]) -> uint32_t { uint32_t *act_code = actionNameMap.get(actionName); - if (act_code) return *act_code; + if (act_code) { + return *act_code; + } cerr << "Input binding failed: " << actionName << '\n'; return 0; } @@ -40,9 +44,9 @@ void CallbackHandler::bind(uint32_t input, const char actionName[]) { } uint32_t CallbackHandler::registerCallback(uint32_t input, const char name[], - Security s, + const Security s, function action) { - uint32_t securityIndex = uint32_t(s); + auto securityIndex = uint32_t(s); // SAFE = 0..999, RESTRICTED=1000.1999, ASK=2000..2999 uint32_t actNum = 1000 * securityIndex + numActions[securityIndex]++; // TODO: do something if 1000 action functions exceeded. For now, completely @@ -57,8 +61,7 @@ uint32_t CallbackHandler::registerCallback(uint32_t input, const char name[], setEvent(input, lookupAction(name)); return actNum; } - -void CallbackHandler::doit(uint32_t input) { +auto CallbackHandler::doit(uint32_t input) -> void { uint32_t act = CallbackHandler::inputMap[input]; if (act == 0) return; auto a = CallbackHandler::actionMap[act]; diff --git a/src/util/Callbacks.hh b/src/util/Callbacks.hh index c237cf8e..fbe14050 100644 --- a/src/util/Callbacks.hh +++ b/src/util/Callbacks.hh @@ -29,22 +29,22 @@ class CallbackHandler { */ inline static std::array, 4096> actionMap; static HashMap actionNameMap; - uint32_t lookupAction(const char actionName[]); + static uint32_t lookupAction(const char actionName[]); // static GLWin* w; - void setEvent(uint32_t e, uint32_t a) { inputMap[e] = a; } + static void setEvent(uint32_t e, uint32_t a) { inputMap.at(e) = a; } - void setEvent(uint32_t key, uint32_t mod, uint32_t a) { + static void setEvent(uint32_t key, uint32_t mod, uint32_t a) { setEvent((mod << 9) | key, a); } - void setAction(uint32_t a, std::function action) { - actionMap[a] = action; + static void setAction(uint32_t a, std::function action) { + actionMap[a] = move(action); } enum class Security { SAFE, // safe for a remote server to trigger this function RESTRICTED, // only the local user can execute this function - ASK // a remote user or server may request this but it will trigger a popup - // asking local user to approve + ASK // a remote user or server may request this, but it will trigger a + // popup asking local user to approve }; std::array numActions; // keep track of how many of each kind of // operations there are @@ -58,7 +58,7 @@ class CallbackHandler { } // registerAction("myFunc", Security::RESTRICTED, myFunc) // bind an input event to an action Name. looks up offsets into arrays - void bind(uint32_t input, const char actionName[]); + static void bind(uint32_t input, const char actionName[]); void bind(const char inputCmd[], const char actionName[]); #define quote(a) #a @@ -80,7 +80,7 @@ class CallbackHandler { registerCallback(inp, quote(func), Security::SAFE, func, ptr); } - void doit(uint32_t input); + static void doit(uint32_t input); void bind2DOrtho(); void bind3D(); diff --git a/src/util/DynArray.hh b/src/util/DynArray.hh index 718e076d..16b3d9b7 100644 --- a/src/util/DynArray.hh +++ b/src/util/DynArray.hh @@ -3,12 +3,20 @@ #include #include + +// The following disables clang-tidy from warning about pointer arithmetic +// Since this is a container implementation, it is unavoidable that pointer +// arithmetic is used +// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + template class DynArray { private: uint32_t capacity; uint32_t size_; T* data; + + // TODO: What is the point of this? We do nothing with either parameter. void* operator new(size_t sz, T* place) { return place; } // TODO: Objects containing pointers may be unable to move // DynArray of Strings seems to break after 2 Strings are added @@ -25,11 +33,11 @@ class DynArray { DynArray(uint32_t capacity) : capacity(capacity), size_(0), data((T*)malloc(capacity * sizeof(T))) {} ~DynArray() { - for (int i = 0; i < size_; i++) data[i].~T(); + for (uint32_t i = 0; i < size_; i++) data[i].~T(); free((void*)data); } void clear() { - for (int i = 0; i < size_; i++) data[i].~T(); + for (uint32_t i = 0; i < size_; i++) data[i].~T(); size_ = 0; } DynArray(const DynArray& orig) @@ -56,16 +64,43 @@ class DynArray { uint32_t size() const { return size_; } const T& last() const { return data[size_ - 1]; } friend std::ostream& operator<<(std::ostream& s, const DynArray& d) { - for (int i = 0; i < d.size_; i++) s << d.data[i] << ' '; + for (uint32_t i = 0; i < d.size_; i++) s << d.data[i] << ' '; return s; } - constexpr bool find(T& t) { - for (T& item : data) { + constexpr T removeAt(uint32_t index) { + T temp = data[index]; + + for (int i = index; i < size_ - 1; ++i) { + data[i] = data[i + 1]; + } + if (index == size_ - 1) data[index].~T(); + --size_; + return temp; + } + template + T& emplace_back(Args&&... args) { + checkGrow(); + return *construct_at(data + size_++, std::forward(args)...); + } + + void push_back(T&& elem) { emplace_back(std::move(elem)); } + + constexpr bool find(T& t) const { + for (const T& item : data) { if (item == t) { return true; } } return false; } + + // Roughly equivalent of std::construct_at. Used to reduce class footprint + template + constexpr T* construct_at(T* p, Args&&... args) { + return ::new (const_cast(static_cast(p))) + T(std::forward(args)...); + } }; + +// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) diff --git a/test/3d/SolarSystem.cc b/test/3d/SolarSystem.cc index 5e9244d3..7eb46789 100644 --- a/test/3d/SolarSystem.cc +++ b/test/3d/SolarSystem.cc @@ -1,13 +1,10 @@ #include -#include #include -#include "opengl/Errcode.hh" #include "opengl/GrailGUI.hh" #include "opengl/MultiShape3D.hh" #include "opengl/util/Transformation.hh" #include "util/DynArray.hh" -#include "util/Ex.hh" using namespace std; @@ -27,18 +24,18 @@ class Body { Transformation* trans; public: - Body(Canvas* c, const Style* s, Camera* cam, const std::string& name, + Body(Canvas* c, const Style* s, Camera* cam, std::string name, const char textureFile[], double r, double orbitalRadius, double orbitalPeriod, double rotationalPeriod, double axialTilt, double startTime, Body* orbits = nullptr); void update(double time); }; -Body::Body(Canvas* c, const Style* s, Camera* cam, const std::string& name, +Body::Body(Canvas* c, const Style* s, Camera* cam, std::string name, const char textureFile[], double r, double orbitalRadius, double orbitalPeriod, double rotationalPeriod, double axialTilt, double startTime, Body* orbits) - : name(name), + : name(move(name)), r(r), orbitalRadius(orbitalRadius), orbitalFreq(1.0 / orbitalPeriod), @@ -86,7 +83,7 @@ class SolarSystem : public Member { constexpr static double SIDEREAL_DAY = 0.9972; // number of 24-hour "days" it takes earth to rotate once public: - SolarSystem(Tab* tab) : Member(tab, 0, .0125), bodies(10) { + explicit SolarSystem(Tab* tab) : Member(tab, 0, .0125), bodies(10) { cam = c->setLookAtProjection(2, 3, 40, 0, 0, 0, 0, 0, 1); GLWin* w = tab->getParentWin(); const Style* s = w->getDefaultStyle(); @@ -131,7 +128,7 @@ class SolarSystem : public Member { void panRight(); void panLeft(); - void update() { + void update() override { double t = tab->time(); for (int i = 0; i < bodies.size(); i++) bodies[i]->update(t); } diff --git a/test/graph/convert_ESRI_to_ASCII.cc b/test/graph/convert_ESRI_to_ASCII.cc new file mode 100644 index 00000000..ebf4aa50 --- /dev/null +++ b/test/graph/convert_ESRI_to_ASCII.cc @@ -0,0 +1,23 @@ +#include + +#include + +#include "data/BlockMapLoader.hh" +#include "opengl/GLWin.hh" + +std::string getFile(const char defaultDir[], const char defaultFilename[], + int argc, char *argv[]) { + const char *grail = getenv("GRAIL"); + if (grail == nullptr || defaultDir == nullptr) + return std::string(argc > 1 ? argv[1] : defaultFilename); + std::string dir = std::string(grail) + std::string(defaultDir); + return dir + (argc > 1 ? argv[1] : defaultFilename); +} + +int main(int argc, char **argv) { + std::string shapefile = + getFile("/test/res/maps/", "USA_Counties.shp", argc, argv); + + BlockMapLoader bml(shapefile.c_str(), "ESRI"); + for (int i = 0; i < bml.getNumSegments(); i++) bml.dumpSegment(seg); +} diff --git a/test/maps/testDrawBlockMap.cc b/test/maps/testDrawBlockMap.cc index 74912e64..6307e022 100644 --- a/test/maps/testDrawBlockMap.cc +++ b/test/maps/testDrawBlockMap.cc @@ -41,6 +41,19 @@ class TestDrawBlockMap : public Member { ~TestDrawBlockMap() { delete mv; } TestDrawBlockMap(const TestDrawBlockMap& orig) = delete; TestDrawBlockMap& operator=(const TestDrawBlockMap& orig) = delete; + TestDrawBlockMap(TestDrawBlockMap&& orig) + : Member(orig), filename(orig.filename), mv(orig.mv) { + orig.mv = nullptr; // TODO: should filename be set to nullptr? + } + TestDrawBlockMap& operator=(const TestDrawBlockMap&& orig) { + if (this != &orig) { + delete mv; // TODO: Not deleting filename as its usually passed on the + // stack + mv = orig.mv; + filename = orig.filename; + } + return *this; + } constexpr static float zoomVal = 1.2; void mapZoomIn() { diff --git a/test/testDynArray.cc b/test/testDynArray.cc new file mode 100644 index 00000000..7f1e1b6b --- /dev/null +++ b/test/testDynArray.cc @@ -0,0 +1,59 @@ +#include "fmt/core.h" +#include "opengl/GrailGUI.hh" +#include "util/DynArray.hh" + +using namespace std; + +template +constexpr void printarr(string msg, uint32_t size, DynArray arr) { + fmt::print("{}", msg); + for (int i = 0; i < size; ++i) { + cout << arr[i] << ","; + } + fmt::print("\n"); +} + +template +constexpr void printarr(string msg, uint32_t size, DynArray arr) { + fmt::print("{}", msg); + for (int i = 0; i < size; ++i) { + fmt::print("{},", arr[i]); + } + fmt::print("\n"); +} + +int main() { + DynArray arr(10); + for (int i = 0; i < 10; i++) { + arr.add(i); + } + + printarr("new array of uint32_t: \n", 10, arr); + + int removedInt = arr.removeAt(5); + fmt::print("Removed value {} at index 5\n", removedInt); + + printarr("array of uint32_t after deletion: \n", 9, arr); + + GLWin w(1024, 800, 0xFFFFFFFF, 0x000000FF, "gw"); + DynArray tabs(4); + for (int i = 0; i < 4; i++) { + tabs.add(new Tab(&w)); + } + + printarr("new array of tabs: \n", 4, tabs); + + Tab* removedTab = tabs.removeAt(2); + cout << "Removed value " << removedTab << " at index 2\n"; + + printarr("array of tabs after deletion: \n", 3, tabs); + + DynArray strs(4); + strs.add("a"); + strs.add("B"); + strs.add("c"); + printarr("new array of strings: \n", 3, strs); + string removedString = strs.removeAt(1); + fmt::print("Removed value {} at index 1\n", removedString); + printarr("array of tabs after deletion: \n", 2, strs); +} \ No newline at end of file diff --git a/test/testDynArrayPerf.cc b/test/testDynArrayPerf.cc new file mode 100644 index 00000000..f73ac3f1 --- /dev/null +++ b/test/testDynArrayPerf.cc @@ -0,0 +1,105 @@ +#include +#include +#include + +#include "util/Benchmark.hh" +#include "util/DynArray.hh" + +using namespace std; + +class PtrObject { + private: + vector data; + string name; + + public: + PtrObject(int initialSize, string name) : data(initialSize), name(name) {} + + int& get(int index) { return data[index]; } + void add(int index, int value) { data.insert(data.begin() + index, value); } +}; + +class Vec3d { + private: + double x, y, z; + + public: + Vec3d(double x, double y, double z) : x(x), y(y), z(z) {} + void set(double x, double y, double z) { + this->x = x; + this->y = y; + this->z = z; + } +}; + +int main() { + auto add_raw_ptr_object = [] { + DynArray a(100); + for (int i = 0; i < 100; i++) { + a.add(new PtrObject(50, "fred")); + for (int j = 0; j < 50; j++) { + a[i]->add(j, i); + } + for (int j = 0; j < 50; j++) { + for (int k = 0; k < 1000; k++) { + a[i]->get(j)++; + } + } + } + for (int i = 0; i < 100; i++) { + delete a[i]; + } + }; + + auto emplace_raw_ptr_object = [] { + DynArray a(100); + for (int i = 0; i < 100; i++) { + a.emplace_back(new PtrObject(50, "fred")); + for (int j = 0; j < 50; j++) { + a[i]->add(j, i); + } + + for (int j = 0; j < 50; j++) { + for (int k = 0; k < 1000; k++) { + a[i]->get(j)++; + } + } + } + for (int i = 0; i < 100; i++) { + delete a[i]; + } + }; + + /* auto add_unique_ptr_object = [] { + DynArray> a(10); + for (int i = 0; i < 10; i++) { + a.add(make_unique(50, "fred")); + for (int j = 0; j < 50; j++) { + a[j]->add(j, i); + } + } + }; + */ + auto emplace_unique_ptr_object = [] { + DynArray> a(100); + for (int i = 0; i < 100; i++) { + a.emplace_back(make_unique(50, "fred")); + for (int j = 0; j < 50; j++) { + a[i]->add(j, i); + } + for (int j = 0; j < 50; j++) { + for (int k = 0; k < 1000; k++) { + a[i]->get(j)++; + } + } + } + }; + + CBenchmark::benchmark("PtrObject raw ptr add", 1e3, bind(add_raw_ptr_object)); + CBenchmark::benchmark("PtrObject raw ptr emplace", 1e3, + bind(emplace_raw_ptr_object)); + // CBenchmark::benchmark("PtrObject unique add", 1e6, + // bind(add_unique_ptr_object)); + CBenchmark::benchmark("PtrObject unique emplace", 1e3, + bind(emplace_unique_ptr_object)); +} \ No newline at end of file diff --git a/test/util/DateDemo.cc b/test/util/DateDemo.cc index 50807ec5..28822ad7 100644 --- a/test/util/DateDemo.cc +++ b/test/util/DateDemo.cc @@ -1,21 +1,21 @@ -#include - -#include "../src/util/JulianDate.hh" -#include "opengl/GrailGUI.hh" -using namespace std; -using namespace grail; - -class DateDemo : public GLWin { - public: - DateDemo() : GLWin(0x000000, 0xCCCCCC, "Test Date") {} - - void init() { - MainCanvas* c = currentTab()->getMainCanvas(); - StyledMultiShape2D* gui = c->getGui(); - MultiText* guiText = c->getGuiText(); - - JulianDate a(12, 1, 12); - } -}; - -int main(int argc, char* argv[]) { return GLWin::init(new DateDemo()); } +#include + +#include "../src/util/JulianDate.hh" +#include "opengl/GrailGUI.hh" +using namespace std; +using namespace grail; + +class DateDemo : public GLWin { + public: + DateDemo() : GLWin(0x000000, 0xCCCCCC, "Test Date") {} + + void init() { + MainCanvas* c = currentTab()->getMainCanvas(); + StyledMultiShape2D* gui = c->getGui(); + MultiText* guiText = c->getGuiText(); + + JulianDate a(12, 1, 12); + } +}; + +int main(int argc, char* argv[]) { return GLWin::init(new DateDemo()); } diff --git a/test/xdl/GenericXDLClient.cc b/test/xdl/GenericXDLClient.cc index 95317ea2..2e2ac9c2 100644 --- a/test/xdl/GenericXDLClient.cc +++ b/test/xdl/GenericXDLClient.cc @@ -1,59 +1,59 @@ -#include "csp/IPV4Socket.hh" -#include "csp/csp.hh" -//#include -#include "opengl/GLWin.hh" -#include "xdl/XDLCompiler.hh" -#include "xdl/std.hh" -using namespace std; - -Log srvlog; // log all important events for security and debugging - -/* - This generic client demonstrates the ability to send a request to an XDL - server, and get in response metadata and then data By reading the metadata, - the client can then print out ASCII views of the data. - - This is a standalone demo that does not require Grail graphics. - The next step after this is to display the data directly on a Grail window - - Known issues at this time: - 1. Not all data types are implemented yet, ie don't send JPEG or BLOB. - We focus mostly on numbers, strings, lists and struct for proof of concept. - - 2. Formatting is very ad hoc and not efficient. We need to come up with a way - to define good formatting that is fast. C++ recently added format, we should - take a look - -*/ -int main(int argc, char* argv[]) { - const char* ip = argc > 1 ? argv[1] : "127.0.0.1"; - int port = argc > 2 ? atoi(argv[2]) : 8060; - uint32_t req = argc > 3 ? atoi(argv[3]) : 0; - GLWin::classInit(); - try { - IPV4Socket s(ip, port); - s.send(req); - Buffer& in = s.getIn(); - in.displayRawRead(); - XDLCompiler compiler(""); - SymbolTable* st = new SymbolTable(&compiler); - const XDLType* metadata = XDLType::readMeta(&compiler, in); - Buffer out("client.txt", 32768); - - metadata->display(in, out); - /* - const Struct* root = (Struct*)st.getRoot(); - // dump all metadata, whether used in the data or not - for (int i = 0; i < root->getMemberCount(); i++) - cout << root->getMemberName(i) << '\t'; - cout << '\n'; - - root->display(in, out); - out.displayText(cout); -*/ - } catch (const Ex& e) { - cerr << e << '\n'; - } - GLWin::classCleanup(); - return 0; -} +#include "csp/IPV4Socket.hh" +#include "csp/csp.hh" +//#include +#include "opengl/GLWin.hh" +#include "xdl/XDLCompiler.hh" +#include "xdl/std.hh" +using namespace std; + +Log srvlog; // log all important events for security and debugging + +/* + This generic client demonstrates the ability to send a request to an XDL + server, and get in response metadata and then data By reading the metadata, + the client can then print out ASCII views of the data. + + This is a standalone demo that does not require Grail graphics. + The next step after this is to display the data directly on a Grail window + + Known issues at this time: + 1. Not all data types are implemented yet, ie don't send JPEG or BLOB. + We focus mostly on numbers, strings, lists and struct for proof of concept. + + 2. Formatting is very ad hoc and not efficient. We need to come up with a way + to define good formatting that is fast. C++ recently added format, we should + take a look + +*/ +int main(int argc, char* argv[]) { + const char* ip = argc > 1 ? argv[1] : "127.0.0.1"; + int port = argc > 2 ? atoi(argv[2]) : 8060; + uint32_t req = argc > 3 ? atoi(argv[3]) : 0; + GLWin::classInit(); + try { + IPV4Socket s(ip, port); + s.send(req); + Buffer& in = s.getIn(); + in.displayRawRead(); + XDLCompiler compiler(""); + SymbolTable* st = new SymbolTable(&compiler); + const XDLType* metadata = XDLType::readMeta(&compiler, in); + Buffer out("client.txt", 32768); + + metadata->display(in, out); + /* + const Struct* root = (Struct*)st.getRoot(); + // dump all metadata, whether used in the data or not + for (int i = 0; i < root->getMemberCount(); i++) + cout << root->getMemberName(i) << '\t'; + cout << '\n'; + + root->display(in, out); + out.displayText(cout); +*/ + } catch (const Ex& e) { + cerr << e << '\n'; + } + GLWin::classCleanup(); + return 0; +} diff --git a/test/xdl/GraphicalXDLClient.cc b/test/xdl/GraphicalXDLClient.cc index 6c662602..b94c3683 100644 --- a/test/xdl/GraphicalXDLClient.cc +++ b/test/xdl/GraphicalXDLClient.cc @@ -1,376 +1,376 @@ -#include "csp/IPV4Socket.hh" -#include "csp/XDLRequest.hh" -//#include "csp/csp.hh" -//#include -#include - -#include "opengl/GrailGUI.hh" -#include "util/Buffer.hh" -#include "util/DynArray.hh" -#include "util/HashMap.hh" -#include "xdl/XDLCompiler.hh" -#include "xdl/std.hh" -using namespace std; - -/** - * @brief Renders incoming data based on the metadata from Buffer to screen - * - * Renderer has state to track current location on the screen (visual cursor) - * and iterators within the object to track position within the data. - * For a large object such as a list, the renderer might only display the - * visible subset and stop. - * - */ -class Renderer { - public: - /** - * @brief A struct containing the top-left corner, width, and height of a - * bounding box - */ - struct BoundBox { - float x0, y0; - uint32_t width, height; - - BoundBox(float x, float y, uint32_t w, uint32_t h) - : x0(x), y0(y), width(w), height(h) {} - }; - typedef void (Renderer::*Method)(XDLIterator&); - - private: - XDLType* it; /**< the iterator to the XDLType to be drawn */ - XDLIterator* lastPage; /**< Stores the start of the current page*/ - XDLIterator* endPage; /**< Stores the end of the current page*/ - StyledMultiShape2D* m; /**< Stores and renders graphics onto the screen */ - MultiText* t; /**< Stores and renders text onto the screen */ - - /**< A dynamic array of top level structures, used for iterating between - * top-level structures */ - DynArray& requests; - - /**< A hashmap of the top-level structures, used for quick lookups */ - HashMap& byName; - std::unordered_map renderMap; - - Buffer& in; /**< A buffer containing the data to be rendered */ - - /**< Store the data for this object so we can go backwards and possibly save - * locally */ - DynArray dataBuffer; - BoundBox bounds; - - /**< Size for each row of data, related to font + spacing if it's text */ - float rowSize; - float x, y; /**< Current render position */ - - void registerRenderers() { - registerRenderer(DataType::STRUCT8, &Renderer::renderStructAcross); - registerRenderer(DataType::LIST16, &Renderer::renderListDown); - registerRenderer(DataType::U32, &Renderer::renderU32); - registerRenderer(DataType::U64, &Renderer::renderU64); - registerRenderer(DataType::F32, &Renderer::renderF32); - registerRenderer(DataType::F64, &Renderer::renderF64); - } - - public: - /** - * @brief Construct a new Renderer object - * - * @param it An XDLIterator to iterate through the data - * @param c A Canvas to draw on - * @param requests A dynamic array of top-level structures - * @param byName A hashmap of top-level structures - * @param in A buffer containing the data to be rendered - */ - Renderer(XDLType* it, MainCanvas* c, DynArray& requests, - HashMap& byName, Buffer& in) - : it(it), - m(c->getGui()), - t(c->getGuiText()), - dataBuffer(65536), - requests(requests), - byName(byName), - renderMap(65536), - in(in), - bounds(0, 0, c->getWidth(), c->getHeight()), - rowSize(20), - x(bounds.x0), - y(bounds.y0 + rowSize) { - // registerIterator(it); - registerRenderers(); - } - - /** - * @brief Construct a new Renderer object - * - * @param it An XDLIterator to iterate through the data - * @param c A Canvas to draw on - * @param requests A dynamic array of top-level structures - * @param byName A hashmap of top-level structures - * @param in A buffer containing the data to be rendered - * @param b A bounding box containing the top-left corner, width, and height - */ - Renderer(XDLType* it, MainCanvas* c, DynArray& requests, - HashMap& byName, Buffer& in, const BoundBox& b) - : it(it), - m(c->getGui()), - t(c->getGuiText()), - requests(requests), - byName(byName), - renderMap(65536), - in(in), - dataBuffer(65536), - bounds(b) { - // registerIterator(it); - registerRenderers(); - } - - /** - * @brief Construct a new Renderer object - * - * @param it An XDLIterator to iterate through the data - * @param c A Canvas to draw on - * @param requests A dynamic array of top-level structures - * @param byName A hashmap of top-level structures - * @param in A buffer containing the data to be rendered - * @param x0 The top-left x coordinate of the bounding box - * @param y0 The top-left y coordinate of the bounding box - * @param width The width of the bounding box - * @param height The height of the bounding box - */ - Renderer(XDLType* it, MainCanvas* c, DynArray& requests, - HashMap& byName, Buffer& in, const float& x0, - const float& y0, const uint32_t& width, const uint32_t& height) - : Renderer(it, c, requests, byName, in, BoundBox(x0, y0, width, height)) { - } - - Method* rendererFind(DataType t) { - auto i = renderMap.find(t); - if (i == renderMap.end()) return nullptr; - return &i->second; - } - - Method* rendererFind(XDLType* t) { - XDLIterator* comp = dynamic_cast(t); - if (comp) { - auto i = renderMap.find((comp->getUnderlying()->getDataType())); - if (i != renderMap.end()) return &i->second; - } - return nullptr; - } - - void registerRenderer(DataType t, Method m) { renderMap[t] = m; } - void renderListDown(XDLIterator& parentIterator); - void renderStructAcross(XDLIterator& parentIterator); - void renderSubStructAcross(Struct* s); - void renderStructNameValue(); - void renderObjectMetadataAcross(XDLIterator& parentIterator); - void renderU32(XDLIterator&); - void renderU64(XDLIterator&); - void renderF32(XDLIterator&); - void renderF64(XDLIterator&); - void nextPage(); - void prevPage(); - void update(); -}; - -void Renderer::update() { - t->clear(); - m->clear(); - Method* elementRenderer = rendererFind(it); - if (!elementRenderer) { - cerr << "bad renderer"; - return; - } - XDLIterator* i = dynamic_cast(it); - if (i == nullptr) { - cerr << "the page iterator is not an iterator, not drawing"; - return; - } - (this->**elementRenderer)(*i); -} - -void Renderer::nextPage() { - lastPage = ((XDLIterator*)it)->clone(); - it = endPage; -} - -void Renderer::prevPage() { it = lastPage; } - -void Renderer::renderListDown(XDLIterator& parentIterator) { - GenericList::Iterator* currentPage = - dynamic_cast(&parentIterator); - if (currentPage == nullptr) { - cerr << "Expected generic list!"; - return; - } - GenericList::Iterator i = - *currentPage; // make a copy to work with to draw this screenful - XDLType* elementType = i.getListType(); - Method* elementRenderer = rendererFind(elementType->getDataType()); - if (!elementRenderer) { - cerr << "bad renderer"; - return; - } - for (; !i && y < bounds.height; ++i, y += rowSize) { - x = bounds.x0; - XDLIterator* childIterator = (XDLIterator*)((GenericList*)i.getUnderlying()) - ->getListType() - ->begin(in); - // call the appropriate renderer for this object - (this->**elementRenderer)(*childIterator); - delete childIterator; - } - endPage = new GenericList::Iterator(i); -} - -void Renderer::renderObjectMetadataAcross(XDLIterator& parentIterator) { - Struct::Iterator* i = dynamic_cast(&parentIterator); - Struct* s = i->getStruct(); - if (i == nullptr) { - cerr << "Expected generic list!"; - return; - } - for (uint32_t i = 0; i < s->getMemberCount(); i++) { - /* - * Struct::Member is protected, need to use s->getMembers(i).type to get - * XDLType - */ - // const Struct::Member& m = s->getMembers(i); - // string memberName = s->getMemberName(); - // TODO: print across page - } - // endPage = current iterator position; -} - -void Renderer::renderStructAcross(XDLIterator& parentIterator) { - Struct::Iterator* currentPosition = - dynamic_cast(&parentIterator); - if (currentPosition == nullptr) { - cerr << "Expected structure!"; - return; - } - Struct* s = currentPosition->getStruct(); - Method elementRenderer; - - for (Struct::Iterator j = *currentPosition; !j; ++j) { - const XDLType* m = *j; - if (m->getDataType() == DataType::STRUCT8) { - renderSubStructAcross((Struct*)m); - } else { - Method* elementRenderer = rendererFind(m->getDataType()); - if (!elementRenderer) { - cerr << "bad renderer datatype=" << uint32_t(m->getDataType()) - << " typename=" << m->getTypeName() << '\n'; - } - (this->**elementRenderer)(j); - x += 150; - } - } -} - -void Renderer::renderSubStructAcross(Struct* s) { - Method elementRenderer; - - for (Struct::Iterator j(s); !j; ++j) { - const XDLType* m = *j; - if (m->getDataType() == DataType::STRUCT8) { - renderSubStructAcross((Struct*)m); - } else { - Method* elementRenderer = rendererFind(m->getDataType()); - if (!elementRenderer) { - cerr << "bad renderer datatype=" << uint32_t(m->getDataType()) - << " typename=" << m->getTypeName() << '\n'; - } - (this->**elementRenderer)(j); - } - x += 150; - } -} - -void Renderer::renderStructNameValue() { return; } -void Renderer::renderU32(XDLIterator&) { - Buffer& incpy = in; - t->add(x, y, in.readU32()); -} -void Renderer::renderU64(XDLIterator&) { t->add(x, y, in.readU64()); } -void Renderer::renderF32(XDLIterator&) { t->add(x, y, in.readF32()); } -void Renderer::renderF64(XDLIterator&) { t->add(x, y, in.readF64()); } - -/* - This generic client demonstrates the ability to send a request to an XDL - server, and draw the data returned on screen, paging through the data - if it's too big. - - Known issues at this time: - 1. Not all data types are implemented yet, ie don't send JPEG or BLOB. - We focus mostly on numbers, strings, lists and struct for proof of concept. - - 2. Formatting is very ad hoc and not efficient. We need to come up with a - way to define good formatting that is fast. C++ recently added format, we - should take a look -*/ - -class GraphicalXDLClient : public GLWin { - private: - IPV4Socket s; - uint32_t reqID; - const XDLType* latest; - DynArray requests; - HashMap byName; - XDLIterator* currentPos; - Renderer* r; - - set structTypes = {DataType::STRUCT8, DataType::STRUCT16, - DataType::STRUCT32}; - - void add(const XDLType* t) { - requests.add(t); - byName.add(t->getTypeName().c_str(), t->getTypeName().length(), t); - } - - public: - GraphicalXDLClient(const char* const ip, int port, uint32_t req) - : GLWin(0x000000, 0xCCCCCC, "Grail Graphical Generic Client"), - s(ip, port), - reqID(req), - requests(64), - byName(64) {} - void readData(uint32_t req) { - s.send(req); - Buffer& in = s.getIn(); - in.displayRawRead(); - XDLCompiler compiler(""); - // SymbolTable st(&compiler); - XDLType* latest = (XDLType*)XDLType::readMeta(&compiler, in); - add(latest); - float rowSize = 20; - - r = new Renderer(latest->begin(in), currentTab()->getMainCanvas(), requests, - byName, in); - // TODO: if we call readData multiple times, delete the old renderer before - // replacing it - } - void init() { - readData(reqID); - bindEvent(Inputs::PAGEDOWN, &GraphicalXDLClient::pageDown, this); - update(); - } - - void update() { r->update(); } - void pageDown() { - r->nextPage(); - setDirty(); - } - - void pageUp() { - r->prevPage(); - setDirty(); - } -}; -int main(int argc, char* argv[]) { - const char* const ip = argc > 1 ? argv[1] : "127.0.0.1"; - int port = argc > 2 ? atoi(argv[2]) : 8060; - uint32_t req = argc > 3 ? atoi(argv[3]) : 0; - GLWin::init(new GraphicalXDLClient(ip, port, req)); - return 0; -} +#include "csp/IPV4Socket.hh" +#include "csp/XDLRequest.hh" +//#include "csp/csp.hh" +//#include +#include + +#include "opengl/GrailGUI.hh" +#include "util/Buffer.hh" +#include "util/DynArray.hh" +#include "util/HashMap.hh" +#include "xdl/XDLCompiler.hh" +#include "xdl/std.hh" +using namespace std; + +/** + * @brief Renders incoming data based on the metadata from Buffer to screen + * + * Renderer has state to track current location on the screen (visual cursor) + * and iterators within the object to track position within the data. + * For a large object such as a list, the renderer might only display the + * visible subset and stop. + * + */ +class Renderer { + public: + /** + * @brief A struct containing the top-left corner, width, and height of a + * bounding box + */ + struct BoundBox { + float x0, y0; + uint32_t width, height; + + BoundBox(float x, float y, uint32_t w, uint32_t h) + : x0(x), y0(y), width(w), height(h) {} + }; + typedef void (Renderer::*Method)(XDLIterator&); + + private: + XDLType* it; /**< the iterator to the XDLType to be drawn */ + XDLIterator* lastPage; /**< Stores the start of the current page*/ + XDLIterator* endPage; /**< Stores the end of the current page*/ + StyledMultiShape2D* m; /**< Stores and renders graphics onto the screen */ + MultiText* t; /**< Stores and renders text onto the screen */ + + /**< A dynamic array of top level structures, used for iterating between + * top-level structures */ + DynArray& requests; + + /**< A hashmap of the top-level structures, used for quick lookups */ + HashMap& byName; + std::unordered_map renderMap; + + Buffer& in; /**< A buffer containing the data to be rendered */ + + /**< Store the data for this object so we can go backwards and possibly save + * locally */ + DynArray dataBuffer; + BoundBox bounds; + + /**< Size for each row of data, related to font + spacing if it's text */ + float rowSize; + float x, y; /**< Current render position */ + + void registerRenderers() { + registerRenderer(DataType::STRUCT8, &Renderer::renderStructAcross); + registerRenderer(DataType::LIST16, &Renderer::renderListDown); + registerRenderer(DataType::U32, &Renderer::renderU32); + registerRenderer(DataType::U64, &Renderer::renderU64); + registerRenderer(DataType::F32, &Renderer::renderF32); + registerRenderer(DataType::F64, &Renderer::renderF64); + } + + public: + /** + * @brief Construct a new Renderer object + * + * @param it An XDLIterator to iterate through the data + * @param c A Canvas to draw on + * @param requests A dynamic array of top-level structures + * @param byName A hashmap of top-level structures + * @param in A buffer containing the data to be rendered + */ + Renderer(XDLType* it, MainCanvas* c, DynArray& requests, + HashMap& byName, Buffer& in) + : it(it), + m(c->getGui()), + t(c->getGuiText()), + dataBuffer(65536), + requests(requests), + byName(byName), + renderMap(65536), + in(in), + bounds(0, 0, c->getWidth(), c->getHeight()), + rowSize(20), + x(bounds.x0), + y(bounds.y0 + rowSize) { + // registerIterator(it); + registerRenderers(); + } + + /** + * @brief Construct a new Renderer object + * + * @param it An XDLIterator to iterate through the data + * @param c A Canvas to draw on + * @param requests A dynamic array of top-level structures + * @param byName A hashmap of top-level structures + * @param in A buffer containing the data to be rendered + * @param b A bounding box containing the top-left corner, width, and height + */ + Renderer(XDLType* it, MainCanvas* c, DynArray& requests, + HashMap& byName, Buffer& in, const BoundBox& b) + : it(it), + m(c->getGui()), + t(c->getGuiText()), + requests(requests), + byName(byName), + renderMap(65536), + in(in), + dataBuffer(65536), + bounds(b) { + // registerIterator(it); + registerRenderers(); + } + + /** + * @brief Construct a new Renderer object + * + * @param it An XDLIterator to iterate through the data + * @param c A Canvas to draw on + * @param requests A dynamic array of top-level structures + * @param byName A hashmap of top-level structures + * @param in A buffer containing the data to be rendered + * @param x0 The top-left x coordinate of the bounding box + * @param y0 The top-left y coordinate of the bounding box + * @param width The width of the bounding box + * @param height The height of the bounding box + */ + Renderer(XDLType* it, MainCanvas* c, DynArray& requests, + HashMap& byName, Buffer& in, const float& x0, + const float& y0, const uint32_t& width, const uint32_t& height) + : Renderer(it, c, requests, byName, in, BoundBox(x0, y0, width, height)) { + } + + Method* rendererFind(DataType t) { + auto i = renderMap.find(t); + if (i == renderMap.end()) return nullptr; + return &i->second; + } + + Method* rendererFind(XDLType* t) { + XDLIterator* comp = dynamic_cast(t); + if (comp) { + auto i = renderMap.find((comp->getUnderlying()->getDataType())); + if (i != renderMap.end()) return &i->second; + } + return nullptr; + } + + void registerRenderer(DataType t, Method m) { renderMap[t] = m; } + void renderListDown(XDLIterator& parentIterator); + void renderStructAcross(XDLIterator& parentIterator); + void renderSubStructAcross(Struct* s); + void renderStructNameValue(); + void renderObjectMetadataAcross(XDLIterator& parentIterator); + void renderU32(XDLIterator&); + void renderU64(XDLIterator&); + void renderF32(XDLIterator&); + void renderF64(XDLIterator&); + void nextPage(); + void prevPage(); + void update(); +}; + +void Renderer::update() { + t->clear(); + m->clear(); + Method* elementRenderer = rendererFind(it); + if (!elementRenderer) { + cerr << "bad renderer"; + return; + } + XDLIterator* i = dynamic_cast(it); + if (i == nullptr) { + cerr << "the page iterator is not an iterator, not drawing"; + return; + } + (this->**elementRenderer)(*i); +} + +void Renderer::nextPage() { + lastPage = ((XDLIterator*)it)->clone(); + it = endPage; +} + +void Renderer::prevPage() { it = lastPage; } + +void Renderer::renderListDown(XDLIterator& parentIterator) { + GenericList::Iterator* currentPage = + dynamic_cast(&parentIterator); + if (currentPage == nullptr) { + cerr << "Expected generic list!"; + return; + } + GenericList::Iterator i = + *currentPage; // make a copy to work with to draw this screenful + XDLType* elementType = i.getListType(); + Method* elementRenderer = rendererFind(elementType->getDataType()); + if (!elementRenderer) { + cerr << "bad renderer"; + return; + } + for (; !i && y < bounds.height; ++i, y += rowSize) { + x = bounds.x0; + XDLIterator* childIterator = (XDLIterator*)((GenericList*)i.getUnderlying()) + ->getListType() + ->begin(in); + // call the appropriate renderer for this object + (this->**elementRenderer)(*childIterator); + delete childIterator; + } + endPage = new GenericList::Iterator(i); +} + +void Renderer::renderObjectMetadataAcross(XDLIterator& parentIterator) { + Struct::Iterator* i = dynamic_cast(&parentIterator); + Struct* s = i->getStruct(); + if (i == nullptr) { + cerr << "Expected generic list!"; + return; + } + for (uint32_t i = 0; i < s->getMemberCount(); i++) { + /* + * Struct::Member is protected, need to use s->getMembers(i).type to get + * XDLType + */ + // const Struct::Member& m = s->getMembers(i); + // string memberName = s->getMemberName(); + // TODO: print across page + } + // endPage = current iterator position; +} + +void Renderer::renderStructAcross(XDLIterator& parentIterator) { + Struct::Iterator* currentPosition = + dynamic_cast(&parentIterator); + if (currentPosition == nullptr) { + cerr << "Expected structure!"; + return; + } + Struct* s = currentPosition->getStruct(); + Method elementRenderer; + + for (Struct::Iterator j = *currentPosition; !j; ++j) { + const XDLType* m = *j; + if (m->getDataType() == DataType::STRUCT8) { + renderSubStructAcross((Struct*)m); + } else { + Method* elementRenderer = rendererFind(m->getDataType()); + if (!elementRenderer) { + cerr << "bad renderer datatype=" << uint32_t(m->getDataType()) + << " typename=" << m->getTypeName() << '\n'; + } + (this->**elementRenderer)(j); + x += 150; + } + } +} + +void Renderer::renderSubStructAcross(Struct* s) { + Method elementRenderer; + + for (Struct::Iterator j(s); !j; ++j) { + const XDLType* m = *j; + if (m->getDataType() == DataType::STRUCT8) { + renderSubStructAcross((Struct*)m); + } else { + Method* elementRenderer = rendererFind(m->getDataType()); + if (!elementRenderer) { + cerr << "bad renderer datatype=" << uint32_t(m->getDataType()) + << " typename=" << m->getTypeName() << '\n'; + } + (this->**elementRenderer)(j); + } + x += 150; + } +} + +void Renderer::renderStructNameValue() { return; } +void Renderer::renderU32(XDLIterator&) { + Buffer& incpy = in; + t->add(x, y, in.readU32()); +} +void Renderer::renderU64(XDLIterator&) { t->add(x, y, in.readU64()); } +void Renderer::renderF32(XDLIterator&) { t->add(x, y, in.readF32()); } +void Renderer::renderF64(XDLIterator&) { t->add(x, y, in.readF64()); } + +/* + This generic client demonstrates the ability to send a request to an XDL + server, and draw the data returned on screen, paging through the data + if it's too big. + + Known issues at this time: + 1. Not all data types are implemented yet, ie don't send JPEG or BLOB. + We focus mostly on numbers, strings, lists and struct for proof of concept. + + 2. Formatting is very ad hoc and not efficient. We need to come up with a + way to define good formatting that is fast. C++ recently added format, we + should take a look +*/ + +class GraphicalXDLClient : public GLWin { + private: + IPV4Socket s; + uint32_t reqID; + const XDLType* latest; + DynArray requests; + HashMap byName; + XDLIterator* currentPos; + Renderer* r; + + set structTypes = {DataType::STRUCT8, DataType::STRUCT16, + DataType::STRUCT32}; + + void add(const XDLType* t) { + requests.add(t); + byName.add(t->getTypeName().c_str(), t->getTypeName().length(), t); + } + + public: + GraphicalXDLClient(const char* const ip, int port, uint32_t req) + : GLWin(0x000000, 0xCCCCCC, "Grail Graphical Generic Client"), + s(ip, port), + reqID(req), + requests(64), + byName(64) {} + void readData(uint32_t req) { + s.send(req); + Buffer& in = s.getIn(); + in.displayRawRead(); + XDLCompiler compiler(""); + // SymbolTable st(&compiler); + XDLType* latest = (XDLType*)XDLType::readMeta(&compiler, in); + add(latest); + float rowSize = 20; + + r = new Renderer(latest->begin(in), currentTab()->getMainCanvas(), requests, + byName, in); + // TODO: if we call readData multiple times, delete the old renderer before + // replacing it + } + void init() { + readData(reqID); + bindEvent(Inputs::PAGEDOWN, &GraphicalXDLClient::pageDown, this); + update(); + } + + void update() { r->update(); } + void pageDown() { + r->nextPage(); + setDirty(); + } + + void pageUp() { + r->prevPage(); + setDirty(); + } +}; +int main(int argc, char* argv[]) { + const char* const ip = argc > 1 ? argv[1] : "127.0.0.1"; + int port = argc > 2 ? atoi(argv[2]) : 8060; + uint32_t req = argc > 3 ? atoi(argv[3]) : 0; + GLWin::init(new GraphicalXDLClient(ip, port, req)); + return 0; +} diff --git a/test/xdl/SimpleXDLServer.cc b/test/xdl/SimpleXDLServer.cc index 0abcffc1..1dd64d13 100644 --- a/test/xdl/SimpleXDLServer.cc +++ b/test/xdl/SimpleXDLServer.cc @@ -1,29 +1,29 @@ -#include "csp/csp.hh" -// our application errors must be defined before Ex.hh -#include "csp/IPV4Socket.hh" -#include "csp/XDLRequest.hh" -#include "opengl/GLWin.hh" -//#include "XDLServlet.hh" -#include -using namespace std; - -Log srvlog; // log all important events for security and debugging - -// Signal Handlers will not work see below: -// https://stackoverflow.com/questions/51169357/unable-to-catch-sigint-sent-by-clion -// However the solution there introduces other issues so code is left as is - -int main(int argc, char* argv[]) { - int port = argc > 1 ? atoi(argv[1]) : 8060; - GLWin::classInit(); - try { - IPV4Socket s(port); - XDLRequest req("conf/test1.xdl"); - s.attach(&req); - s.wait(); // main server wait loop - } catch (const Ex& e) { - cerr << e << '\n'; - } - GLWin::classCleanup(); - return 0; -} +#include "csp/csp.hh" +// our application errors must be defined before Ex.hh +#include "csp/IPV4Socket.hh" +#include "csp/XDLRequest.hh" +#include "opengl/GLWin.hh" +//#include "XDLServlet.hh" +#include +using namespace std; + +Log srvlog; // log all important events for security and debugging + +// Signal Handlers will not work see below: +// https://stackoverflow.com/questions/51169357/unable-to-catch-sigint-sent-by-clion +// However the solution there introduces other issues so code is left as is + +int main(int argc, char* argv[]) { + int port = argc > 1 ? atoi(argv[1]) : 8060; + GLWin::classInit(); + try { + IPV4Socket s(port); + XDLRequest req("conf/test1.xdl"); + s.attach(&req); + s.wait(); // main server wait loop + } catch (const Ex& e) { + cerr << e << '\n'; + } + GLWin::classCleanup(); + return 0; +} diff --git a/test/xdl/StockDemo.cc b/test/xdl/StockDemo.cc index 5abec01a..4312bd00 100644 --- a/test/xdl/StockDemo.cc +++ b/test/xdl/StockDemo.cc @@ -1,73 +1,73 @@ -#include -#include -#include -#include -#include -#include - -#include "opengl/ButtonWidget.hh" -#include "opengl/GrailGUI.hh" -#include "opengl/LineGraphWidget.hh" -using namespace std; -using namespace grail; - -class StockDemo : public GLWin { - public: - StockDemo() : GLWin(0x000000, 0xCCCCCC, "Stock Demo") {} - - vector openFile(const char name[]) { - fstream file; - vector v; - // Read file - file.open(name, ios::in); // Open file - if (file.is_open()) { // If file has correctly opened... - // Output debug message - cout << "File correctly opened" << endl; - - string temp; - float x, y; - // Dynamically store data into array - while (file.peek() != EOF) { // ... and while there are no errors, - getline(file, temp, '\n'); - v.push_back(atof(temp.c_str())); - } - } else - cout << "Unable to open file" << endl; - file.close(); - return v; - } - - void init() { - MainCanvas* c = currentTab()->getMainCanvas(); - StyledMultiShape2D* gui = c->getGui(); - MultiText* guiText = c->getGuiText(); - - vector GME = openFile("GME.csv"); - vector AAPL = openFile("AAPL.csv"); - vector NTDOY = openFile("NTDOY.csv"); - vector AMC = openFile("AMC.csv"); - - vector day; - for (int i = 0; i < AMC.size(); i++) day.push_back(i); - -#if 0 - LineGraphWidget chart(gui, guiText, 100, 320, 800, 400); - chart.axes("Days",4,"Price ($)",9,day.size(),75,day.size()-100,0,10,10,day.size()-100,day.size()); - chart.add(day, GME, blue, "GME"); - //chart.add(day, AAPL, red, "AAPL"); - chart.add(day, NTDOY, green, "NTDOY"); - chart.add(day, AMC, purple, "AMC"); - chart.title("Daily High of GME, and NTDOY Stocks Since 2010"); - chart.legend(100,800); - chart.init(); - //TODO:Add xAxis and yAxis label funcs - //TODO:Add legend to all graphwidgets - //TODO:Fix chart axis ticker in chart(), maybe move to init() - //TODO:Iterations of chart funcs - //TODO:Custom Locations of axes labels - //TODO:Comment code -#endif - } -}; - -int main(int argc, char* argv[]) { return GLWin::init(new StockDemo()); } +#include +#include +#include +#include +#include +#include + +#include "opengl/ButtonWidget.hh" +#include "opengl/GrailGUI.hh" +#include "opengl/LineGraphWidget.hh" +using namespace std; +using namespace grail; + +class StockDemo : public GLWin { + public: + StockDemo() : GLWin(0x000000, 0xCCCCCC, "Stock Demo") {} + + vector openFile(const char name[]) { + fstream file; + vector v; + // Read file + file.open(name, ios::in); // Open file + if (file.is_open()) { // If file has correctly opened... + // Output debug message + cout << "File correctly opened" << endl; + + string temp; + float x, y; + // Dynamically store data into array + while (file.peek() != EOF) { // ... and while there are no errors, + getline(file, temp, '\n'); + v.push_back(atof(temp.c_str())); + } + } else + cout << "Unable to open file" << endl; + file.close(); + return v; + } + + void init() { + MainCanvas* c = currentTab()->getMainCanvas(); + StyledMultiShape2D* gui = c->getGui(); + MultiText* guiText = c->getGuiText(); + + vector GME = openFile("GME.csv"); + vector AAPL = openFile("AAPL.csv"); + vector NTDOY = openFile("NTDOY.csv"); + vector AMC = openFile("AMC.csv"); + + vector day; + for (int i = 0; i < AMC.size(); i++) day.push_back(i); + +#if 0 + LineGraphWidget chart(gui, guiText, 100, 320, 800, 400); + chart.axes("Days",4,"Price ($)",9,day.size(),75,day.size()-100,0,10,10,day.size()-100,day.size()); + chart.add(day, GME, blue, "GME"); + //chart.add(day, AAPL, red, "AAPL"); + chart.add(day, NTDOY, green, "NTDOY"); + chart.add(day, AMC, purple, "AMC"); + chart.title("Daily High of GME, and NTDOY Stocks Since 2010"); + chart.legend(100,800); + chart.init(); + //TODO:Add xAxis and yAxis label funcs + //TODO:Add legend to all graphwidgets + //TODO:Fix chart axis ticker in chart(), maybe move to init() + //TODO:Iterations of chart funcs + //TODO:Custom Locations of axes labels + //TODO:Comment code +#endif + } +}; + +int main(int argc, char* argv[]) { return GLWin::init(new StockDemo()); } diff --git a/test/xp/plot.cc b/test/xp/plot.cc index b0aaa9d2..01aafd99 100644 --- a/test/xp/plot.cc +++ b/test/xp/plot.cc @@ -1,256 +1,256 @@ -#include "plot.hh" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "opengl/GLMath.hh" -#include "opengl/GLWin.hh" -#include "opengl/GLWinFonts.hh" -#include "opengl/MultiShape2D.hh" -#include "opengl/Style.hh" -#include "opengl/Tab.hh" -#include "opengl/Text.hh" -using namespace std; - -PointPlot::PointPlot(shared_ptr tab, float x, float y, float w, float h) { - const Font *font = FontFace::get("TIMES", 30, FontFace::BOLD); - srand(time(NULL)); - - float r = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); - float g = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); - float b = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); - - s = new Style(font, 1, 0, 0, 0, 0.3, 1); - s->setLineWidth(2); - s->setShaderIndex(GLWin::COMMON_SHADER); - textStyle = new Style(font, 0, 0, 0, 0, 0, 0); - textStyle->setShaderIndex(GLWin::TEXT_SHADER); - c = cw->addCanvas(s, x, y, w, h); - m = c->addLayer(new MultiShape2D(s)); - cWidth = c->getWidth(); - cHeight = c->getHeight(); -} - -void PointPlot::add_Point(float add_x, float add_y) { - X.push_back(add_x); - Y.push_back(add_y); -} -// void pointPlot::remove_point(float x, float y){ -// vector::iterator it_x = find(X.begin(), X.end(), x); -// vector::iterator it_y = find(Y.begin(), Y.end(), y); -// int index_x = distance(X.begin(), it_x) -// } -void PointPlot::add_Points(vector &x, vector &y) { - X.insert(X.end(), x.begin(), x.end()); - Y.insert(Y.end(), y.begin(), y.end()); -} -void PointPlot::linePlot(vector &X, vector &Y) { - if ((X.size() == Y.size()) && (X.size() > 1)) { - for (int i = 1; i < X.size(); i++) { - m->drawLine(X[i - 1] + cWidth / 2, cHeight / 2 - Y[i - 1], - X[i] + cWidth / 2, cHeight / 2 - Y[i]); - } - } else { - // Figure out what to place here. - // m->drawPoint(X[i]+40, cHeight-Y[i]-40); - } -} -void PointPlot::scatterPlot(vector &X, vector &Y) { - if (X.size() == Y.size()) { - for (int i = 0; i < X.size(); i++) { - // Figure out what drawPoint is - m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); - } - } else if (X.size() < Y.size()) { - for (int i = 0; i < X.size(); i++) { - // Figure out what drawPoint is - m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); - } - } else { - for (int i = 0; i < Y.size(); i++) { - // Figure out what drawPoint is - m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); - } - } -} -float PointPlot::maxWidth(vector &X) { - float maxValue = std::numeric_limits::min(); - for (int i = 0; i < X.size(); i++) { - if (X[i] > maxValue) { - maxValue = X[i]; - } - } - return maxValue; -} -float PointPlot::minWidth(vector &X) { - float minValue = std::numeric_limits::max(); - for (int i = 0; i < X.size(); i++) { - if (X[i] < minValue) { - minValue = X[i]; - } - } - return minValue; -} - -float PointPlot::maxHeight(vector &Y) { - float maxHeight = std::numeric_limits::min(); - for (int i = 0; i < Y.size(); i++) { - if (Y[i] > maxHeight) { - maxHeight = Y[i]; - } - } - return maxHeight; -} -float PointPlot::minHeight(vector &Y) { - float minHeight = std::numeric_limits::max(); - for (int i = 0; i < Y.size(); i++) { - if (Y[i] < minHeight) { - minHeight = Y[i]; - } - } - return minHeight; -} - -void PointPlot::linearRegression(vector &X, vector &Y) { - if (X.size() != Y.size()) { - throw "Vectors are not the same size."; - } - float n = X.size(); - float X_sum = accumulate(X.begin(), X.end(), 0); - float Y_sum = accumulate(Y.begin(), Y.end(), 0); - cout << "X total: " << X_sum << endl; - - float X_squared = 0; - for (int i = 0; i < X.size(); i++) { - X_squared += X[i] * X[i]; - } - - float Y_squared = 0; - for (int i = 0; i < Y.size(); i++) { - Y_squared += Y[i] * Y[i]; - } - float XY_sum = 0; - for (int i = 0; i < X.size(); i++) { - XY_sum += X[i] * Y[i]; - } - - float a = (n * XY_sum - X_sum * Y_sum) / (n * X_squared - X_sum * X_sum); - float b = (Y_sum - a * X_sum) / n; - - cout << "a: " << a << '\t' << "b: " << b << endl; - - float p1_x = 0; - float p1_y = b; - float p2_x = maxWidth(X); - float p2_y = p2_x * a + b; - m->drawLine(p1_x + cWidth / 2, cHeight / 2 - p1_y, p2_x + cWidth / 2, - cHeight / 2 - p2_y); -} - -void PointPlot::drawAxes() { - m->drawLine(0, cHeight / 2, cWidth, cHeight / 2); - m->drawLine(cWidth / 2, 0, cWidth / 2, cHeight); -} -void PointPlot::drawTicks() { - float x_pos = 0; - float y_pos = 0; - for (int i = 0; i <= 10; i++) { - m->drawLine(x_pos, cHeight / 2 - (.01 * cHeight), x_pos, - cHeight / 2 + (.01 * cHeight)); - x_pos += cWidth / 10; - } - for (int i = 0; i <= 10; i++) { - m->drawLine(cWidth / 2 - .01 * cWidth, y_pos, cWidth / 2 + .01 * cWidth, - y_pos); - y_pos += cHeight / 10; - } -} -void PointPlot::tickValues(vector &X, vector &Y) { - float increment_x = (maxWidth(X) + minWidth(X)) / 5; - float increment_y = (maxHeight(Y) + minHeight(Y)) / 5; - // c->addLayer(new Text(5,cHeight-5,textStyle, "0,0")); - int tickPos_x = -10; - int tickPos_y = cHeight - 25; - float tickNum_x = 0; - float tickNum_y = 0; - - for (int i = 0; i <= 5; i++) { - stringstream ss; - ss << fixed << setprecision(1) << tickNum_x; - string text_x = ss.str(); - // change r=the round function later to work for decimals. - c->addLayer(new Text(tickPos_x, tickPos_y, textStyle, text_x)); - tickNum_x += increment_x; - tickPos_x += cWidth / 5; - } - for (int i = 0; i <= 5; i++) { - stringstream ss; - ss << fixed << setprecision(1) << tickNum_y; - string text_y = ss.str(); - // change r=the round function later to work for decimals. - c->addLayer(new Text(0, tickPos_y, textStyle, text_y)); - tickNum_y += increment_y; - tickPos_y -= cHeight / 5; - } -} -void PointPlot::chartTitle(string title) { - const Font *font = FontFace::get("TIMES", 30, FontFace::BOLD); - Style *titleStyle = new Style(font, 0, 0, 0, 0, 0, 0); - titleStyle->setShaderIndex(CompiledWebWindow::TEXT_SHADER); - c->addLayer(new Text(cWidth / 2 - 150, 40, titleStyle, title)); -} - -void PointPlot::drawFunc(double x_min, double x_max, double y_min, double y_max, - FuncOneVar f, uint32_t pixXMin, uint32_t pixXMax, - uint32_t pixYMin, uint32_t pixYMax, - uint32_t numPoints) { - const double x_step = (x_max - x_min) / numPoints; - - vector X_points{}; - vector Y_points{}; - int y_pixel = 0; - double y_func = 0; - double ratioX = pixXMax / x_max; - double ratioY = pixYMax / y_max; - for (double i = x_min; i <= x_max; i += x_step) { - y_func = f(i); - X_points.push_back(i * ratioX); - y_pixel = y_func * ratioY + pixYMin; - Y_points.push_back(y_pixel); - } - linePlot(X_points, Y_points); -} -void PointPlot::drawTwoFunc(double val_min, double val_max, double step, - FuncOneVar f, FuncOneVar g, int scaleF, - int scaleG) { - vector Points_X{}; - vector Points_Y{}; - double x_func = 0; - double x_pixel = 0; - double FUNC2PIX_X = cWidth / val_max; - for (double i = val_min; i <= val_max; i += step) { - x_func = f(scaleF * i); - x_pixel = x_func * FUNC2PIX_X; - Points_X.push_back(x_pixel); - } - double y_func = 0; - double y_pixel = 0; - double FUNC2PIX_Y = cHeight / val_max; - for (double i = val_min; i <= val_max; i += step) { - y_func = g(scaleG * i); - y_pixel = y_func * FUNC2PIX_Y; - Points_Y.push_back(y_pixel); - } - linePlot(Points_X, Points_Y); -} -// following method will only work for months as julian calendar is not fully -// working pointPlot::monthPlot(vector date, vector price){ -// } +#include "plot.hh" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "opengl/GLMath.hh" +#include "opengl/GLWin.hh" +#include "opengl/GLWinFonts.hh" +#include "opengl/MultiShape2D.hh" +#include "opengl/Style.hh" +#include "opengl/Tab.hh" +#include "opengl/Text.hh" +using namespace std; + +PointPlot::PointPlot(shared_ptr tab, float x, float y, float w, float h) { + const Font *font = FontFace::get("TIMES", 30, FontFace::BOLD); + srand(time(NULL)); + + float r = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); + float g = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); + float b = (float)((rand() % (10 - 4 + 1) + 4) / 10.0); + + s = new Style(font, 1, 0, 0, 0, 0.3, 1); + s->setLineWidth(2); + s->setShaderIndex(GLWin::COMMON_SHADER); + textStyle = new Style(font, 0, 0, 0, 0, 0, 0); + textStyle->setShaderIndex(GLWin::TEXT_SHADER); + c = cw->addCanvas(s, x, y, w, h); + m = c->addLayer(new MultiShape2D(s)); + cWidth = c->getWidth(); + cHeight = c->getHeight(); +} + +void PointPlot::add_Point(float add_x, float add_y) { + X.push_back(add_x); + Y.push_back(add_y); +} +// void pointPlot::remove_point(float x, float y){ +// vector::iterator it_x = find(X.begin(), X.end(), x); +// vector::iterator it_y = find(Y.begin(), Y.end(), y); +// int index_x = distance(X.begin(), it_x) +// } +void PointPlot::add_Points(vector &x, vector &y) { + X.insert(X.end(), x.begin(), x.end()); + Y.insert(Y.end(), y.begin(), y.end()); +} +void PointPlot::linePlot(vector &X, vector &Y) { + if ((X.size() == Y.size()) && (X.size() > 1)) { + for (int i = 1; i < X.size(); i++) { + m->drawLine(X[i - 1] + cWidth / 2, cHeight / 2 - Y[i - 1], + X[i] + cWidth / 2, cHeight / 2 - Y[i]); + } + } else { + // Figure out what to place here. + // m->drawPoint(X[i]+40, cHeight-Y[i]-40); + } +} +void PointPlot::scatterPlot(vector &X, vector &Y) { + if (X.size() == Y.size()) { + for (int i = 0; i < X.size(); i++) { + // Figure out what drawPoint is + m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); + } + } else if (X.size() < Y.size()) { + for (int i = 0; i < X.size(); i++) { + // Figure out what drawPoint is + m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); + } + } else { + for (int i = 0; i < Y.size(); i++) { + // Figure out what drawPoint is + m->drawPoint(X[i] + cWidth / 2, cHeight / 2 - Y[i]); + } + } +} +float PointPlot::maxWidth(vector &X) { + float maxValue = std::numeric_limits::min(); + for (int i = 0; i < X.size(); i++) { + if (X[i] > maxValue) { + maxValue = X[i]; + } + } + return maxValue; +} +float PointPlot::minWidth(vector &X) { + float minValue = std::numeric_limits::max(); + for (int i = 0; i < X.size(); i++) { + if (X[i] < minValue) { + minValue = X[i]; + } + } + return minValue; +} + +float PointPlot::maxHeight(vector &Y) { + float maxHeight = std::numeric_limits::min(); + for (int i = 0; i < Y.size(); i++) { + if (Y[i] > maxHeight) { + maxHeight = Y[i]; + } + } + return maxHeight; +} +float PointPlot::minHeight(vector &Y) { + float minHeight = std::numeric_limits::max(); + for (int i = 0; i < Y.size(); i++) { + if (Y[i] < minHeight) { + minHeight = Y[i]; + } + } + return minHeight; +} + +void PointPlot::linearRegression(vector &X, vector &Y) { + if (X.size() != Y.size()) { + throw "Vectors are not the same size."; + } + float n = X.size(); + float X_sum = accumulate(X.begin(), X.end(), 0); + float Y_sum = accumulate(Y.begin(), Y.end(), 0); + cout << "X total: " << X_sum << endl; + + float X_squared = 0; + for (int i = 0; i < X.size(); i++) { + X_squared += X[i] * X[i]; + } + + float Y_squared = 0; + for (int i = 0; i < Y.size(); i++) { + Y_squared += Y[i] * Y[i]; + } + float XY_sum = 0; + for (int i = 0; i < X.size(); i++) { + XY_sum += X[i] * Y[i]; + } + + float a = (n * XY_sum - X_sum * Y_sum) / (n * X_squared - X_sum * X_sum); + float b = (Y_sum - a * X_sum) / n; + + cout << "a: " << a << '\t' << "b: " << b << endl; + + float p1_x = 0; + float p1_y = b; + float p2_x = maxWidth(X); + float p2_y = p2_x * a + b; + m->drawLine(p1_x + cWidth / 2, cHeight / 2 - p1_y, p2_x + cWidth / 2, + cHeight / 2 - p2_y); +} + +void PointPlot::drawAxes() { + m->drawLine(0, cHeight / 2, cWidth, cHeight / 2); + m->drawLine(cWidth / 2, 0, cWidth / 2, cHeight); +} +void PointPlot::drawTicks() { + float x_pos = 0; + float y_pos = 0; + for (int i = 0; i <= 10; i++) { + m->drawLine(x_pos, cHeight / 2 - (.01 * cHeight), x_pos, + cHeight / 2 + (.01 * cHeight)); + x_pos += cWidth / 10; + } + for (int i = 0; i <= 10; i++) { + m->drawLine(cWidth / 2 - .01 * cWidth, y_pos, cWidth / 2 + .01 * cWidth, + y_pos); + y_pos += cHeight / 10; + } +} +void PointPlot::tickValues(vector &X, vector &Y) { + float increment_x = (maxWidth(X) + minWidth(X)) / 5; + float increment_y = (maxHeight(Y) + minHeight(Y)) / 5; + // c->addLayer(new Text(5,cHeight-5,textStyle, "0,0")); + int tickPos_x = -10; + int tickPos_y = cHeight - 25; + float tickNum_x = 0; + float tickNum_y = 0; + + for (int i = 0; i <= 5; i++) { + stringstream ss; + ss << fixed << setprecision(1) << tickNum_x; + string text_x = ss.str(); + // change r=the round function later to work for decimals. + c->addLayer(new Text(tickPos_x, tickPos_y, textStyle, text_x)); + tickNum_x += increment_x; + tickPos_x += cWidth / 5; + } + for (int i = 0; i <= 5; i++) { + stringstream ss; + ss << fixed << setprecision(1) << tickNum_y; + string text_y = ss.str(); + // change r=the round function later to work for decimals. + c->addLayer(new Text(0, tickPos_y, textStyle, text_y)); + tickNum_y += increment_y; + tickPos_y -= cHeight / 5; + } +} +void PointPlot::chartTitle(string title) { + const Font *font = FontFace::get("TIMES", 30, FontFace::BOLD); + Style *titleStyle = new Style(font, 0, 0, 0, 0, 0, 0); + titleStyle->setShaderIndex(CompiledWebWindow::TEXT_SHADER); + c->addLayer(new Text(cWidth / 2 - 150, 40, titleStyle, title)); +} + +void PointPlot::drawFunc(double x_min, double x_max, double y_min, double y_max, + FuncOneVar f, uint32_t pixXMin, uint32_t pixXMax, + uint32_t pixYMin, uint32_t pixYMax, + uint32_t numPoints) { + const double x_step = (x_max - x_min) / numPoints; + + vector X_points{}; + vector Y_points{}; + int y_pixel = 0; + double y_func = 0; + double ratioX = pixXMax / x_max; + double ratioY = pixYMax / y_max; + for (double i = x_min; i <= x_max; i += x_step) { + y_func = f(i); + X_points.push_back(i * ratioX); + y_pixel = y_func * ratioY + pixYMin; + Y_points.push_back(y_pixel); + } + linePlot(X_points, Y_points); +} +void PointPlot::drawTwoFunc(double val_min, double val_max, double step, + FuncOneVar f, FuncOneVar g, int scaleF, + int scaleG) { + vector Points_X{}; + vector Points_Y{}; + double x_func = 0; + double x_pixel = 0; + double FUNC2PIX_X = cWidth / val_max; + for (double i = val_min; i <= val_max; i += step) { + x_func = f(scaleF * i); + x_pixel = x_func * FUNC2PIX_X; + Points_X.push_back(x_pixel); + } + double y_func = 0; + double y_pixel = 0; + double FUNC2PIX_Y = cHeight / val_max; + for (double i = val_min; i <= val_max; i += step) { + y_func = g(scaleG * i); + y_pixel = y_func * FUNC2PIX_Y; + Points_Y.push_back(y_pixel); + } + linePlot(Points_X, Points_Y); +} +// following method will only work for months as julian calendar is not fully +// working pointPlot::monthPlot(vector date, vector price){ +// } diff --git a/test/xp/testHashMap.cc b/test/xp/testHashMap.cc index 7b8d09d3..7d09f24c 100644 --- a/test/xp/testHashMap.cc +++ b/test/xp/testHashMap.cc @@ -1,42 +1,44 @@ #include + #include "util/HashMap.hh" // make a copy of util/Hashmap.hh into src/xp void convertAsciiDictionaryToBlockLoader() { - HashMap dict; + HashMap dict; // while (!f.getline()) { - dict.add(word, count++); - } - - uint32_t val; - if (dict.get("apple", &val)) { - cout << val - - } else { - cout << "Apple not found"; - } - // first create a hashmap and load dictionary in with a unique integer for each word - //for (each word) dict.add(word, count++); - // now, modify hash map to save the dictionary into a single block loader - - // class HashMapBase : BlockLoader { ??? - // write out the block loader format - // 4 bytes magic number, 2 bytes type , .... - // save here as "fastloaddict.bld" - - // allocate assuming each word = 2 bytes. - // length of file = header + number of bytes in words - // conservative estimate of words = (length of file - header) / 2 - // use: malloc() to allocate the memory - // read in the file into the memory you allocated - // calculate the 3 pointers: symbols, table, nodes - // use realloc() to give back the excess (because you had to over-estimate) - // add and fill in the table + dict.add(word, count++); +} + +uint32_t val; +if (dict.get("apple", &val)) { + cout << val + +} else { + cout << "Apple not found"; +} +// first create a hashmap and load dictionary in with a unique integer for each +// word +// for (each word) dict.add(word, count++); +// now, modify hash map to save the dictionary into a single block loader + +// class HashMapBase : BlockLoader { ??? +// write out the block loader format +// 4 bytes magic number, 2 bytes type , .... +// save here as "fastloaddict.bld" + +// allocate assuming each word = 2 bytes. +// length of file = header + number of bytes in words +// conservative estimate of words = (length of file - header) / 2 +// use: malloc() to allocate the memory +// read in the file into the memory you allocated +// calculate the 3 pointers: symbols, table, nodes +// use realloc() to give back the excess (because you had to over-estimate) +// add and fill in the table } int main() { convertAsciiDictionaryToBlockLoader(); -// make a fast dictionary loader that loads from the format you saved + // make a fast dictionary loader that loads from the format you saved HashMap dict("fastloaddict.bld"); } \ No newline at end of file diff --git a/test/xp/testfmt.cc b/test/xp/testfmt.cc index 0ca0088b..5d0f8748 100644 --- a/test/xp/testfmt.cc +++ b/test/xp/testfmt.cc @@ -194,7 +194,7 @@ constexpr uint32_t _formatgrl(char destBuf[33], int printVal) { constexpr inline char DECIMAL_POINT = '.'; void _insertdec(char destBuf[33], uint32_t& i, uint32_t decimalLoc, - uint32_t digit4) { + uint32_t digit4) { // load the right 4 digits from the table 0000 to 9999 uint32_t digits = ((uint32_t*)dig4)[digit4]; if (decimalLoc >= 4) { @@ -246,7 +246,7 @@ void _insertdec(char destBuf[33], uint32_t& i, uint32_t decimalLoc, // R to L, 4 at a time uint32_t _formatgrlfloat(char destBuf[33], uint64_t printVal, - uint32_t precision, uint32_t decimalLoc) { + uint32_t precision, uint32_t decimalLoc) { uint32_t len; uint32_t i; for (i = 28; precision >= 4; i -= 4, precision -= 4, decimalLoc -= 4) { @@ -291,7 +291,7 @@ constexpr uint32_t _formatgrl5(char destBuf[33], T data) { } template -constexpr void testboth(T data) { +void testboth(T data) { print(fg(color::steel_blue) | emphasis::bold, "Currently processing: {}\n", data); char dest[33]; @@ -306,7 +306,7 @@ constexpr void testboth(T data) { } template -constexpr void testAll(T data) { +void testAll(T data) { print(fg(color::steel_blue) | emphasis::bold, "Currently processing: {}\n", data); char dest[33];