Commits

rkruppe committed f0a092d

Remove doc, mostly broken and outdated, the few good parts can be salvaged later

Comments (0)

Files changed (6)

doc/Makefile

-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html       to make standalone HTML files"
-	@echo "  dirhtml    to make HTML files named index.html in directories"
-	@echo "  singlehtml to make a single large HTML file"
-	@echo "  pickle     to make pickle files"
-	@echo "  json       to make JSON files"
-	@echo "  htmlhelp   to make HTML files and a HTML help project"
-	@echo "  qthelp     to make HTML files and a qthelp project"
-	@echo "  devhelp    to make HTML files and a Devhelp project"
-	@echo "  epub       to make an epub"
-	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-	@echo "  text       to make text files"
-	@echo "  man        to make manual pages"
-	@echo "  texinfo    to make Texinfo files"
-	@echo "  info       to make Texinfo files and run them through makeinfo"
-	@echo "  gettext    to make PO message catalogs"
-	@echo "  changes    to make an overview of all changed/added/deprecated items"
-	@echo "  linkcheck  to check all external links for integrity"
-	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-	-rm -rf $(BUILDDIR)/*
-
-html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
-	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-	@echo
-	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files."
-
-json:
-	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-	@echo
-	@echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-	@echo
-	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
-	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Tutagx.qhcp"
-	@echo "To view the help file:"
-	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Tutagx.qhc"
-
-devhelp:
-	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-	@echo
-	@echo "Build finished."
-	@echo "To view the help file:"
-	@echo "# mkdir -p $$HOME/.local/share/devhelp/Tutagx"
-	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Tutagx"
-	@echo "# devhelp"
-
-epub:
-	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-	@echo
-	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-	@echo "Run \`make' in that directory to run these through (pdf)latex" \
-	      "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo "Running LaTeX files through pdflatex..."
-	$(MAKE) -C $(BUILDDIR)/latex all-pdf
-	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
-	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-	@echo
-	@echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
-	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-	@echo
-	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo
-	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-	@echo "Run \`make' in that directory to run these through makeinfo" \
-	      "(use \`make info' here to do that automatically)."
-
-info:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo "Running Texinfo files through makeinfo..."
-	make -C $(BUILDDIR)/texinfo info
-	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
-	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-	@echo
-	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-	@echo
-	@echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-	@echo "Testing of doctests in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/doctest/output.txt."

doc/api/tutagx.nsgui.rst

-nsgui Package
-=============
-
-:mod:`button` Module
---------------------
-
-.. automodule:: tutagx.nsgui.button
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`driver` Module
---------------------
-
-.. automodule:: tutagx.nsgui.driver
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`frame` Module
---------------------
-
-.. automodule:: tutagx.nsgui.frame
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`label` Module
---------------------
-
-.. automodule:: tutagx.nsgui.label
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`style` Module
---------------------
-
-.. automodule:: tutagx.nsgui.style
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`util` Module
---------------------
-
-.. automodule:: tutagx.nsgui.util
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`widget` Module
---------------------
-
-.. automodule:: tutagx.nsgui.widget
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
-:mod:`window` Module
---------------------
-
-.. automodule:: tutagx.nsgui.window
-    :members:
-    :undoc-members:
-    :show-inheritance:
-

doc/conf.py

-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# Tutagx documentation build configuration file, created by
-# sphinx-quickstart on Sat Apr  7 10:06:46 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys
-import os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = 'Tutagx'
-copyright = '2012, Robin Kruppe'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '0.0.1'
-# The full version, including alpha/beta/rc tags.
-release = '0.0.1'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Tutagxdoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'Tutagx.tex', 'Tutagx Documentation',
-   'Robin Kruppe', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'tutagx', 'Tutagx Documentation',
-     ['Robin Kruppe'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-#  dir menu entry, description, category)
-texinfo_documents = [
-  ('index', 'Tutagx', 'Tutagx Documentation',
-   'Robin Kruppe', 'Tutagx', 'One line description of project.',
-   'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'http://docs.python.org/': None}
-
-# -- Options for extensions ------------------------------------------------
-
-# generally include TODOs
-todo_include_todos = True

doc/index.rst

-Welcome to Tutagx's documentation!
-===================================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   model
-
-
-.. seealso:: :ref:`modindex`

doc/make.bat

-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
-	set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
-	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
-	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
-	:help
-	echo.Please use `make ^<target^>` where ^<target^> is one of
-	echo.  html       to make standalone HTML files
-	echo.  dirhtml    to make HTML files named index.html in directories
-	echo.  singlehtml to make a single large HTML file
-	echo.  pickle     to make pickle files
-	echo.  json       to make JSON files
-	echo.  htmlhelp   to make HTML files and a HTML help project
-	echo.  qthelp     to make HTML files and a qthelp project
-	echo.  devhelp    to make HTML files and a Devhelp project
-	echo.  epub       to make an epub
-	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
-	echo.  text       to make text files
-	echo.  man        to make manual pages
-	echo.  texinfo    to make Texinfo files
-	echo.  gettext    to make PO message catalogs
-	echo.  changes    to make an overview over all changed/added/deprecated items
-	echo.  linkcheck  to check all external links for integrity
-	echo.  doctest    to run all doctests embedded in the documentation if enabled
-	goto end
-)
-
-if "%1" == "clean" (
-	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
-	del /q /s %BUILDDIR%\*
-	goto end
-)
-
-if "%1" == "html" (
-	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
-	goto end
-)
-
-if "%1" == "dirhtml" (
-	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
-	goto end
-)
-
-if "%1" == "singlehtml" (
-	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
-	goto end
-)
-
-if "%1" == "pickle" (
-	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished; now you can process the pickle files.
-	goto end
-)
-
-if "%1" == "json" (
-	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished; now you can process the JSON files.
-	goto end
-)
-
-if "%1" == "htmlhelp" (
-	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
-	goto end
-)
-
-if "%1" == "qthelp" (
-	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
-	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Tutagx.qhcp
-	echo.To view the help file:
-	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Tutagx.ghc
-	goto end
-)
-
-if "%1" == "devhelp" (
-	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished.
-	goto end
-)
-
-if "%1" == "epub" (
-	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The epub file is in %BUILDDIR%/epub.
-	goto end
-)
-
-if "%1" == "latex" (
-	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
-	goto end
-)
-
-if "%1" == "text" (
-	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The text files are in %BUILDDIR%/text.
-	goto end
-)
-
-if "%1" == "man" (
-	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The manual pages are in %BUILDDIR%/man.
-	goto end
-)
-
-if "%1" == "texinfo" (
-	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
-	goto end
-)
-
-if "%1" == "gettext" (
-	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
-	goto end
-)
-
-if "%1" == "changes" (
-	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.The overview file is in %BUILDDIR%/changes.
-	goto end
-)
-
-if "%1" == "linkcheck" (
-	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
-	goto end
-)
-
-if "%1" == "doctest" (
-	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
-	if errorlevel 1 exit /b 1
-	echo.
-	echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
-	goto end
-)
-
-:end

doc/model.rst

-=======================
-Data Modeling Overview
-=======================
-
-Sooner or later, data needs to be serialized.
-Serialization in general is a solved problem, without doubt.
-However, a game like this has additional needs:
-
-- All data should be human-readable and easy to edit.
-  This requires a great deal of control over the resulting data.
-  Most general-purpose serialization is either:
-
-  1. far too limited to be useful (sometimes only a handful of primitive types can be stored), or
-  2. far too general to be human-readable and -editable.
-     Some serializers handle arbitrary untyped object graphs, leading to lots of overhead (e.g. embedded metadata).
-     Such metadata distracts human readers and is easy to break during editing.
-
-- Externally-developed tools should be able to read, edit and write the data.
-  This restricts the output format to a handful of widely-supported formats that can be parsed by many languages.
-  XML, JSON and YAML come to mind; at most one or two others exist.
-  SQL data bases (SQLite?) may be another option, but seem overkill for this purpose.
-  And in any case, the question remains: How do those tools learn about the schema?
-
-- It should be possible to migrate serialized data between versions.
-  Obviously, some human guidance is necessary and not all changes can be redeemed.
-  But it would be great if adding an attribute with a sensible default value wouldn't break all game sets.
-
-- It would be cool if we could re-use the model declaration to do whatever the hell is necessary.
-  For instance, one could generate a game set editor GUI.
-  This would also allow doing any of the above -- and further customizations -- manually, should the need arise.
-
-To the best of my (rkruppe's) knowledge, there is no Python library which satisfies all these needs.
-There are ORMs which come close in openness and flexibility of the serialized data.
-However, there are several problems with those:
-
-- They are tailored towards relational data bases.
-  There's no XML or JSON output, except maybe through the DB.
-  (But the result of *that* is unlikely to be really useful.)
-  The DB focus also influences the model descriptions, polluting our nice little OO world with keys, queries and the like.
-
-- The primary mode of operation seems to be: load a few objects, modifying them, and put them back.
-  Aside from the time and space overhead, this may make game code even more complex.
-  While having a live database may have advantages, it seems like overkill for a small game like this.
-  There won't be gigabytes of data (and if it does pop up, one can still add a DB for that subset of the models) that would benefit from on-disk storage.
-
-- They may require some help with detecting changes that don't happen through attribute assignment on the modeled object, e.g. changing a list member.
-  This may end up polluting code that doesn't really care about the persistent storage.
-  It may even leak into scripts, which would be a major annoyance and a seriously leaking abstraction.
-
-- I'm not aware of officially supported ways to re-use the model definitions.
-  Of course that's rarely needed -- but as outlined above, this is an exceptional case.
-  There are several things one cannot expect from a ready-made library that we'd want to add anyway.
-
-Lacking really good existing options, we re-invent the wheel... slightly differently.
-We place restrictions as needed and possibly require annotations beyond the mere basics.
-In particular, we enforce moderately static typing and disallow subtyping.
-
-Progress
---------
-
-What's been done so far indicates that all of the above goals can be fulfilled with acceptable work.
-Some are already fulfilled, and other areas never thought of before have already benefited from this approach.
-
-- Model definitions are turned into serialization code that produces very predictable and readable YAML output.
-  Appropriate deserialization code is, of course, generated as well.
-
-- The code generated for the aforementioned purposes is simple and only depends on a few basic data structures.
-  It could easily be adapted to other programming languages and serialization formats. [#]_
-  Those languages obviously wouldn't get the full Python objects back, but at least get the equivalent data reliably.
-
-- There is decent infrastructure in place for whipping up any number of further metaprograms guided by model definitions.
-  Reliable, moderately declarative code generation based on models, as well as more general traversals, are supported.
-  These have been put to use in numerous other passes, including:
-
-  - A rather detailed verification pass (including *great* error messages) for YAML files.
-
-  - Passes collecting reachable objects and used types (basis for the following).
-
-  - A tool for detecting unused objects in serialized data.
-
-  - A mixin which automatically splits serialized data into multiple files, for easier reading and editing.
-
-.. warning::
-
-    Such tasks are inherently nontrivial, and are made more bearable by some metaprogramming.
-    Most of the files in :mod:`tutagx.meta` are **not** for the faint of heart.
-    Solid knowledge of recursion (in particular depth-first traversal), trees and (cyclic) graphs is recommended.
-    Anyone diving into into the code generators (and their base class in :mod:`tutagx.meta.common`) also ought to be comfortable with code generation.
-
-.. [#] An early prototype generated JSON rather than YAML.
-       To this day, we still restrict ourselves to JSON features, i.e. only numbers, strings, arrays and dictionaries are used.
-       Therefore, JSON output could be re-introduced easily, a matter of hours.
-       Doing so has no readability benefits, but it may ease things for languages without decent YAML parser.
-
-Object IDs: Handling Cycles & Sharing
--------------------------------------
-Consider a mutable object holding some data - we'll call it ``cell``.
-Now consider two separate objects (mutators), both holding a reference to this ``cell``.
-If one mutator updates ``cell``'s value, the other mutator sees the new value.
-Now we serialize some data, and in the process encounter both mutator objects (and thus ``cell`` too, as they hold a reference to it).
-If we simply store ``cell`` again each time we encounter it, we'd store ``cell`` twice.
-Deserialization then results in two separate ``cell`` objects.
-The object graph, and thus the program's behavior, would be different - updates by one mutator are no longer visible to the other.
-
-Clearly, this sudden change of behavior is unacceptable.
-And there's another problem.
-Cyclic references [#]_ would lead to infinite data being generated (or, more likely, a stack overflow) - equally unacceptable.
-
-Therefore, every object must be stored exactly once.
-To this end, there is a unique "object ID" which is used to identify multiple uses of the same object.
-To ease editing of files, and to ease separating the data into multiple files, this ID must persist across multiple de-/serializations.
-The ID should be a string and mutable, to make the serialization output potentially [#]_ more human-readable.
-
-During serialization, the object ID is stored along with the actual value.
-If a second reference to the object is encountered, only the object ID is stored.
-Deserialization does the reverse: If an object ID instead of a full object is encountered, a reference to the already-loaded object is created.
-Multiple serialization passes (of either serialization or deserialization) may go hand in hand via a so-called "namespace" object.
-This object holds all information needed to not process objects already processed before.
-
-Modeling cyclic types is also an issue - one cannot simply store the classes if both classes refer to each other. [#]_
-It is resolved through the Ref model type, which represents a user-defined model type but only holds that class's *name* and module name.
-Therefore, it is possible to do tricks like self- and cyclic references.
-By the time the ``Ref`` is followed (e.g. for creating serialization code), the class must already be defined (not a problem in general).
-
-.. [#] As an example: Aircraft hold a reference to their home base and bases store a list of aircrafts based there.
-.. [#] The default IDs are UUIDs -- not very readable, but they avoid collisions.
-.. [#] This specific problem *could* be solved by making the model types (temporarily) mutable or allowing the addition of members after class definition.
-       However, doing so introduces many other problems, gotchas, potential bugs, etc. and requires extra work.
-       It also becomes harder to use types in dictionaries and sets (done under the hood, to great effect).
-
-Value Types
------------
-Python has reference types [#]_ only, and in theory that's is sufficient.
-But it is occasionally useful to treat a user-defined class as value type [#]_.
-By restricting it to be reachable through only one object, we can associate instances of value types with exactly one other object, its "parent".
-This additional knowledge can be used to very desirable ends:
-
-- The serialization output for for value type objects can be simpler and more readable.
-  All data is put directly inside the parent's serialization output, even when objects are split across files.
-- There is *never* a need to go by the object ID, and it is thus omitted.
-  Thus there are fewer IDs to remember and follow, both for the computer and for humans fiddling with the on-disk data.
-
-Conceptually, another object just contains the objects of some value type *immediately*, without indirection.
-Lacking value types altogether, Python allows us to construct objects which violate this property.
-In that case, the serialization code should reject them.
-
-All user-defined classes can be value types, though they are reference types by default.
-Making a model a value type requires a class-level constant::
-
-  is_value_type = True
-
-.. [#] Types whose instances are only ever accessed through an indirection (e.g. reference).
-.. [#] Types whose instances are stored directly inside another object.
-
-The "Data Model"
-----------------
-
-If you've given static type systems and object relationships a bit of thought, you may realize that modeling a reasonable range of data requires a few types:
-
-- Several atomic data types such as integers (``Integer(min, max)``), floating point numbers (``Float(min, max)``) and strings (``String()``).
-
-- A few basic types of collection:
-
-  - Homogeneous [#]_ arrays.
-    This is implemented by ``List(item_type)``.
-  - Homogeneous mappings [#]_ from one type to another.
-    This is implemented by `Dict(key_type, value_type)`.
-    (Note that in Python, lists and dictionaries don't work as dictionary keys.)
-
-- Compound data types, or records, which have a name and heterogeneous [#]_ members.
-  The members are an ordered collection of (identifier, type) pairs.
-  This is implemented by ``Record(('attr1', type1), ('attr2', type2), ..., name='MyRecord')``.
-  The name is usually taken into account, but may be dropped.
-
-- References to other objects.
-  These connect user-defined classes and allow all kinds of sharing, cyclic reference and self-reference.
-  Objects of a reference type are accessed exclusively through references and may be reachable from many different objects.
-  Every user-defined model is a reference type by default.
-  This is implemented by ``Ref(model_cls)`` and ``Ref(class_name, module_name)`` (avoid the latter whenever possible).
-
-- For consistency with ``Ref`` and to catch errors, there is another type which is to value types as ``Ref`` is to reference types.
-  ``Value(model_cls)`` accepts a model class marked as value type and represents values of a certain type contained directly [#]_ in the object.
-
-.. [#] Composed of objects of a single type.
-.. [#] Both keys and values are taken to be homogeneous.
-.. [#] Composed of objects of potentially different types.
-.. [#] Unlike ``Ref``, which may have to handle cyclic references, ``Value`` always requires an already-constructed class.
-       This rules out cycles of value types and keeps both internals and the public interface simpler.
-       It also prevents some errors that ``Ref`` cannot catch at model definition time, such as referring to non-existing types (typos).
-
-Defining Models
----------------
-
-Basically, you inherit from ``tutagx.meta.model.Model`` or any other "model base".
-Currently, there is only one other model base, in :mod:`tutagx.model.entity`.
-This one is specialized for entities that occur in the game and belong to :class:`tutagx.model.context.GameContext`.
-
-All members are defined in ORM-style [#]_ by creating class-level objects representing types::
-
-    class Foo(model.Model):
-        num = model.Integer()
-        names = model.List(model.String())
-        # Ref to class Foo in this module - i.e. self-reference
-        another_foo = Ref('Foo', __name__)
-
-        ORDINARY_CONSTANT = ...
-
-
-    class Bar(model.Model):
-        foos = model.Dict(model.Float(), model.Ref(Foo))
-
-        def ordinary_method(self, ...):
-            ...
-
-Referring to a user-defined value type, be it as member of another
-user-defined class or for some built-in container type (e.g. List)
-requires an explicit annotation, either:
-
-- ``Ref(cls)`` or ``Ref(clsname, modulename)`` for reference types, or
-- ``Value(cls)`` for value types.
-
-Passing a reference type to ``Value``, and vice versa, is considered an error.
-This is intended to make the distinction more apparent and minimize bugs.
-For instance, it prevents two model definitions from disagreeing about the "kind" of a user-defined class.
-Sadly, this can't be checked immediately for ``Ref(clsname, modulename)``.
-Whether the referred-to type is a value type is only checked at the time the ``Ref`` is "dereferenced" by some visitor examining the model type.
-Therefore, this way of constructing references should be avoided whenever possible.
-
-The intended semantics for serialization are as follows:
-
-- ``Ref`` members are either stored as object ID or object ID along with the object's value.
-  If an object is reachable through multiple objects, the value should be stored at most once.
-  The object ID alone should be stored in all other places.
-- ``Value`` members are stored just "by value", without object ID.
-  In fact, the default implementation of ``object_id`` will refuse to work with value types.
-  Objects of value types reachable through more than one objects should raise an exception.
-
-.. [#] This is implemented by `metaclass magic <http://pyvideo.org/video/877/introduction-to-metaclasses>`_, in case you wonder.
-       Magic that is hopefully well-justified here.
-       At least the Django ORM uses a superficially similar model definition (and was, in fact, the inspiration).
-       Coincidentally, it is also implemented using metaclasses.
-
-Restrictions
-------------
-
-- No ``__init__`` method can be defined.
-  Instead, two hooks are provided:
-
-  - ``_pre_init``, which is called when the object is first constructed.
-    Due to the nature of deserialization, this may be long before any attributes were loaded.
-    Thus, only basic/preliminary initialization should be done here.
-  - ``_on_loaded``, which is called when the object is fully loaded.
-    Thus, the object is complete and most initialization should happen here.
-
-- Models cannot inherit from other models (non-model mixins are fine though).
-  This may be alleviated in the future by allowing some kind of mixins.
-  Implementation inheritance, and any kind of polymorphism, is very much out of question though, at least in the near future.
-  It's just hard to reconcile with the on-disk storage which only records attributes, not types.
-  Tagged unions [#]_ may provide a good alternative later.
-
-.. todo:: I think there are several other restrictions.
-
-.. [#] A value wrapping values of multiple types.
-       Which one is actually present is determined by a *tag* (similar to an ``enum``).
-