From 0b800b206f6480b03f7e0c701535cd78bedf7ca5 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Wed, 3 Jan 2024 13:26:56 +0100 Subject: [PATCH 01/11] make cl input request equal to inklecate --- inkcpp_cl/inkcpp_cl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inkcpp_cl/inkcpp_cl.cpp b/inkcpp_cl/inkcpp_cl.cpp index a00ababe..521a46f6 100644 --- a/inkcpp_cl/inkcpp_cl.cpp +++ b/inkcpp_cl/inkcpp_cl.cpp @@ -183,6 +183,7 @@ int main(int argc, const char** argv) } int c = 0; + std::cout << "?> "; std::cin >> c; if (c == -1) { snapshot* snap = thread->create_snapshot(); @@ -193,7 +194,6 @@ int main(int argc, const char** argv) break; } thread->choose(c - 1); - std::cout << "?> "; continue; } From 79f6367e4b6f69def4c0f25179621a47b89c4bd9 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 10:57:14 +0100 Subject: [PATCH 02/11] Setup Doxygen * start documentation of ink::runtime::value --- CMakeLists.txt | 2 +- Doxyfile | 858 +++++++++++++++++++---------- inkcpp/globals_impl.cpp | 4 +- inkcpp/include/globals.h | 12 +- inkcpp/include/traits.h | 1 + inkcpp/include/types.h | 195 +++++-- inkcpp/value.cpp | 12 +- inkcpp_compiler/include/compiler.h | 13 +- inkcpp_py/src/module.cpp | 21 +- inkcpp_test/Observer.cpp | 10 +- shared/public/system.h | 2 +- 11 files changed, 729 insertions(+), 401 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47073309..704593b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ include(CPack) find_package(Doxygen) if (DOXYGEN_FOUND) set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) - doxygen_add_docs(doc ${PROJECT_SOURCE_DIR} COMMENT "Generate docs") + doxygen_add_docs(doc WORKING_DIR ${PROJECT_SOURCE_DIR} CONFIG_FILE "${PROJECT_SOURCE_DIR}/Doxyfile" COMMENT "Generate docs") else(DOXYGEN_FOUND) message("Doxygen needed to generate documntation!") endif(DOXYGEN_FOUND) diff --git a/Doxyfile b/Doxyfile index d151bb6e..e0d7a996 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.16 +# Doxyfile 1.9.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,6 +12,16 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options @@ -32,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "inkcpp" +PROJECT_NAME = inkcpp # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -60,16 +70,28 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = Documentation -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,26 +103,18 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. @@ -227,6 +241,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -250,25 +272,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -309,19 +325,22 @@ OPTIMIZE_OUTPUT_SLICE = NO # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is -# Fortran), use: inc=Fortran f=C. +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = @@ -344,6 +363,17 @@ MARKDOWN_SUPPORT = YES TOC_INCLUDE_HEADINGS = 5 +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -392,7 +422,7 @@ IDL_PROPERTY_SUPPORT = YES # all members of a group must be documented explicitly. # The default value is: NO. -DISTRIBUTE_GROUP_DOC = NO +DISTRIBUTE_GROUP_DOC = YES # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option @@ -455,6 +485,27 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -518,6 +569,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -529,14 +587,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -555,12 +614,20 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# (including Cygwin) ands Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = NO @@ -578,6 +645,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -735,7 +808,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -781,24 +855,50 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO @@ -809,13 +909,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -829,17 +943,30 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = include +INPUT = inkcpp/include \ + shared/public \ + inkcpp_compiler/include # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -848,11 +975,15 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, +# *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, *.php, +# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be +# provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -935,12 +1066,9 @@ EXCLUDE_PATTERNS = # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* +# ANamespace::AClass, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = ink::list_flag # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -983,6 +1111,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -1024,6 +1157,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -1110,35 +1252,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files -# were built. This is equivalent to specifying the "-p" option to a clang tool, -# such as clang-check. These options will then be passed to the parser. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1150,17 +1263,11 @@ CLANG_DATABASE_PATH = ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1239,7 +1346,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1254,9 +1366,22 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see +# this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. @@ -1266,7 +1391,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1284,20 +1409,11 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that -# are dynamically created via Javascript. If disabled, the navigation index will +# are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have Javascript, +# page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1312,6 +1428,13 @@ HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1327,10 +1450,11 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/xcode/), introduced with OSX -# 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy # genXcode/_index.html for more information. @@ -1347,6 +1471,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1372,8 +1503,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1403,7 +1538,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1430,6 +1565,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1448,7 +1593,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1456,8 +1602,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1465,16 +1611,16 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = @@ -1486,9 +1632,9 @@ QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1531,16 +1677,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1565,6 +1723,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1574,19 +1750,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1596,11 +1767,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1613,22 +1802,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1656,7 +1852,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1675,7 +1871,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1688,8 +1885,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: https://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1798,29 +1996,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1853,18 +2053,26 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1877,16 +2085,6 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # https://en.wikipedia.org/wiki/BibTeX and \cite for more info. @@ -1895,14 +2093,6 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # path from which the emoji images will be read. If a relative path is entered, # it will be relative to the LATEX_OUTPUT directory. If left blank the @@ -1967,16 +2157,6 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -2073,27 +2253,44 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to Sqlite3 output +#--------------------------------------------------------------------------- + +# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3 +# database with symbols found by doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each doxygen run. If set to NO, doxygen +# will warn if an a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- @@ -2168,7 +2365,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2235,15 +2433,15 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2257,25 +2455,9 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2284,7 +2466,7 @@ HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2301,49 +2483,73 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" + +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2366,10 +2572,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2381,7 +2609,9 @@ TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to # YES then doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2390,7 +2620,10 @@ INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2430,16 +2663,26 @@ GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2476,11 +2719,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2489,10 +2733,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2530,18 +2774,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2554,14 +2786,34 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/inkcpp/globals_impl.cpp b/inkcpp/globals_impl.cpp index 163f4177..fc3e23be 100644 --- a/inkcpp/globals_impl.cpp +++ b/inkcpp/globals_impl.cpp @@ -154,13 +154,13 @@ bool globals_impl::set_var(hash_t name, const ink::runtime::value& val) } size_t size = 0; char* ptr; - for (const char* i = val.v_string; *i; ++i) { + for (const char* i = val.get(); *i; ++i) { ++size; } char* new_string = strings().create(size + 1); strings().mark_used(new_string); ptr = new_string; - for (const char* i = val.v_string; *i; ++i) { + for (const char* i = val.get(); *i; ++i) { *ptr++ = *i; } *ptr = 0; diff --git a/inkcpp/include/globals.h b/inkcpp/include/globals.h index ac18c284..ee12f782 100644 --- a/inkcpp/include/globals.h +++ b/inkcpp/include/globals.h @@ -81,7 +81,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if ( var && var->type == value::Type::Bool) { - return {var->v_bool}; + return {var->get()}; } return nullopt; } @@ -94,7 +94,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if (var && var->type == value::Type::Uint32) { - return {var->v_uint32}; + return {var->get()}; } return nullopt; } @@ -107,7 +107,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if (var && var->type == value::Type::Int32) { - return {var->v_int32}; + return {var->get()}; } return nullopt; } @@ -121,7 +121,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if ( var && var->type == value::Type::Float) { - return {var->v_float}; + return {var->get()}; } return nullopt; } @@ -134,7 +134,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if ( var && var->type == value::Type::String ) { - return {var->v_string}; + return {var->get()}; } return nullopt; } @@ -147,7 +147,7 @@ namespace ink::runtime inline optional globals_interface::get(const char* name) const { auto var = get_var(hash_string(name)); if (var && var->type == value::Type::List) { - return {var->v_list}; + return {var->get()}; } return nullopt; } diff --git a/inkcpp/include/traits.h b/inkcpp/include/traits.h index aa9e0967..809d134f 100644 --- a/inkcpp/include/traits.h +++ b/inkcpp/include/traits.h @@ -7,6 +7,7 @@ #include #endif +/** Util templates and implimentation of STL if STL is not available */ namespace ink::runtime::internal { template diff --git a/inkcpp/include/types.h b/inkcpp/include/types.h index 208d2d08..623af031 100644 --- a/inkcpp/include/types.h +++ b/inkcpp/include/types.h @@ -6,72 +6,149 @@ namespace ink::runtime { - class globals_interface; - class runner_interface; - class snapshot; - - using globals = story_ptr; - using runner = story_ptr; - using list = list_interface*; - - struct value { - union { - bool v_bool; - uint32_t v_uint32; - int32_t v_int32; - const char* v_string; - float v_float; - list v_list; - }; - enum class Type { - Bool, Uint32, Int32, String, Float, List - } type; - value() : v_int32{0}, type{Type::Int32} {} - value(bool v) : v_bool{v}, type{Type::Bool} {} - value(uint32_t v) : v_uint32{v}, type{Type::Uint32} {} - value(int32_t v) : v_int32{v}, type{Type::Int32} {} - value(const char* v) : v_string{v}, type{Type::String} {} - value(float v) : v_float{v}, type{Type::Float} {} - value(list_interface* list) : v_list{list}, type{Type::List} {} - value(const value& v) : type{v.type} { - switch(type) { - case Type::Bool: v_bool = v.v_bool; break; - case Type::Uint32: v_uint32 = v.v_uint32; break; - case Type::Int32: v_int32 = v.v_int32; break; - case Type::String: v_string = v.v_string; break; - case Type::Float: v_float = v.v_float; break; - case Type::List: v_list = v.v_list; break; - } - } +class globals_interface; +class runner_interface; +class snapshot; - template - const auto& get() const { - static_assert(Ty != Ty, "No value getter for the selected type"); - } +using globals = story_ptr; +using runner = story_ptr; +using list = list_interface*; + +/** A Ink variable + * + * Used for accassing, writing and observing global variables + * @ref globals_interface::get() const, + * @ref globals_interface::set() + * @ref globals_interface::observe() + * + * and for the execution of extern functions + * @ref ink::runtime::runner_interface::bind() + */ +struct value { +private: + union { + bool v_bool; + uint32_t v_uint32; + int32_t v_int32; + const char* v_string; + float v_float; + list v_list; }; - template<> - inline const auto& value::get() const { - return v_bool; +public: + /** Type labels for @ref ink::runtime::value */ + enum class Type { + Bool, ///< containing bool + Uint32, ///< containing uint32_t + Int32, ///< containing int32_t + String, ///< contaning a const char* + Float, ///< containing a float + List ///< containing a @ref list_interface + } type; ///< Label of type currently contained in @ref value + + value() + : v_int32{0} + , type{Type::Int32} + { } - template<> - inline const auto& value::get() const { - return v_uint32; + + ///@{ + /** Construct value from corresponding type */ + value(bool v) + : v_bool{v} + , type{Type::Bool} + { } - template<> - inline const auto& value::get() const { - return v_int32; + + value(uint32_t v) + : v_uint32{v} + , type{Type::Uint32} + { } - template<> - inline const auto& value::get() const { - return v_string; + + value(int32_t v) + : v_int32{v} + , type{Type::Int32} + { } - template<> - inline const auto& value::get() const { - return v_float; + + value(const char* v) + : v_string{v} + , type{Type::String} + { } - template<> - inline const auto& value::get() const { - return v_list; + + value(float v) + : v_float{v} + , type{Type::Float} + { + } + + value(list_interface* list) + : v_list{list} + , type{Type::List} + { + } + + value(const value& v) + : type{v.type} + { + switch (type) { + case Type::Bool: v_bool = v.v_bool; break; + case Type::Uint32: v_uint32 = v.v_uint32; break; + case Type::Int32: v_int32 = v.v_int32; break; + case Type::String: v_string = v.v_string; break; + case Type::Float: v_float = v.v_float; break; + case Type::List: v_list = v.v_list; break; + } + } + + /// @} + + /** Get value to corresponding type + * @tparam Ty #Type label of type to get + * @attention behavior if undefined if Ty != value.type + */ + template + const auto& get() const + { + static_assert(Ty != Ty, "No value getter for the selected type"); } +}; + +template<> +inline const auto& value::get() const +{ + return v_bool; +} + +template<> +inline const auto& value::get() const +{ + return v_uint32; +} + +template<> +inline const auto& value::get() const +{ + return v_int32; +} + +template<> +inline const auto& value::get() const +{ + return v_string; +} + +template<> +inline const auto& value::get() const +{ + return v_float; +} + +template<> +inline const auto& value::get() const +{ + return v_list; } +} // namespace ink::runtime diff --git a/inkcpp/value.cpp b/inkcpp/value.cpp index ec2fc0c0..0d944fb2 100644 --- a/inkcpp/value.cpp +++ b/inkcpp/value.cpp @@ -170,22 +170,22 @@ namespace ink::runtime::internal using types = ink::runtime::value::Type; switch (val.type) { case types::Bool: - set(val.v_bool); + set(val.get()); break; case types::Uint32: - set(val.v_uint32); + set(val.get()); break; case types::Int32: - set(val.v_int32); + set(val.get()); break; case types::String: - set(val.v_string); + set(val.get()); break; case types::Float: - set(val.v_float); + set(val.get()); break; case types::List: - set(list_table::list{static_cast(val.v_list)->get_lid()}); + set(list_table::list{static_cast(val.get())->get_lid()}); } } diff --git a/inkcpp_compiler/include/compiler.h b/inkcpp_compiler/include/compiler.h index 2e22410c..5f1d4c8a 100644 --- a/inkcpp_compiler/include/compiler.h +++ b/inkcpp_compiler/include/compiler.h @@ -9,26 +9,27 @@ namespace ink { + /** collection of functions to compile a story.json to story.bin */ namespace compiler { - // file -> file + /** file -> file */ void run(const char* filenameIn, const char* filenameOut, compilation_results* results = nullptr); - // file -> stream + /** file -> stream */ void run(const char* filenameIn, std::ostream& out, compilation_results* results = nullptr); #ifdef INK_EXPOSE_JSON - // JSON -> file + /** JSON -> file */ void run(const nlohmann::json&, const char* filenameOut, compilation_results* results = nullptr); - // JSON -> stream + /** JSON -> stream */ void run(const nlohmann::json&, std::ostream& out, compilation_results* results = nullptr); #endif - // stream -> stream + /** stream -> stream */ void run(std::istream& in, std::ostream& out, compilation_results* results = nullptr); - // stream -> file + /* stream -> file **/ void run(std::istream& in, const char* filenameOut, compilation_results* results = nullptr); } } diff --git a/inkcpp_py/src/module.cpp b/inkcpp_py/src/module.cpp index 7e4e13a9..e1df0022 100644 --- a/inkcpp_py/src/module.cpp +++ b/inkcpp_py/src/module.cpp @@ -35,11 +35,8 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, ink::runtime::story_ptr); struct StringValueWrap : public value { StringValueWrap(const std::string& s) - : str{s} - { - value::type = value::Type::String; - value::v_string = str.c_str(); - } + : value(s.c_str()), str{s} + { } ~StringValueWrap() { std::cout << "death" << std::endl; } @@ -158,19 +155,19 @@ PYBIND11_MODULE(inkcpp_py, m) if (self.type != value::Type::List) { throw py::attribute_error("Try to access list of non list value"); } - return self.v_list; + return self.get(); }, py::return_value_policy::reference ); py_value.def("__str__", [](const value& self) { switch (self.type) { - case value::Type::Bool: return std::string(self.v_bool ? "true" : "false"); - case value::Type::Uint32: return std::to_string(self.v_uint32); - case value::Type::Int32: return std::to_string(self.v_int32); - case value::Type::String: return std::string(self.v_string); - case value::Type::Float: return std::to_string(self.v_float); + case value::Type::Bool: return std::string(self.get() ? "true" : "false"); + case value::Type::Uint32: return std::to_string(self.get()); + case value::Type::Int32: return std::to_string(self.get()); + case value::Type::String: return std::string(self.get()); + case value::Type::Float: return std::to_string(self.get()); case value::Type::List: { - return list_to_str(*self.v_list); + return list_to_str(*self.get()); } } throw py::attribute_error("value is in an invalid state"); diff --git a/inkcpp_test/Observer.cpp b/inkcpp_test/Observer.cpp index f8522308..f23e7367 100644 --- a/inkcpp_test/Observer.cpp +++ b/inkcpp_test/Observer.cpp @@ -57,15 +57,15 @@ SCENARIO("Observer", "[variables]") auto var1 = [&var1_cnt](value v) { REQUIRE(v.type == value::Type::Int32); if (var1_cnt++ == 0) { - REQUIRE(v.v_int32 == 1); + REQUIRE(v.get() == 1); } else { - REQUIRE(v.v_int32 == 5); + REQUIRE(v.get() == 5); } }; int var2_cnt = 0; auto var2 = [&var2_cnt](value v) { REQUIRE(v.type == value::Type::String); - std::string str(v.v_string); + std::string str(v.get()); if (var2_cnt++ == 0) { REQUIRE(str == "hello"); } else { @@ -133,7 +133,7 @@ SCENARIO("Observer", "[variables]") int var2_cnt = 0; auto var2 = [&var2_cnt](value v, ink::optional o_v) { REQUIRE(v.type == value::Type::String); - std::string str(v.v_string); + std::string str(v.get()); if (var2_cnt++ == 0) { REQUIRE(str == "hello"); REQUIRE_FALSE(o_v.has_value()); @@ -141,7 +141,7 @@ SCENARIO("Observer", "[variables]") REQUIRE(str == "test"); REQUIRE(o_v.has_value()); REQUIRE(o_v.value().type == value::Type::String); - std::string str2(o_v.value().v_string); + std::string str2(o_v.value().get()); REQUIRE(str2 == "hello"); } }; diff --git a/shared/public/system.h b/shared/public/system.h index 6e834119..4b5e5652 100644 --- a/shared/public/system.h +++ b/shared/public/system.h @@ -56,7 +56,7 @@ namespace ink // Used to uniquely identify threads typedef uint32_t thread_t; - // Used to unique identify a list flag + /** Used to unique identify a list flag */ struct list_flag { int16_t list_id; int16_t flag; bool operator==(const list_flag& o) const { From efeadb1f761e40b4602a22c2feb6b2b112b44c83 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:17:22 +0100 Subject: [PATCH 03/11] Add Doxygen landing page --- .gitignore | 2 + CMakeLists.txt | 26 ++++++++ Documentation/cmake_example.zip | Bin 0 -> 1961 bytes Documentation/cmake_example/CMakeLists.txt | 8 +++ Documentation/cmake_example/main.cpp | 46 ++++++++++++++ Documentation/cmake_example/test.ink | 8 +++ Doxyfile | 8 +-- inkcpp/include/story.h | 68 +++++++++++++++++++++ 8 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 Documentation/cmake_example.zip create mode 100644 Documentation/cmake_example/CMakeLists.txt create mode 100644 Documentation/cmake_example/main.cpp create mode 100644 Documentation/cmake_example/test.ink diff --git a/.gitignore b/.gitignore index 4f4b9f8b..d7443423 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ inkcpp_cl/*.ink # Doxygen Documentation/* +!Documentation/cmake_example/ +!Documentation/cmake_example.zip # Output Build/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 704593b5..dc6faa54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,32 @@ find_package(Doxygen) if (DOXYGEN_FOUND) set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) doxygen_add_docs(doc WORKING_DIR ${PROJECT_SOURCE_DIR} CONFIG_FILE "${PROJECT_SOURCE_DIR}/Doxyfile" COMMENT "Generate docs") + if (INKCPP_PY) + find_package( + Python3 + REQUIRED + COMPONENTS Interpreter + ) + execute_process( + COMMAND ${Python3_EXECUTABLE} -m pydoc + RESULT_VARIABLE PYDOC_MISSING + OUTPUT_QUIET) + set(PY_HTML "${PROJECT_SOURCE_DIR}/Documentation/inkcpp_py.html") + if (${PYDOC_MISSING} EQUAL 0) + add_custom_target(inkcpp_py_doc + python -m pydoc -w inkcpp_py + COMMAND mv "./inkcpp_py.html" ${PY_HTML} + DEPENDS inkcpp_py + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inkcpp_py" + COMMENT "Generates simple python documentation") + else() + message(WARNING "The pydoc module is not installed. Therfore no documentation for the python bindings can be created! '${PYDOC_MISSING}'") + add_custom_target(inkcpp_py_doc + echo "

Python Documenattion was not build!

" > ${PY_HTML} + COMMENT "Python Documentation dummy") + endif() + add_dependencies(doc inkcpp_py_doc) + endif(INKCPP_PY) else(DOXYGEN_FOUND) message("Doxygen needed to generate documntation!") endif(DOXYGEN_FOUND) diff --git a/Documentation/cmake_example.zip b/Documentation/cmake_example.zip new file mode 100644 index 0000000000000000000000000000000000000000..492d8d14128f000313c9fb2942a77106615a2561 GIT binary patch literal 1961 zcmWIWW@h1H00F-Y)d(;HO7JnrFeK+DW~audRwU*YVt=WgxGj;t|e+qaq zCIjiOAmdKErl&cdrJ!`xCdg^uG zpft|YAJY6Mh_B;bsi?!2F}FZ!+1Bs%NveADkG*1)ag0ZVf+jE&c#khX?#jr(@R^B$ zK^h|zN>YnU^fL3Z^|Ffd^T2^H7kePAo#g9($U&g(|0$z_56PNacsp;h2zRpk&+C!n zQr()9eYos;&UTK>U-#$cY6?1CXg)r3&*yW-@}en4e@~T8)Z{!9XX&9qZRo3ZCqrko(gyYG}8)mq;oHu%FE!+6c_wA~F$-QkCfarq7}{@trCl|<*i-4PQzODT8zt{|cO3%bA4JseY7E1z(ht$6iI z8WA(fz?hk{Bx2D?V9cxrrd%o4lD ziXP$fxVdNZZTFH)`kGs@noVgb zX^2tdeBgQJh2>9OvF!wsgp%{LBe2yw)-gywC1!IgGC+>xu} zd+U@b!CH~G_9rK&Oyv8py~cBU!HmD3CYa>vpRm2{w|QmBZN6}$I!WG7Onz(c)T~<6 z`DWjQmsvBnNPArj*UNZxkZ|0%fzbwx)`-)$+JIHs;wf_Wtv`BuG`VdRkUNauJEku z`)3LTuMd0qLp)ueKYi-P8`D}MG+b9jJKC?_d09ZDbwl3$H-cub12_De|8MgzW<txZ-)~$)ismXHT9C*Ep|#$}{lErAI9VlZ7U47Tsy_*JyIEsMjY^qafjKkxN~l zibb_PdpE8Uv6!nBywhT?(;?9w(Ji7rqB)|gF8Z2ZGrYRy>7}i~1z(FFG6Bn8MkYCC zT&1`K&?_Jy!0^@)M5CAKtdKGt%^MIiah2#0Gl3b1VM(J0hMDN)JJ1GD`Hsg1%+eCs z20x%hsIG=Z1hnh~S^z3L@mPSF>5(mX0W6?VEkG0jK(j$b03Ne3(+#rOjI8Kp!yF$P b0yG;-3JUOMWdlVND-fOsdi@B{1O^5GC~4sB literal 0 HcmV?d00001 diff --git a/Documentation/cmake_example/CMakeLists.txt b/Documentation/cmake_example/CMakeLists.txt new file mode 100644 index 00000000..af11af8f --- /dev/null +++ b/Documentation/cmake_example/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(main) + +find_package(inkcpp CONFIG REQUIRED) + +add_executable(main main.cpp) +set_property(TARGET main PROPERTY CXX_STANDARD 17) +target_link_libraries(main inkcpp inkcpp_compiler) diff --git a/Documentation/cmake_example/main.cpp b/Documentation/cmake_example/main.cpp new file mode 100644 index 00000000..f29bd1c1 --- /dev/null +++ b/Documentation/cmake_example/main.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +#include + +using namespace ink::runtime; + +int +MyInkFunction( int a, int b ) +{ + return a + b; +} + +int +main() +{ + ink::compiler::run("test.ink.json", "test.bin"); + // Load ink binary story, generated from the inkCPP compiler + story* myInk = story::from_file( "test.bin" ); + + // Create a new thread + runner thread = myInk->new_runner(); + + // Register external functions (glue automatically generated via templates) + thread->bind( "my_ink_function", &MyInkFunction ); + + // Write to cout + while ( thread->can_continue() ) + std::cout << thread->getline(); + + // Iterate choices + int id = 0; + for ( const choice& c : *thread ) + { + std::cout << (id++) << ". " << c.text() << std::endl; + } + std::cin >> id; + thread->choose(id); + + // Write to cout + while ( thread->can_continue() ) + std::cout << thread->getline(); +} diff --git a/Documentation/cmake_example/test.ink b/Documentation/cmake_example/test.ink new file mode 100644 index 00000000..0f9a99e5 --- /dev/null +++ b/Documentation/cmake_example/test.ink @@ -0,0 +1,8 @@ +EXTERNAL my_ink_function(a,b) + +Hello world! +* Hello back! + Nice to hear from you! +* Bye + BTW 3 + 5 = {my_ink_function(3,5)} +-> END diff --git a/Doxyfile b/Doxyfile index e0d7a996..01d852ac 100644 --- a/Doxyfile +++ b/Doxyfile @@ -836,7 +836,7 @@ CITE_BIB_FILES = # messages are off. # The default value is: NO. -QUIET = NO +QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES @@ -1074,7 +1074,7 @@ EXCLUDE_SYMBOLS = ink::list_flag # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = Documentation # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -1364,7 +1364,7 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = Documentation/inkcpp_py.html # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. @@ -1925,7 +1925,7 @@ EXTRA_SEARCH_MAPPINGS = # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/inkcpp/include/story.h b/inkcpp/include/story.h index c62cbbdd..9ba75d8b 100644 --- a/inkcpp/include/story.h +++ b/inkcpp/include/story.h @@ -85,3 +85,71 @@ namespace ink::runtime #pragma endregion }; } + +/** @mainpage InkCPP Documentation + * @tableofcontents + * + * @section cmake CMAKE usage + * + * The current erlease is available at the [release page](https://github.com/JBenda/inkcpp/releases/latest), as `-lib.zip` (e.g. `linux-lib.zip`).
+ * to link the libraries you can use `find_package(inkcpp CONFIG)` which provides two targets: + * + inkcpp: the runtime enviroment + * + inkcpp_comopiler: functionality to compile a story.json to story.bin + * + * To run your own `.ink` files you need a way to compile it to inks runtime format `.ink.json`. One way is to use `inklecate .ink`.
+ * Which is available at the [official release page](https://github.com/inkle/ink/releases/latest).
+ * + * Exampl with library extracted at /YOUR/PROJECT/linux-lib + * And the [Example project](../cmake_example.zip) is extracted to /YOUR/PROJECT + * @code {sh} + * cd /YOUR/PROJECT + * ls # expected output: CMakeLists.txt main.cpp test.ink test.ink.json linux-lib + * mkdir build + * cd build + * inkcpp_DIR=../linux-lib cmake .. + * cmake --build . + * cp ../test.ink.json . + * ./main + * @endcode + * + * @subsection src_main main.cpp + * @include cmake_example/main.cpp + * + * @subsection src_cmake CMakeLists.txt + * @include cmake_example/CMakeLists.txt + * + * @subsection src_story_json test.ink + * @include cmake_example/test.ink + * [test.ink.json](../cmake_example/test.ink.json) + * + * @section ue Unreal Installation + * + * The current release is available at the [release page](https://github.com/JBenda/inkcpp/releases/latest), as `-unreal.zip` (e.g. `win64-unreal.zip`).
+ * Unpack this folder in `/PATH/TO/UNREAL_PROJECT/Plugins/` and it will be intigrated at the next startup.
+ * A MarketPlace appearance is work in progress :) + * + * If you want to use the newest version clone the project and install the unreal component. + * @code {sh} + * git clone https://github.com/JBenda/inkcpp + * cd inkcpp + * mkdir build + * mkdir plugin + * cd build + * cmake .. + * cmake --install . --component unreal --prefix ../plugin + * cd ../plugin + * # Should contain a folder named 'inkcpp' + * cp -r inkcpp /PATH/TO/UNREAL_PROJECT/Plugins + * @endcode + * + * @section py Python example + * + * You can install the current release from [pypi](https://pypi.com/projects/inkcpp-py) with
+ * `pip install inkcpp-py`.
+ * Or build it yourself with
+ * `pip install .` + * + * Here can you find an [example](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/example.py) inclusive [story](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/unreal_example.ink). + * + * [Python module documentation](./inkcpp_py.html) + */ From 50b7606194528444222e01a4d33b4acaec114584 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:34:44 +0100 Subject: [PATCH 04/11] Add doxygen deploy in workflow --- .github/workflows/build.yml | 59 +++++++++++++++++++++++++++++-------- README.md | 6 ++-- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a2248d94..afccd18c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,7 +74,7 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{github.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DINKCPP_PY=ON + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DINKCPP_PY=OFF # Build using CMake and OS toolkit - name: Build @@ -125,17 +125,6 @@ jobs: name: ${{ matrix.artifact }}-unreal path: build/comp_unreal/ - # - name: Install PythonLib - # working-directory: ${{github.workspace}}/build - # shell: bash - # run: cmake --install . --config $BUILD_TYPE --prefix comp_py --component py - - # - name: Upload Binary Artifact - # uses: actions/upload-artifact@v3 - # with: - # name: ${{ matrix.artifact }}-py - # path: build/comp_py/ - # Make sure Inkproof has everything it needs to run our executable - name: Setup Ink Proof if: ${{ matrix.proof }} @@ -181,6 +170,45 @@ jobs: name: ${{ matrix.artifact }}-www path: proofing/ink-proof/out + build-doc: + name: Build Doxygen documentation + needs: compilation build-python + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Set upt Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: install python deps + run: >- + python3 -m + pip install + pydoc + --user + - name: Install Doxygen + run: sudo apt-get install doxygen graphviz -y + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1.14.2 + with: + cmake-version: '3.21.x' + - name: Create Build Environment + run: cmake -E make_directory ${{github.workspace}}/build + - name: Configure CMake + shell: bash + working-directory: ${{github.workspace}}/build + run: cmake $GITHUB_WORKSPACE -DINKCPP_PY=ON + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + run: cmake --build . --target doc + - name: Upload + uses: actions/upload-artifact@v3 + with: + name: doxygen + path: Documentation/ build-python: name: Build Python package @@ -293,12 +321,17 @@ jobs: runs-on: ubuntu-latest if: github.ref == 'refs/heads/master' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # Download Ink Proof page for Linux - uses: actions/download-artifact@v2 with: name: linux-www + path: www/proof + + - uses: actions/download-artifact@v2 + with: + name: doxygen path: www # Deploy to Github Pages diff --git a/README.md b/README.md index 3688c39f..677c9c86 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,9 @@ Inkle Ink C++ Runtime with JSON -> Binary Compiler. -Ink Proofing Test Results: https://jbenda.github.io/inkcpp +Ink Proofing Test Results: https://jbenda.github.io/inkcpp/proof + +Doxygen Documentation: https://jbenda.github.io/inkcpp/html ## Project Goals * Fast, simple, clean syntax @@ -145,7 +147,7 @@ Right now this only executes the internal unit tests which test the functions of ## Python Bindings The easy way to start is installing it with pip: `pip install inkcpp_py`. -An example can be found at [./inkcpp_py/example.py]. +An example can be found at [example.py](./inkcpp_py/example.py). To build it from source use: ```sh From 21543e1695fa5c57475e6ab9700813c678ed8d73 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:38:51 +0100 Subject: [PATCH 05/11] typo --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afccd18c..55a35e0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -172,7 +172,7 @@ jobs: build-doc: name: Build Doxygen documentation - needs: compilation build-python + needs: [compilation, build-python] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 5150619b22f699bb6f0d2ee8b3926a068a5e1384 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:42:38 +0100 Subject: [PATCH 06/11] formatting --- Documentation/cmake_example/main.cpp | 20 +- inkcpp/include/globals.h | 289 +++++++++--------- inkcpp/include/story.h | 30 +- inkcpp/value.cpp | 438 ++++++++++++++------------- inkcpp_compiler/include/compiler.h | 32 +- inkcpp_py/src/module.cpp | 6 +- inkcpp_test/Observer.cpp | 42 +-- shared/public/system.h | 408 +++++++++++++------------ 8 files changed, 670 insertions(+), 595 deletions(-) diff --git a/Documentation/cmake_example/main.cpp b/Documentation/cmake_example/main.cpp index f29bd1c1..bf661cbf 100644 --- a/Documentation/cmake_example/main.cpp +++ b/Documentation/cmake_example/main.cpp @@ -8,39 +8,33 @@ using namespace ink::runtime; -int -MyInkFunction( int a, int b ) -{ - return a + b; -} +int MyInkFunction(int a, int b) { return a + b; } -int -main() +int main() { ink::compiler::run("test.ink.json", "test.bin"); // Load ink binary story, generated from the inkCPP compiler - story* myInk = story::from_file( "test.bin" ); + story* myInk = story::from_file("test.bin"); // Create a new thread runner thread = myInk->new_runner(); // Register external functions (glue automatically generated via templates) - thread->bind( "my_ink_function", &MyInkFunction ); + thread->bind("my_ink_function", &MyInkFunction); // Write to cout - while ( thread->can_continue() ) + while (thread->can_continue()) std::cout << thread->getline(); // Iterate choices int id = 0; - for ( const choice& c : *thread ) - { + for (const choice& c : *thread) { std::cout << (id++) << ". " << c.text() << std::endl; } std::cin >> id; thread->choose(id); // Write to cout - while ( thread->can_continue() ) + while (thread->can_continue()) std::cout << thread->getline(); } diff --git a/inkcpp/include/globals.h b/inkcpp/include/globals.h index ee12f782..53f1eb0a 100644 --- a/inkcpp/include/globals.h +++ b/inkcpp/include/globals.h @@ -5,154 +5,173 @@ namespace ink::runtime { - class snapshot; +class snapshot; +/** + * Represents a global store to be shared amongst ink runners. + * Stores global variable values, visit counts, turn counts, etc. + */ +class globals_interface +{ +public: /** - * Represents a global store to be shared amongst ink runners. - * Stores global variable values, visit counts, turn counts, etc. - */ - class globals_interface + * @brief Access global variable of Ink runner. + * @param name name of variable, as defined in InkScript + * @tparam T c++ type of variable + * @return nullopt if variable won't exist or type won't match + */ + template + optional get(const char* name) const { - public: - - /** - * @brief Access global variable of Ink runner. - * @param name name of variable, as defined in InkScript - * @tparam T c++ type of variable - * @return nullopt if variable won't exist or type won't match - */ - template - optional get(const char* name) const { - static_assert( - internal::always_false::value, - "Requested Type is not supported"); - } - - /** - * @brief Write new value in global store. - * @param name name of variable, as defined in InkScript - * @tparam T c++ type of variable - * @return true on success - */ - template - bool set(const char* name, const T& val) { - static_assert( - internal::always_false::value, - "Requested Type is not supported"); - return false; - } - - /** - * @brief Observers global variable. - * - * Calls callback with `value` or with casted value if it is one of - * values variants. The callback will also be called with the current value - * when the observe is bind. - * @param callback functor with: - * * 0 arguments - * * 1 argument: `new_value` - * * 2 arguments: `new_value`, `ink::optional`: first time call will not contain a old_value - */ - template - void observe(const char* name, F callback) { - internal_observe(hash_string(name), new internal::callback(callback)); - } - - virtual snapshot* create_snapshot() const = 0; - - virtual ~globals_interface() = default; - - protected: - virtual optional get_var(hash_t name) const = 0; - virtual bool set_var(hash_t name, const value& val) = 0; - virtual void internal_observe(hash_t name, internal::callback_base* callback) = 0; - }; - - template<> - inline optional globals_interface::get(const char* name) const { - return get_var(hash_string(name)); - } - template<> - inline bool globals_interface::set(const char* name, const value& val) { - return set_var(hash_string(name), val); - } - - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if ( var && var->type == value::Type::Bool) { - return {var->get()}; - } - return nullopt; - } - template<> - inline bool globals_interface::set(const char* name, const bool& val) { - return set_var(hash_string(name), value(val)); + static_assert(internal::always_false::value, "Requested Type is not supported"); } - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if (var && var->type == value::Type::Uint32) { - return {var->get()}; - } - return nullopt; - } - template<> - inline bool globals_interface::set(const char* name, const uint32_t& val) { - return set_var(hash_string(name), value(val)); + /** + * @brief Write new value in global store. + * @param name name of variable, as defined in InkScript + * @tparam T c++ type of variable + * @return true on success + */ + template + bool set(const char* name, const T& val) + { + static_assert(internal::always_false::value, "Requested Type is not supported"); + return false; } - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if (var && var->type == value::Type::Int32) { - return {var->get()}; - } - return nullopt; - } - template<> - inline bool globals_interface::set(const char* name, const int32_t& val) { - return set_var(hash_string(name), value(val)); + /** + * @brief Observers global variable. + * + * Calls callback with `value` or with casted value if it is one of + * values variants. The callback will also be called with the current value + * when the observe is bind. + * @param callback functor with: + * * 0 arguments + * * 1 argument: `new_value` + * * 2 arguments: `new_value`, `ink::optional`: first time call will not contain a + * old_value + */ + template + void observe(const char* name, F callback) + { + internal_observe(hash_string(name), new internal::callback(callback)); } - - - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if ( var && var->type == value::Type::Float) { - return {var->get()}; - } - return nullopt; + + virtual snapshot* create_snapshot() const = 0; + + virtual ~globals_interface() = default; + +protected: + virtual optional get_var(hash_t name) const = 0; + virtual bool set_var(hash_t name, const value& val) = 0; + virtual void internal_observe(hash_t name, internal::callback_base* callback) = 0; +}; + +template<> +inline optional globals_interface::get(const char* name) const +{ + return get_var(hash_string(name)); +} + +template<> +inline bool globals_interface::set(const char* name, const value& val) +{ + return set_var(hash_string(name), val); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::Bool) { + return {var->get()}; } - template<> - inline bool globals_interface::set(const char* name, const float& val) { - return set_var(hash_string(name), value(val)); + return nullopt; +} + +template<> +inline bool globals_interface::set(const char* name, const bool& val) +{ + return set_var(hash_string(name), value(val)); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::Uint32) { + return {var->get()}; } - - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if ( var && var->type == value::Type::String ) { - return {var->get()}; - } - return nullopt; + return nullopt; +} + +template<> +inline bool globals_interface::set(const char* name, const uint32_t& val) +{ + return set_var(hash_string(name), value(val)); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::Int32) { + return {var->get()}; } - template<> - inline bool globals_interface::set(const char* name, const char* const& val) { - return set_var(hash_string(name), value(val)); + return nullopt; +} + +template<> +inline bool globals_interface::set(const char* name, const int32_t& val) +{ + return set_var(hash_string(name), value(val)); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::Float) { + return {var->get()}; } + return nullopt; +} - template<> - inline optional globals_interface::get(const char* name) const { - auto var = get_var(hash_string(name)); - if (var && var->type == value::Type::List) { - return {var->get()}; - } - return nullopt; +template<> +inline bool globals_interface::set(const char* name, const float& val) +{ + return set_var(hash_string(name), value(val)); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::String) { + return {var->get()}; } - template<> - inline bool globals_interface::set(const char* name, const list& val) { - return set_var(hash_string(name), value(val)); + return nullopt; +} + +template<> +inline bool globals_interface::set(const char* name, const char* const& val) +{ + return set_var(hash_string(name), value(val)); +} + +template<> +inline optional globals_interface::get(const char* name) const +{ + auto var = get_var(hash_string(name)); + if (var && var->type == value::Type::List) { + return {var->get()}; } + return nullopt; +} + +template<> +inline bool globals_interface::set(const char* name, const list& val) +{ + return set_var(hash_string(name), value(val)); } +} // namespace ink::runtime diff --git a/inkcpp/include/story.h b/inkcpp/include/story.h index 9ba75d8b..4abaed74 100644 --- a/inkcpp/include/story.h +++ b/inkcpp/include/story.h @@ -91,13 +91,16 @@ namespace ink::runtime * * @section cmake CMAKE usage * - * The current erlease is available at the [release page](https://github.com/JBenda/inkcpp/releases/latest), as `-lib.zip` (e.g. `linux-lib.zip`).
- * to link the libraries you can use `find_package(inkcpp CONFIG)` which provides two targets: + * The current erlease is available at the [release + * page](https://github.com/JBenda/inkcpp/releases/latest), as `-lib.zip` (e.g. + * `linux-lib.zip`).
to link the libraries you can use `find_package(inkcpp CONFIG)` which + * provides two targets: * + inkcpp: the runtime enviroment * + inkcpp_comopiler: functionality to compile a story.json to story.bin * - * To run your own `.ink` files you need a way to compile it to inks runtime format `.ink.json`. One way is to use `inklecate .ink`.
- * Which is available at the [official release page](https://github.com/inkle/ink/releases/latest).
+ * To run your own `.ink` files you need a way to compile it to inks runtime format `.ink.json`. One + * way is to use `inklecate .ink`.
Which is available at the [official release + * page](https://github.com/inkle/ink/releases/latest).
* * Exampl with library extracted at /YOUR/PROJECT/linux-lib * And the [Example project](../cmake_example.zip) is extracted to /YOUR/PROJECT @@ -114,7 +117,7 @@ namespace ink::runtime * * @subsection src_main main.cpp * @include cmake_example/main.cpp - * + * * @subsection src_cmake CMakeLists.txt * @include cmake_example/CMakeLists.txt * @@ -124,9 +127,10 @@ namespace ink::runtime * * @section ue Unreal Installation * - * The current release is available at the [release page](https://github.com/JBenda/inkcpp/releases/latest), as `-unreal.zip` (e.g. `win64-unreal.zip`).
- * Unpack this folder in `/PATH/TO/UNREAL_PROJECT/Plugins/` and it will be intigrated at the next startup.
- * A MarketPlace appearance is work in progress :) + * The current release is available at the [release + * page](https://github.com/JBenda/inkcpp/releases/latest), as `-unreal.zip` (e.g. + * `win64-unreal.zip`).
Unpack this folder in `/PATH/TO/UNREAL_PROJECT/Plugins/` and it will be + * intigrated at the next startup.
A MarketPlace appearance is work in progress :) * * If you want to use the newest version clone the project and install the unreal component. * @code {sh} @@ -143,13 +147,15 @@ namespace ink::runtime * @endcode * * @section py Python example - * + * * You can install the current release from [pypi](https://pypi.com/projects/inkcpp-py) with
* `pip install inkcpp-py`.
* Or build it yourself with
* `pip install .` - * - * Here can you find an [example](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/example.py) inclusive [story](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/unreal_example.ink). * - * [Python module documentation](./inkcpp_py.html) + * Here can you find an + * [example](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/example.py) inclusive + * [story](https://raw.githubusercontent.com/JBenda/inkcpp/master/inkcpp_py/unreal_example.ink). + * + * [Python module documentation](./inkcpp_py.html) */ diff --git a/inkcpp/value.cpp b/inkcpp/value.cpp index 0d944fb2..49a7bfca 100644 --- a/inkcpp/value.cpp +++ b/inkcpp/value.cpp @@ -9,246 +9,266 @@ namespace ink::runtime::internal { - - template - bool truthy_impl(const value& v, const list_table& lists); - template<> - bool truthy_impl(const value& v, const list_table& lists) { - inkFail("Type was not found in operational types or it has no conversion to boolean"); - return false; +template +bool truthy_impl(const value& v, const list_table& lists); + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + inkFail("Type was not found in operational types or it has no conversion to boolean"); + return false; +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::string) { + // if string is not empty + return *v.get().str != 0; + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if(v.type() == value_type::string) { - // if string is not empty - return *v.get().str != 0; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + // if list is not empty -> valid flag -> filled list + if (v.type() == value_type::list_flag) { + auto flag = v.get(); + return flag != null_flag && flag != empty_flag; + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - // if list is not empty -> valid flag -> filled list - if(v.type() == value_type::list_flag) { - auto flag = v.get(); - return flag != null_flag && flag != empty_flag; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + // if list is not empty + if (v.type() == value_type::list) { + return lists.count(v.get()) > 0; + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - // if list is not empty - if(v.type() == value_type::list) { - return lists.count(v.get()) > 0; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::float32) { + return v.get() != 0.0f; + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if (v.type() == value_type::float32) { - return v.get() != 0.0f; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::int32) { + return v.get() != 0; + } else { + return truthy_impl(v, lists); } - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if(v.type() == value_type::int32) { - return v.get() != 0; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::uint32) { + return v.get() != 0; + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if (v.type() == value_type::uint32) { - return v.get() != 0; - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::boolean) { + return v.get(); + } else { + return truthy_impl(v, lists); } - - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if(v.type() == value_type::boolean) { - return v.get(); - } else { - return truthy_impl(v, lists); - } +} + +template<> +bool truthy_impl(const value& v, const list_table& lists) +{ + if (v.type() == value_type::divert) { + inkFail("Divert can not be evaluated to boolean"); + return false; + } else { + return truthy_impl(v, lists); } +} + +bool value::truthy(const list_table& lists) const { return truthy_impl(*this, lists); } - template<> - bool truthy_impl(const value& v, const list_table& lists) { - if (v.type() == value_type::divert) { - inkFail("Divert can not be evaluated to boolean"); - return false; + +#ifdef INK_ENABLE_STL +template +void append(std::ostream& os, const value& val, const list_table* lists) +{ + if constexpr (ty != value_type::PRINT_END) { + if (ty == val.type()) { + os << val.get(); } else { - return truthy_impl(v, lists); + append(os, val, lists); } } +} - bool value::truthy(const list_table& lists) const { - return truthy_impl(*this, lists); +template<> +void append(std::ostream& os, const value& val, const list_table* lists) +{ + if (val.type() == value_type::list_flag) { + inkAssert(lists, "to stringify lists, we need a list_table"); + os << lists->toString(val.get()); + } else { + append(os, val, lists); } - +} - -#ifdef INK_ENABLE_STL - template - void append(std::ostream& os, const value& val, const list_table* lists) { - if constexpr (ty != value_type::PRINT_END) { - if (ty == val.type()) { - os << val.get(); - } else { - append(os, val, lists); - } - } +template<> +void append(std::ostream& os, const value& val, const list_table* lists) +{ + if (val.type() == value_type::list) { + inkAssert(lists, "to stringify lists, we need a list_table"); + lists->write(os, val.get()); + } else { + append(os, val, lists); } +} - template<> - void append(std::ostream& os, const value& val, - const list_table* lists) { - if (val.type() == value_type::list_flag) { - inkAssert(lists, "to stringify lists, we need a list_table"); - os << lists->toString(val.get()); - } else { - append(os, val, lists); - } +template<> +void append(std::ostream& os, const value& val, const list_table* lists) +{ + if (val.type() == value_type::float32) { + char number[32]; + ink::runtime::internal::toStr(number, 32, val.get()); + os << number; + } else { + append(os, val, lists); } - template<> - void append(std::ostream& os, const value& val, - const list_table* lists) { - if (val.type() == value_type::list) { - inkAssert(lists, "to stringify lists, we need a list_table"); - lists->write(os, val.get()); - } else { - append(os, val, lists); - } +} + +template<> +void append(std::ostream& os, const value& val, const list_table* lists) +{ + if (val.type() == value_type::boolean) { + os << (val.get() ? "true" : "false"); + } else { + append(os, val, lists); } - template<> - void append(std::ostream& os, const value& val, const list_table* lists) { - if(val.type() == value_type::float32) { - char number[32]; - ink::runtime::internal::toStr(number, 32, val.get()); - os << number; - } else { - append(os, val, lists); - } +} + +std::ostream& value::write(std::ostream& os, const list_table* lists) const +{ + if (type() < value_type::PRINT_BEGIN || type() >= value_type::PRINT_END) { + throw ink_exception("printing this type is not supported"); } - template<> - void append(std::ostream& os, const value& val, const list_table* lists) { - if(val.type() == value_type::boolean) { - os << (val.get() ? "true" : "false"); - } else { - append(os, val, lists); - } + append(os, *this, lists); + return os; +} +#endif + +basic_stream& operator<<(basic_stream& os, const value& val) +{ + os.append(val); + return os; +} + +value::value(const ink::runtime::value& val) + : value() +{ + using types = ink::runtime::value::Type; + switch (val.type) { + case types::Bool: set(val.get()); break; + case types::Uint32: set(val.get()); break; + case types::Int32: set(val.get()); break; + case types::String: set(val.get()); break; + case types::Float: set(val.get()); break; + case types::List: + set(list_table::list{ + static_cast(val.get())->get_lid()}); } +} - std::ostream& value::write(std::ostream& os, const list_table* lists) const { - if (type() < value_type::PRINT_BEGIN || type() >= value_type::PRINT_END) { - throw ink_exception("printing this type is not supported"); - } - append(os, *this, lists); - return os; +bool value::set(const ink::runtime::value& val) +{ + auto var = value(val); + if (type() == value_type::none || var.type() == type()) { + *this = var; + return true; } -#endif + return false; +} - basic_stream& operator<<(basic_stream& os, const value& val) { - os.append(val); - return os; - } - - value::value(const ink::runtime::value& val) : value() { - using types = ink::runtime::value::Type; - switch (val.type) { - case types::Bool: - set(val.get()); - break; - case types::Uint32: - set(val.get()); - break; - case types::Int32: - set(val.get()); - break; - case types::String: - set(val.get()); - break; - case types::Float: - set(val.get()); - break; - case types::List: - set(list_table::list{static_cast(val.get())->get_lid()}); - } +ink::runtime::value value::to_interface_value(list_table& table) const +{ + using val = ink::runtime::value; + if (type() == value_type::boolean) { + return val(get()); + } else if (type() == value_type::uint32) { + return val(get()); + } else if (type() == value_type::int32) { + return val(get()); + } else if (type() == value_type::string) { + return val(get().str); + } else if (type() == value_type::float32) { + return val(get()); + } else if (type() == value_type::list_flag) { + auto v = table.create(); + v = table.add(v, get()); + return val(table.handout_list(v)); + } else if (type() == value_type::list) { + return val(table.handout_list(get())); } + inkFail("No valid type to convert to interface value!"); + return val(); +} - bool value::set( const ink::runtime::value& val ) { - auto var = value( val ); - if ( type() == value_type::none || var.type() == type() ) { - *this = var; - return true; +size_t value::snap(unsigned char* data, const snapper& snapper) const +{ + unsigned char* ptr = data; + bool should_write = data != nullptr; + ptr = snap_write(ptr, _type, should_write); + if (_type == value_type::string) { + unsigned char buf[max_value_size]; + string_type* res = reinterpret_cast(buf); + auto str = get(); + res->allocated = str.allocated; + if (str.allocated) { + res->str = reinterpret_cast( + static_cast(snapper.strings.get_id(str.str)) + ); + } else { + res->str = reinterpret_cast( + static_cast(str.str - snapper.story_string_table) + ); } - return false; + ptr = snap_write(ptr, buf, should_write); + } else { + // TODO more space efficent? + ptr = snap_write(ptr, &bool_value, max_value_size, should_write); } + return ptr - data; +} - ink::runtime::value value::to_interface_value(list_table& table) const { - using val = ink::runtime::value; - if(type() == value_type::boolean) { return val(get()); } - else if(type() == value_type::uint32) { return val(get()); } - else if(type() == value_type::int32) { return val(get()); } - else if(type() == value_type::string) { return val(get().str); } - else if(type() == value_type::float32) { return val(get()); } - else if(type() == value_type::list_flag) { - auto v = table.create(); - v = table.add(v, get()); - return val(table.handout_list(v)); - } else if(type() == value_type::list) { - return val(table.handout_list(get())); - } - inkFail("No valid type to convert to interface value!"); - return val(); - } - - size_t value::snap(unsigned char* data, const snapper& snapper) const - { - unsigned char* ptr = data; - bool should_write = data != nullptr; - ptr = snap_write(ptr, _type, should_write ); - if (_type == value_type::string) { - unsigned char buf[max_value_size]; - string_type* res = reinterpret_cast(buf); - auto str = get(); - res->allocated = str.allocated; - if (str.allocated) { - res->str = reinterpret_cast(static_cast(snapper.strings.get_id(str.str))); - } else { - res->str = reinterpret_cast(static_cast(str.str - snapper.story_string_table)); - } - ptr = snap_write(ptr, buf, should_write ); +const unsigned char* value::snap_load(const unsigned char* ptr, const loader& loader) +{ + ptr = snap_read(ptr, _type); + ptr = snap_read(ptr, &bool_value, max_value_size); + if (_type == value_type::string) { + if (string_value.allocated) { + string_value.str = loader.string_table[(std::uintptr_t)(string_value.str)]; } else { - // TODO more space efficent? - ptr = snap_write(ptr, &bool_value, max_value_size, should_write ); - } - return ptr - data; - } - const unsigned char* value::snap_load(const unsigned char* ptr, const loader& loader) - { - ptr = snap_read(ptr, _type); - ptr = snap_read(ptr, &bool_value, max_value_size); - if(_type == value_type::string) { - if(string_value.allocated) { - string_value.str = loader.string_table[(std::uintptr_t)(string_value.str)]; - } else { - string_value.str = loader.story_string_table +(std::uintptr_t)(string_value.str); - } + string_value.str = loader.story_string_table + (std::uintptr_t)(string_value.str); } - return ptr; } + return ptr; } +} // namespace ink::runtime::internal diff --git a/inkcpp_compiler/include/compiler.h b/inkcpp_compiler/include/compiler.h index 5f1d4c8a..e88f4f44 100644 --- a/inkcpp_compiler/include/compiler.h +++ b/inkcpp_compiler/include/compiler.h @@ -9,27 +9,27 @@ namespace ink { - /** collection of functions to compile a story.json to story.bin */ - namespace compiler - { - /** file -> file */ - void run(const char* filenameIn, const char* filenameOut, compilation_results* results = nullptr); +/** collection of functions to compile a story.json to story.bin */ +namespace compiler +{ + /** file -> file */ + void run(const char* filenameIn, const char* filenameOut, compilation_results* results = nullptr); - /** file -> stream */ - void run(const char* filenameIn, std::ostream& out, compilation_results* results = nullptr); + /** file -> stream */ + void run(const char* filenameIn, std::ostream& out, compilation_results* results = nullptr); #ifdef INK_EXPOSE_JSON - /** JSON -> file */ - void run(const nlohmann::json&, const char* filenameOut, compilation_results* results = nullptr); + /** JSON -> file */ + void run(const nlohmann::json&, const char* filenameOut, compilation_results* results = nullptr); - /** JSON -> stream */ - void run(const nlohmann::json&, std::ostream& out, compilation_results* results = nullptr); + /** JSON -> stream */ + void run(const nlohmann::json&, std::ostream& out, compilation_results* results = nullptr); #endif - /** stream -> stream */ - void run(std::istream& in, std::ostream& out, compilation_results* results = nullptr); + /** stream -> stream */ + void run(std::istream& in, std::ostream& out, compilation_results* results = nullptr); - /* stream -> file **/ - void run(std::istream& in, const char* filenameOut, compilation_results* results = nullptr); - } + /* stream -> file **/ + void run(std::istream& in, const char* filenameOut, compilation_results* results = nullptr); +} // namespace compiler } diff --git a/inkcpp_py/src/module.cpp b/inkcpp_py/src/module.cpp index e1df0022..83a3046d 100644 --- a/inkcpp_py/src/module.cpp +++ b/inkcpp_py/src/module.cpp @@ -35,8 +35,10 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, ink::runtime::story_ptr); struct StringValueWrap : public value { StringValueWrap(const std::string& s) - : value(s.c_str()), str{s} - { } + : value(s.c_str()) + , str{s} + { + } ~StringValueWrap() { std::cout << "death" << std::endl; } diff --git a/inkcpp_test/Observer.cpp b/inkcpp_test/Observer.cpp index f23e7367..caae3b6f 100644 --- a/inkcpp_test/Observer.cpp +++ b/inkcpp_test/Observer.cpp @@ -57,20 +57,20 @@ SCENARIO("Observer", "[variables]") auto var1 = [&var1_cnt](value v) { REQUIRE(v.type == value::Type::Int32); if (var1_cnt++ == 0) { - REQUIRE(v.get() == 1); - } else { - REQUIRE(v.get() == 5); - } + REQUIRE(v.get() == 1); + } else { + REQUIRE(v.get() == 5); + } }; int var2_cnt = 0; auto var2 = [&var2_cnt](value v) { REQUIRE(v.type == value::Type::String); - std::string str(v.get()); - if (var2_cnt++ == 0) { - REQUIRE(str == "hello"); - } else { - REQUIRE(str == "test"); - } + std::string str(v.get()); + if (var2_cnt++ == 0) { + REQUIRE(str == "hello"); + } else { + REQUIRE(str == "test"); + } }; globals->observe("var1", var1); @@ -133,17 +133,17 @@ SCENARIO("Observer", "[variables]") int var2_cnt = 0; auto var2 = [&var2_cnt](value v, ink::optional o_v) { REQUIRE(v.type == value::Type::String); - std::string str(v.get()); - if (var2_cnt++ == 0) { - REQUIRE(str == "hello"); - REQUIRE_FALSE(o_v.has_value()); - } else { - REQUIRE(str == "test"); - REQUIRE(o_v.has_value()); - REQUIRE(o_v.value().type == value::Type::String); - std::string str2(o_v.value().get()); - REQUIRE(str2 == "hello"); - } + std::string str(v.get()); + if (var2_cnt++ == 0) { + REQUIRE(str == "hello"); + REQUIRE_FALSE(o_v.has_value()); + } else { + REQUIRE(str == "test"); + REQUIRE(o_v.has_value()); + REQUIRE(o_v.value().type == value::Type::String); + std::string str2(o_v.value().get()); + REQUIRE(str2 == "hello"); + } }; globals->observe("var1", var1); diff --git a/shared/public/system.h b/shared/public/system.h index 4b5e5652..1ff957b8 100644 --- a/shared/public/system.h +++ b/shared/public/system.h @@ -3,252 +3,286 @@ #include "config.h" #ifdef INK_ENABLE_UNREAL -#include "Misc/AssertionMacros.h" -#include "Misc/CString.h" -#include "HAL/UnrealMemory.h" -#include "Hash/CityHash.h" +# include "Misc/AssertionMacros.h" +# include "Misc/CString.h" +# include "HAL/UnrealMemory.h" +# include "Hash/CityHash.h" #endif #ifdef INK_ENABLE_STL -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include #endif namespace ink { - typedef unsigned int uint32_t; +typedef unsigned int uint32_t; - // Name hash (used for temporary variables) - typedef uint32_t hash_t; +// Name hash (used for temporary variables) +typedef uint32_t hash_t; - // Invalid hash - const hash_t InvalidHash = 0; +// Invalid hash +const hash_t InvalidHash = 0; - // Simple hash for serialization of strings +// Simple hash for serialization of strings #ifdef INK_ENABLE_UNREAL - inline hash_t hash_string(const char* string) - { - return CityHash32(string, FCStringAnsi::Strlen(string)); - } +inline hash_t hash_string(const char* string) +{ + return CityHash32(string, FCStringAnsi::Strlen(string)); +} #else - hash_t hash_string(const char* string); +hash_t hash_string(const char* string); #endif - // Byte type - typedef unsigned char byte_t; +// Byte type +typedef unsigned char byte_t; - // Used to identify an offset in a data table (like a string in the string table) - typedef uint32_t offset_t; +// Used to identify an offset in a data table (like a string in the string table) +typedef uint32_t offset_t; - // Instruction pointer used for addressing within the story instructions - typedef unsigned char const* ip_t; - - // Used for the size of arrays - typedef unsigned int size_t; +// Instruction pointer used for addressing within the story instructions +typedef const unsigned char* ip_t; - // Used as the unique identifier for an ink container - typedef uint32_t container_t; +// Used for the size of arrays +typedef unsigned int size_t; - // Used to uniquely identify threads - typedef uint32_t thread_t; +// Used as the unique identifier for an ink container +typedef uint32_t container_t; - /** Used to unique identify a list flag */ - struct list_flag { - int16_t list_id; int16_t flag; - bool operator==(const list_flag& o) const { - return list_id == o.list_id && flag == o.flag; - } - bool operator!=(const list_flag& o) const { - return !(*this == o); - } - }; - constexpr list_flag null_flag{-1,-1}; - constexpr list_flag empty_flag{-1,0}; +// Used to uniquely identify threads +typedef uint32_t thread_t; - // Checks if a string is only whitespace - static bool is_whitespace(const char* string, bool includeNewline = true) - { - // Iterate string - while (true) - { - switch (*(string++)) - { - case 0: - return true; +/** Used to unique identify a list flag */ +struct list_flag { + int16_t list_id; + int16_t flag; + + bool operator==(const list_flag& o) const { return list_id == o.list_id && flag == o.flag; } + + bool operator!=(const list_flag& o) const { return ! (*this == o); } +}; + +constexpr list_flag null_flag{-1, -1}; +constexpr list_flag empty_flag{-1, 0}; + +// Checks if a string is only whitespace +static bool is_whitespace(const char* string, bool includeNewline = true) +{ + // Iterate string + while (true) { + switch (*(string++)) { + case 0: return true; case '\n': - if (!includeNewline) + if (! includeNewline) return false; case '\t': - case ' ': - continue; - default: - return false; - } + case ' ': continue; + default: return false; } } +} +// check if character can be only part of a word, when two part of word characters put together the +// will be a space inserted I049 +inline bool is_part_of_word(char character) { return isalpha(character) || isdigit(character); } - // check if character can be only part of a word, when two part of word characters put together the - // will be a space inserted I049 - inline bool is_part_of_word(char character) - { - return isalpha(character) || isdigit(character); - } - - inline constexpr bool is_whitespace(char character, bool includeNewline = true) - { - switch (character) - { +inline constexpr bool is_whitespace(char character, bool includeNewline = true) +{ + switch (character) { case '\n': - if (!includeNewline) + if (! includeNewline) return false; case '\t': [[fallthrough]]; - case ' ': - return true; - default: - return false; - } + case ' ': return true; + default: return false; } +} - // Zero memory +// Zero memory #ifndef INK_ENABLE_UNREAL - void zero_memory(void* buffer, size_t length); +void zero_memory(void* buffer, size_t length); #endif #ifdef INK_ENABLE_STL - using ink_exception = std::runtime_error; -#else - // Non-STL exception class - class ink_exception +using ink_exception = std::runtime_error; +#else +// Non-STL exception class +class ink_exception +{ +public: + ink_exception(const char* msg) + : _msg(msg) { - public: - ink_exception(const char* msg) : _msg(msg) { } + } - inline const char* message() const { return _msg; } - private: - const char* _msg; - }; + inline const char* message() const { return _msg; } + +private: + const char* _msg; +}; #endif - // assert +// assert #ifndef INK_ENABLE_UNREAL - template - void ink_assert( bool condition, const char* msg = nullptr, Args... args ) - { - static const char* EMPTY = ""; - if (msg == nullptr) { - msg = EMPTY; - } - if ( !condition ) - { - if constexpr ( sizeof...( args ) > 0 ) - { - char* message = static_cast( - malloc( snprintf( nullptr, 0, msg, args... ) + 1 ) ); - sprintf( message, msg, args... ); - throw ink_exception( message ); - } - else - { - throw ink_exception( msg ); - } - } - } - template - [[noreturn]] inline void ink_assert( const char* msg = nullptr, Args... args ) - { - ink_assert( false, msg, args... ); - exit( EXIT_FAILURE ); +template +void ink_assert(bool condition, const char* msg = nullptr, Args... args) +{ + static const char* EMPTY = ""; + if (msg == nullptr) { + msg = EMPTY; } -#else - template - inline void ink_fail(const char* msg, Args... args) { - if (sizeof...(args) > 0) { - checkf(false, UTF8_TO_TCHAR(msg), args...) + if (! condition) { + if constexpr (sizeof...(args) > 0) { + char* message = static_cast(malloc(snprintf(nullptr, 0, msg, args...) + 1)); + sprintf(message, msg, args...); + throw ink_exception(message); } else { - checkf(false, UTF8_TO_TCHAR(msg)); + throw ink_exception(msg); } } -#endif +} - namespace runtime::internal - { - constexpr unsigned abs(int i) { return i < 0 ? -i : i; } - - template - struct always_false { static constexpr bool value = false; }; - - template - struct if_type { using type = T1; }; - template - struct if_type { using type = T2; }; - template - using if_t = typename if_type::type; - - template - struct enable_if { }; - template - struct enable_if { using type = T; }; - template - using enable_if_t = typename enable_if::type; +template +[[noreturn]] inline void ink_assert(const char* msg = nullptr, Args... args) +{ + ink_assert(false, msg, args...); + exit(EXIT_FAILURE); +} +#else +template +inline void ink_fail(const char* msg, Args... args) +{ + if (sizeof...(args) > 0) { + checkf(false, UTF8_TO_TCHAR(msg), args...) + } else { + checkf(false, UTF8_TO_TCHAR(msg)); } +} +#endif +namespace runtime::internal +{ + constexpr unsigned abs(int i) { return i < 0 ? -i : i; } -#ifdef INK_ENABLE_STL template - using optional = std::optional; - constexpr std::nullopt_t nullopt = std::nullopt; -#else - struct nullopt_t{}; - constexpr nullopt_t nullopt; + struct always_false { + static constexpr bool value = false; + }; + + template + struct if_type { + using type = T1; + }; + + template + struct if_type { + using type = T2; + }; + + template + using if_t = typename if_type::type; + + template + struct enable_if { + }; template - class optional { - public: - optional() {} - optional(nullopt_t) {} - optional(T&& val) : _has_value{true}, _value{val}{} - optional(const T& val) : _has_value{true}, _value{val}{} - - const T& operator*() const { return _value; } - T& operator*() { return _value; } - const T* operator->() const { return &_value; } - T* operator->() { return &_value; } - - constexpr bool has_value() const { return _has_value; } - constexpr T& value() { test_value(); return _value; } - constexpr const T& value() const { test_value(); return _value; } - constexpr operator bool() const { return has_value(); } - template - constexpr T value_or(U&& u) const { - return _has_value ? _value : static_cast(u); - } - private: - void test_value() const { - if ( ! _has_value) { - ink_fail("Can't access empty optional!"); - } + struct enable_if { + using type = T; + }; + + template + using enable_if_t = typename enable_if::type; +} // namespace runtime::internal + + +#ifdef INK_ENABLE_STL +template +using optional = std::optional; +constexpr std::nullopt_t nullopt = std::nullopt; +#else +struct nullopt_t { +}; + +constexpr nullopt_t nullopt; + +template +class optional +{ +public: + optional() {} + + optional(nullopt_t) {} + + optional(T&& val) + : _has_value{true} + , _value{val} + { + } + + optional(const T& val) + : _has_value{true} + , _value{val} + { + } + + const T& operator*() const { return _value; } + + T& operator*() { return _value; } + + const T* operator->() const { return &_value; } + + T* operator->() { return &_value; } + + constexpr bool has_value() const { return _has_value; } + + constexpr T& value() + { + test_value(); + return _value; + } + + constexpr const T& value() const + { + test_value(); + return _value; + } + + constexpr operator bool() const { return has_value(); } + + template + constexpr T value_or(U&& u) const + { + return _has_value ? _value : static_cast(u); + } + +private: + void test_value() const + { + if (! _has_value) { + ink_fail("Can't access empty optional!"); } + } - bool _has_value = false; - T _value; - }; + bool _has_value = false; + T _value; +}; #endif -} +} // namespace ink // Platform specific defines // #ifdef INK_ENABLE_UNREAL -#define inkZeroMemory(buff, len) FMemory::Memset(buff, 0, len) -#define inkAssert(condition, text, ...) checkf(condition, TEXT(text), ##__VA_ARGS__) -#define inkFail ink::ink_fail +# define inkZeroMemory(buff, len) FMemory::Memset(buff, 0, len) +# define inkAssert(condition, text, ...) checkf(condition, TEXT(text), ##__VA_ARGS__) +# define inkFail ink::ink_fail #else -#define inkZeroMemory ink::zero_memory -#define inkAssert ink::ink_assert -#define inkFail(...) ink::ink_assert(false, __VA_ARGS__) +# define inkZeroMemory ink::zero_memory +# define inkAssert ink::ink_assert +# define inkFail(...) ink::ink_assert(false, __VA_ARGS__) #endif From 3442ae3715a630bd56a9a56cafc85c7d2011dfed Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:47:54 +0100 Subject: [PATCH 07/11] Do not install system module in python --- .github/workflows/build.yml | 6 ------ CMakeLists.txt | 25 +++++++++---------------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55a35e0a..e171920a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -182,12 +182,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: "3.x" - - name: install python deps - run: >- - python3 -m - pip install - pydoc - --user - name: Install Doxygen run: sudo apt-get install doxygen graphviz -y - name: Setup cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index dc6faa54..0be0db3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,26 +78,19 @@ if (DOXYGEN_FOUND) REQUIRED COMPONENTS Interpreter ) - execute_process( - COMMAND ${Python3_EXECUTABLE} -m pydoc - RESULT_VARIABLE PYDOC_MISSING - OUTPUT_QUIET) - set(PY_HTML "${PROJECT_SOURCE_DIR}/Documentation/inkcpp_py.html") - if (${PYDOC_MISSING} EQUAL 0) - add_custom_target(inkcpp_py_doc - python -m pydoc -w inkcpp_py - COMMAND mv "./inkcpp_py.html" ${PY_HTML} - DEPENDS inkcpp_py - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inkcpp_py" - COMMENT "Generates simple python documentation") - else() - message(WARNING "The pydoc module is not installed. Therfore no documentation for the python bindings can be created! '${PYDOC_MISSING}'") + add_custom_target(inkcpp_py_doc + python -m pydoc -w inkcpp_py + COMMAND mv "./inkcpp_py.html" ${PY_HTML} + DEPENDS inkcpp_py + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inkcpp_py" + COMMENT "Generates simple python documentation") + else() + message(WARNING "The python target is disabled, therfore no python documentation will be build. Set INKCPP_PY=ON to change this") add_custom_target(inkcpp_py_doc echo "

Python Documenattion was not build!

" > ${PY_HTML} COMMENT "Python Documentation dummy") - endif() - add_dependencies(doc inkcpp_py_doc) endif(INKCPP_PY) + add_dependencies(doc inkcpp_py_doc) else(DOXYGEN_FOUND) message("Doxygen needed to generate documntation!") endif(DOXYGEN_FOUND) From bb54774fef8712faf34a318f2bd1e34f94a27b95 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 13:58:06 +0100 Subject: [PATCH 08/11] re insert deleted PY_HTML --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0be0db3b..d3b07b30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ find_package(Doxygen) if (DOXYGEN_FOUND) set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) doxygen_add_docs(doc WORKING_DIR ${PROJECT_SOURCE_DIR} CONFIG_FILE "${PROJECT_SOURCE_DIR}/Doxyfile" COMMENT "Generate docs") + set(PY_HTML "${PROJECT_SOURCE_DIR}/Documentation/inkcpp_py.html") if (INKCPP_PY) find_package( Python3 @@ -85,7 +86,7 @@ if (DOXYGEN_FOUND) WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inkcpp_py" COMMENT "Generates simple python documentation") else() - message(WARNING "The python target is disabled, therfore no python documentation will be build. Set INKCPP_PY=ON to change this") + message(WARNING "The python target is disabled, therfore no python documentation will be build. Set INKCPP_PY to change this") add_custom_target(inkcpp_py_doc echo "

Python Documenattion was not build!

" > ${PY_HTML} COMMENT "Python Documentation dummy") From 854c8dcf810bf91c3f87a651c8e9ed35ccef8e89 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 16:41:16 +0100 Subject: [PATCH 09/11] Add short Unreal and cmake descriptions to Doxygen --- CMakeLists.txt | 6 ++---- inkcpp/include/globals.h | 4 ++++ inkcpp/include/story.h | 13 +++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3b07b30..5b0891ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,13 +85,11 @@ if (DOXYGEN_FOUND) DEPENDS inkcpp_py WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inkcpp_py" COMMENT "Generates simple python documentation") + add_dependencies(doc inkcpp_py_doc) else() message(WARNING "The python target is disabled, therfore no python documentation will be build. Set INKCPP_PY to change this") - add_custom_target(inkcpp_py_doc - echo "

Python Documenattion was not build!

" > ${PY_HTML} - COMMENT "Python Documentation dummy") + file(WRITE ${PY_HTML} "

Python Documenattion was not build!

") endif(INKCPP_PY) - add_dependencies(doc inkcpp_py_doc) else(DOXYGEN_FOUND) message("Doxygen needed to generate documntation!") endif(DOXYGEN_FOUND) diff --git a/inkcpp/include/globals.h b/inkcpp/include/globals.h index 53f1eb0a..2f75ddce 100644 --- a/inkcpp/include/globals.h +++ b/inkcpp/include/globals.h @@ -67,6 +67,9 @@ class globals_interface virtual void internal_observe(hash_t name, internal::callback_base* callback) = 0; }; +/** @name Instanciations */ +///@{ +/** getter and setter instanciations for supported types */ template<> inline optional globals_interface::get(const char* name) const { @@ -174,4 +177,5 @@ inline bool globals_interface::set(const char* name, const list& val) { return set_var(hash_string(name), value(val)); } +///@} } // namespace ink::runtime diff --git a/inkcpp/include/story.h b/inkcpp/include/story.h index 4abaed74..8d3e6706 100644 --- a/inkcpp/include/story.h +++ b/inkcpp/include/story.h @@ -14,7 +14,7 @@ namespace ink::runtime * globals object. By default, each runner gets its own newly * created globals store. * @see runner_interface - * @see globals + * @see globals_interface */ class story { @@ -88,6 +88,11 @@ namespace ink::runtime /** @mainpage InkCPP Documentation * @tableofcontents + * Inkle Ink C++ Runtime with INK.JSON -> Binary Compiler.
+ * supports ussage in: + * + C++ (with CMAKE) + * + UE + * + Python [inkcpp_py](https://pypi.org/project/inkcpp-py/) * * @section cmake CMAKE usage * @@ -123,7 +128,7 @@ namespace ink::runtime * * @subsection src_story_json test.ink * @include cmake_example/test.ink - * [test.ink.json](../cmake_example/test.ink.json) + * compiled: [test.ink.json](../cmake_example/test.ink.json) * * @section ue Unreal Installation * @@ -148,9 +153,9 @@ namespace ink::runtime * * @section py Python example * - * You can install the current release from [pypi](https://pypi.com/projects/inkcpp-py) with
+ * You can install the current release from [pypi](https://pypi.org/project/inkcpp-py/) with
* `pip install inkcpp-py`.
- * Or build it yourself with
+ * Or build it yourself from main with:
* `pip install .` * * Here can you find an From 4ccd7934a292675d3104673ae77c31c914baa0eb Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 17:28:21 +0100 Subject: [PATCH 10/11] Add Unreal Documentation --- Doxyfile | 5 ++-- inkcpp/include/story.h | 14 +++++++++++ unreal/inkcpp/Source/inkcpp/Public/InkAsset.h | 5 +++- .../inkcpp/Source/inkcpp/Public/InkChoice.h | 5 +++- .../Source/inkcpp/Public/InkDelegates.h | 2 +- unreal/inkcpp/Source/inkcpp/Public/InkList.h | 24 ++++++++++++------- .../inkcpp/Source/inkcpp/Public/InkRuntime.h | 3 +++ .../inkcpp/Source/inkcpp/Public/InkSnapshot.h | 5 +++- .../inkcpp/Source/inkcpp/Public/InkThread.h | 5 ++-- unreal/inkcpp/Source/inkcpp/Public/InkVar.h | 14 ++++++++--- unreal/inkcpp/Source/inkcpp/Public/TagList.h | 3 ++- unreal/inkcpp/Source/inkcpp/Public/inkcpp.h | 9 ++++++- 12 files changed, 71 insertions(+), 23 deletions(-) diff --git a/Doxyfile b/Doxyfile index 01d852ac..615e3060 100644 --- a/Doxyfile +++ b/Doxyfile @@ -945,7 +945,8 @@ WARN_LOGFILE = INPUT = inkcpp/include \ shared/public \ - inkcpp_compiler/include + inkcpp_compiler/include \ + unreal/inkcpp/Source/inkcpp/Public/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -1446,7 +1447,7 @@ HTML_CODE_FOLDING = YES # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_INDEX_NUM_ENTRIES = 100 +HTML_INDEX_NUM_ENTRIES = 32 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development diff --git a/inkcpp/include/story.h b/inkcpp/include/story.h index 8d3e6706..060c4b17 100644 --- a/inkcpp/include/story.h +++ b/inkcpp/include/story.h @@ -86,6 +86,17 @@ namespace ink::runtime }; } +/** @namespace ink + * Namespace contaning all modules and classes from InkCPP + * + * (Unreal Blueprint Classes Excluded, but there will not be there in a normal build) + */ + +/** @namespace ink::runtime + * Contaning all modules and classes used for the inkles ink runtime. + * A minimal example can be found at @ref src_main + */ + /** @mainpage InkCPP Documentation * @tableofcontents * Inkle Ink C++ Runtime with INK.JSON -> Binary Compiler.
@@ -137,6 +148,9 @@ namespace ink::runtime * `win64-unreal.zip`).
Unpack this folder in `/PATH/TO/UNREAL_PROJECT/Plugins/` and it will be * intigrated at the next startup.
A MarketPlace appearance is work in progress :) * + * The overview to the UE Blueprint class can be found at @ref unreal "here". + * A more detailed explination with images in WIP. + * * If you want to use the newest version clone the project and install the unreal component. * @code {sh} * git clone https://github.com/JBenda/inkcpp diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h b/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h index 59b272d3..4c15448e 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h @@ -4,6 +4,9 @@ #include "InkAsset.generated.h" +/** Assets contanining a InkCPP .bin + * @ingroup unreal + */ UCLASS(hidecategories=Object) class INKCPP_API UInkAsset : public UObject { @@ -27,4 +30,4 @@ class INKCPP_API UInkAsset : public UObject virtual void GetAssetRegistryTags(TArray& OutTags) const override; // End UObject #endif -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h b/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h index 0a3c8aec..a7a3b868 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h @@ -9,6 +9,9 @@ namespace ink::runtime { class choice; } class UTagList; +/** Representing a Ink Choice in the story flow + * @ingroup unreal + */ UCLASS(BlueprintType) class UInkChoice : public UObject { @@ -32,4 +35,4 @@ class UInkChoice : public UObject private: const ink::runtime::choice* data; TObjectPtr tags; -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h b/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h index 94a4aa1c..1ca71094 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h @@ -21,4 +21,4 @@ UCLASS() class UFuckYou : public UObject { GENERATED_BODY() -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkList.h b/unreal/inkcpp/Source/inkcpp/Public/InkList.h index dc434476..0dea19b4 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkList.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkList.h @@ -7,6 +7,9 @@ namespace ink::runtime { using list = list_interface*; } +/** A single flag of a list + * @ingroup unreal + */ USTRUCT(BlueprintType) struct FListFlag { GENERATED_BODY() @@ -18,6 +21,7 @@ struct FListFlag { /** * Allowes reading ink lists. + * @ingroup unreal */ UCLASS(Blueprintable, BlueprintType) class INKCPP_API UInkList : public UObject @@ -31,32 +35,34 @@ class INKCPP_API UInkList : public UObject bool ContainsFlag(const FString& flag_name) const; UFUNCTION(BlueprintPure, Category = "Ink") - /// returns true if a flag with the same spelling then the enum `value` is set in the list + /** returns true if a flag with the same spelling then the enum `value` is set in the list + */ bool ContainsEnum(const FString& enumName, const uint8& value) const; UFUNCTION(BlueprintPure, Category = "Ink") - /// returns all values of a list with the same name as the enum + /** returns all values of a list with the same name as the enum + */ TArray ElementsOf(const FString& enumName) const; UFUNCTION(BlueprintPure, Category = "Ink") - /// returns all flag as string contained in the list from a list with the name `list_name` + /** returns all flag as string contained in the list from a list with the name `list_name` + */ TArray ElementsOfAsString(const FString& list_name) const; UFUNCTION(BlueprintPure, Category = "Ink") - /// returns all `list_name` `flag_name` toubples + /** returns all `list_name` `flag_name` toubples + */ TArray Elements() const; UFUNCTION(BlueprintPure, Category = "Ink") - /// check if at least one value of the given list is included, OR the list is empty - /// and assoziatet with the list + /** check if at least one value of the given list is included, OR the list is empty + * and assoziatet with the list */ bool ContainsList(const FString& name) const; private: friend struct FInkVar; ink::runtime::list GetData() const { return list_data; } - /// @TODO - ink::runtime::list list_data; -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h b/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h index a6da0389..e9f388b8 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h @@ -19,6 +19,9 @@ class UInkThread; struct FInkVar; namespace ink::runtime { class story; } +/** Instanciated story with global variable storage and access, used to instanciate new threads. + * @ingroup unreal + */ UCLASS() class INKCPP_API AInkRuntime : public AActor { diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h b/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h index abe3d61b..e635b31e 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h @@ -2,6 +2,9 @@ #include "InkSnapshot.generated.h" +/** A serelizable snapshot of a runtime state + * @ingroup unreal + */ USTRUCT(BlueprintType) struct INKCPP_API FInkSnapshot { @@ -11,4 +14,4 @@ struct INKCPP_API FInkSnapshot : data(snap_data, snap_len) {} TArray data; -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkThread.h b/unreal/inkcpp/Source/inkcpp/Public/InkThread.h index 076704d3..4704dcbc 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkThread.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkThread.h @@ -18,11 +18,10 @@ class UTagList; class AInkRuntime; class UInkChoice; -/** - * Base class for all ink threads +/** Base class for all ink threads + * @ingroup unreal */ UCLASS(Blueprintable) - class INKCPP_API UInkThread : public UObject { GENERATED_BODY() diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkVar.h b/unreal/inkcpp/Source/inkcpp/Public/InkVar.h index 49e5213d..e9b7b171 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkVar.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkVar.h @@ -12,8 +12,9 @@ #include "InkVar.generated.h" -// A wrapper for passing around ink vars to and from ink itself -// Not templated so it can be used in blueprints +/** Label for types possible contained in a @ref FInkVar + * @ingroup unreal + */ UENUM(BlueprintType) enum class EInkVarType : uint8 { @@ -28,6 +29,10 @@ enum class EInkVarType : uint8 namespace ink::runtime { struct value; } +/** A wrapper for passing around ink vars to and from ink itself + * Not templated so it can be used in blueprints + * @ingroup unreal + */ USTRUCT(BlueprintType) struct INKCPP_API FInkVar { @@ -80,6 +85,9 @@ struct INKCPP_API FInkVar } }; +/** Conversion Methods for @ref FInkVar + * @ingroup unreal + */ UCLASS() class INKCPP_API UInkVarLibrary : public UBlueprintFunctionLibrary { @@ -136,4 +144,4 @@ class INKCPP_API UInkVarLibrary : public UBlueprintFunctionLibrary // UFUNCTION(BlueprintPure, meta = (DisplayName = "Ink Var (UInt)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Ink") // static FInkVar Conv_UIntInkVar(unsigned Number); -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/TagList.h b/unreal/inkcpp/Source/inkcpp/Public/TagList.h index d77fe0fe..a05aa391 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/TagList.h +++ b/unreal/inkcpp/Source/inkcpp/Public/TagList.h @@ -7,6 +7,7 @@ /** * Helpful tag list + * @ingroup unreal */ UCLASS() class INKCPP_API UTagList : public UObject @@ -32,4 +33,4 @@ class INKCPP_API UTagList : public UObject private: TArray Tags; -}; \ No newline at end of file +}; diff --git a/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h b/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h index 19743cbb..2856c50c 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +++ b/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h @@ -2,4 +2,11 @@ #include "Logging/LogMacros.h" -DECLARE_LOG_CATEGORY_EXTERN(InkCpp, Log, All); \ No newline at end of file +/** + * @defgroup unreal Unreal Blueprints + * Blueprint Classes usable in Unreal. An example can be found [here](https://cloud.julian-benda.de/index.php/s/cRMBGBWbHPCcdwb) + * + * The C++ API will be available soon(TM). + */ + +DECLARE_LOG_CATEGORY_EXTERN(InkCpp, Log, All); From fc65f7e3aea4bd17276ec4ab1101e20574373c77 Mon Sep 17 00:00:00 2001 From: Julian Benda Date: Fri, 5 Jan 2024 17:28:51 +0100 Subject: [PATCH 11/11] format --- inkcpp/include/globals.h | 1 + inkcpp/include/story.h | 34 +++++++++---------- unreal/inkcpp/Source/inkcpp/Public/InkAsset.h | 2 +- unreal/inkcpp/Source/inkcpp/Public/InkList.h | 1 + unreal/inkcpp/Source/inkcpp/Public/inkcpp.h | 3 +- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/inkcpp/include/globals.h b/inkcpp/include/globals.h index 2f75ddce..c9ca1ab8 100644 --- a/inkcpp/include/globals.h +++ b/inkcpp/include/globals.h @@ -177,5 +177,6 @@ inline bool globals_interface::set(const char* name, const list& val) { return set_var(hash_string(name), value(val)); } + ///@} } // namespace ink::runtime diff --git a/inkcpp/include/story.h b/inkcpp/include/story.h index 060c4b17..16850680 100644 --- a/inkcpp/include/story.h +++ b/inkcpp/include/story.h @@ -4,22 +4,22 @@ namespace ink::runtime { - /** - * A loaded ink story. - * - * Created by loading a binary ink story into memory. Once loaded, - * the story class can create "runners" which execute story code. - * A story can have any number of runners, which can optionally - * share globals (variables, visit counts, etc). through the - * globals object. By default, each runner gets its own newly - * created globals store. - * @see runner_interface - * @see globals_interface - */ - class story - { - public: - virtual ~story(){}; +/** + * A loaded ink story. + * + * Created by loading a binary ink story into memory. Once loaded, + * the story class can create "runners" which execute story code. + * A story can have any number of runners, which can optionally + * share globals (variables, visit counts, etc). through the + * globals object. By default, each runner gets its own newly + * created globals store. + * @see runner_interface + * @see globals_interface + */ +class story +{ +public: + virtual ~story(){}; #pragma region Interface Methods /** * Creates a new global store @@ -83,7 +83,7 @@ namespace ink::runtime */ static story* from_binary(unsigned char* data, size_t length, bool freeOnDestroy = true); #pragma endregion - }; +}; } /** @namespace ink diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h b/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h index 4c15448e..ca449a3e 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h @@ -4,7 +4,7 @@ #include "InkAsset.generated.h" -/** Assets contanining a InkCPP .bin +/** Assets contanining a InkCPP .bin * @ingroup unreal */ UCLASS(hidecategories=Object) diff --git a/unreal/inkcpp/Source/inkcpp/Public/InkList.h b/unreal/inkcpp/Source/inkcpp/Public/InkList.h index 0dea19b4..164e617d 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/InkList.h +++ b/unreal/inkcpp/Source/inkcpp/Public/InkList.h @@ -62,6 +62,7 @@ class INKCPP_API UInkList : public UObject private: friend struct FInkVar; + ink::runtime::list GetData() const { return list_data; } ink::runtime::list list_data; diff --git a/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h b/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h index 2856c50c..0d5e1c6c 100644 --- a/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +++ b/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h @@ -4,7 +4,8 @@ /** * @defgroup unreal Unreal Blueprints - * Blueprint Classes usable in Unreal. An example can be found [here](https://cloud.julian-benda.de/index.php/s/cRMBGBWbHPCcdwb) + * Blueprint Classes usable in Unreal. An example can be found + * [here](https://cloud.julian-benda.de/index.php/s/cRMBGBWbHPCcdwb) * * The C++ API will be available soon(TM). */