aboutsummaryrefslogtreecommitdiff
path: root/docs/designDocs.tex
blob: 8e62edc24b6e6909a5a8bad95d58c1b6db17cc6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
\documentclass{article}
\usepackage{fullpage}
\begin{document}
    \title{150 Smoots Lighting Installation Design Document}
    \author{Russell Cohen}
    \date{\today}
    \maketitle
    \newcommand{\classDoc}[5]{
        \subsection{#1}
            \begin{itemize}
            \item \textbf{Inherits from: } #2 
            \item \textbf{Inherited by: } #3 
            \item \textbf{Brief Description: } #4 
            \item \textbf{Argument Requirements: } #5
            \end{itemize}
        }
    \section{Intro}
        \textbf{NB: These docs give an overview of the classes and methods but
            may lag behind the code for certain in-flux functionality.  For
                up-to-the minute docs, please use pydoc.} \\
        The system, which we will describe henceforth as SmootLight is a
        modular system designed with the following goals in mind:
        \begin{itemize} 
            \item The system must abstract away from all components while
            remaining useful (\verb=Renderer=, \verb=Input=, \verb=Behavior=) 
            \item The system must be modular and be easy to write new code for.
            \item More goals as I think of them
        \end{itemize}
        We accomplish this in the following manner:
        \begin{itemize}
            \item The system is configured by an XML file which specifies its
            components.
            \item All classes are initialized with a dictionary as an argument
                containing anything a class may need.  All objects are passed
                between members as python dictionaries because their easy
                serialization.
        \end{itemize}
    \section{Overview}
        \begin{itemize}
            \item
    \section{Operations Class Patterns}
    \classDoc{SmootCoreObject}{None}{All 2nd level classes (PixelAssembler, Renderer,
                Input, Behavior)}
    {SmootCoreObject is essentially a super-object
            that makes things easy for us.  It does the following actions:
                \begin{itemize}
                    \item Defines a constructor that sets argDict
                    \item Defines a \texttt{\_\_getitem\_\_} , which lets us acces items in
                    argDict as if the class was a dictionary.
                    (\texttt{self['itemName']}).  It also automatically maps the
                    initial contents of the argDict to class attributes.
                    \item Defines validateArgs and validateArgDict which
                    validate the incoming arguments against a dictionary
                    containing argument names as keys and an error message to
                    display if they are missing as a values.  This file should
                    be named classname.params and look like a python dict
                    (\texttt{\{'key':value, 'key2':value2\}} )
                \end{itemize}
            Note that at this point, the only class using this functionality
                is the PixelEvent class.}
            {No required parameters in argDict}
    \classDoc{PixelAssembler}{SmootCoreObject}{LineLayout, ZigzagLayout}{
        PixelAssembler is a class that defines the positions of lights.  It
            provides a method \texttt{getLightLocations} which give a list of
            all light locations for a given strip.  Inheriting classes must
            define \texttt{layoutFunc} which returns the next location given the
            previous location.  (They may simply override
                    \texttt{getLightLocations}
                    instead, if they wish, but be careful when doing so).  In
            heriting classes may defint \texttt{initLayout} which is called at
            initialization.}{\begin{itemize}
                \item \texttt{lightToLightSpacing}: this is the length of wire
                    between 2 adjacent LEDs.  Common values are 4 or 12.
                \item \texttt{numLights}: Number of lights in a strip.
                \item \texttt{originLocation}: Location of the first light.
                \end{itemize}}
    \classDoc{Renderer}{SmootCoreObject}{PygameRenderer, IndoorRenderer}{
        Renderer is a class that serves as an abstract class for renderers
            interacting with the system.  Inheriting classes must define
            render, which is passed a \texttt{lightSystem} object.  Inheriting
            classes may define initRenderer which is called on initiation.
    }{No required arguments}
    \classDoc{Input}{SmootCoreObject, threading.Thread}{PygameInput,
        TCPInput,UDPInput}{Input is a abstract class which facilitates Inputs.
            It does this by providing a method that is polled at a periodic
                interval within which the inheriting class can raise an event.
                Inheriting classes must define \texttt{sensingLoop} which is
                called at the interval specified in the config.  Inheriting
                classes should call respond with an dictionary as an argument
                to raise an event.  Classes using (not
                        inheriting) input must pass a scope into
        the argDict which offers a \texttt{processInput}
            method.  Inputs are marked as Daemon threads, and
                are therefore killed when their parent is
                killed.}{\begin{itemize}
                    \item \texttt{InputId}: The string id of a given input.  Must be
                        unique.
                    \item Optional:\texttt{RefreshInterval}: The interval in
                    seconds (will soon be changed to milliseconds) between
                    sucessive calls to the sensingLoop method.  TODO: make
                    timeout.
                \end{itemize}}
    \classDoc{Behavior}{SmootCoreObject}{EchoBehavior, DebugBehavior}{
Abstract class for a behavior.  On every time step, the behavior is passed the
inputs from all sensors it is bound to as well as any recursive inputs that it
spawned during the last time step.  Inheriting classes MUST define
\texttt{processBehavior}.  \texttt{processBehavior} should return a list of dictionaries which
define the properties of the light response.  The must return a location
\texttt{PixelEvent} class.  Soon be be deprecated:\textit{They must give a location and
color.  They may define a function pointer which defines a custom mapping.
[More on this later.  Bug Russell if you want to do it].}
Call \texttt{recursiveResponse} to queue a input on the next iteration with a dictionary
argument.  This will be passed in via recursive inputs.}
{\begin{itemize}
    \item \texttt{Inputs}: A list of input Ids specifying input to the
        behavior.  In the future, this may also contain behavior ids.
\end{itemize}}
\classDoc{PixelEvent}{SmootCoreObject}{StepResponse}{
    Abstract class defining the behavior of a light after it has been turned on.
        Inheriting classes should defint \texttt{lightState} which is passed a
        timeDelay in ms as an argument.  \texttt{lightState} should return a
        color or None if the response is complete.}{\begin{itemize}
            \item \texttt{Color}: The color of response.  \textit{This is may be
                removed in the future}
            \end{itemize}
        }
\section{The Screen Class and Its Relatives}
\classDoc{Screen}{None}{None}
{The \texttt{Screen} class is a representation of an entire system of pixels,
    distributed over space.  The Screen class and its relatives process
        responses (mapped to pixels via a LayoutEngine), and add PixelEvents
        to the individual pixels.  The Screen provides an instance that
        renderers can call to determine the color of all the individual pixels. It contains a list of PixelStrips, which each
        address the individual pixels.  \texttt{Screen} offers a
        \texttt{respond} method which takes a dictionary containing information
        about a response.  TODO: detail the contents of this dictionary (maybe
                somewhere else).  Note: \texttt{Screen} will not process its
        responses until \texttt{timeStep} is called which processes all responses that
        have been queued since the last time that \texttt{timeStep} was
        called.  Screen also offers an iterator over \textit{all} lights,
    accesible by using an expression like: \texttt{for light in screen:}.  For
        addressing of specific \texttt{PixelStrips} , \texttt{self.pixelStrips}
    is exposed.}{No required parameters}
\classDoc{PixelStrip}{None}{None}
{The \texttt{PixelStrip} class is a representation of a string of Pixels that are
    connected in physical space (eg. a strip of lights).  A \texttt{PixelStrip} takes a
        \texttt{LayoutBuilder} (\textit{Name up for debate, currently known as layout
            engine}) as an argument.  The \texttt{argDict} of the
        \texttt{LayoutBuilder} is
        passed becomes the \texttt{argDict} of the \texttt{PixelStrip}.
        \texttt{PixelStrip} generally shouldn't be
        adressed directly unless you need Strip-Identification for rendering
        purposes.  You should never, for example, call \texttt{respond} on a
        \texttt{PixelStrip}
        directly, unless you really know what you're doing.  Well, actually you
            should never need to do that.
        never.  Don't do it.}{Takes a \texttt{LayoutBuilder} as an argument.}
    \section{Best Practices}
        \subsection{Variable and function naming}
            I'm pretty bad about being consistent.  However, in all future
            code, please adhere to the following:
            \begin{itemize}
                \item Classes: \texttt{FirstLetterCaps}
                \item Functions: \texttt{camelCase}
                \item Property Names: \texttt{FirstLetterCaps}
                \item Constants: \texttt{ALL\_CAPS\_WITH\_UNDERSCORES}
            \end{itemize}
        \subsection{Time}
            For time, use the \texttt{util.TimeOps.time()} method to return the current
            time in ms.
        \subsection{Acessing a Component Given an Id}
            Use \texttt{util.ComponentRegistry.getComponent(id)}.  This provides any
            component access to any other components.  We may consider a way to
            make this read-only.
        \subsection{Acessing Pixels}
            The ideal method for acessing Pixels in a screen is to use its
            iterator.  Iterating over the individual PixelStrips is also an
            acceptable method.  
        \subsection{Determining the state of a \texttt{Pixel}}
            The best practice for determining the color of a \texttt{Pixel} is to call
            \texttt{state}.  This ensures
            all current active responses running on the Pixel contribute correctly. 
        \subsection{Color}
            For color, use a tuple of (R,G,B) 0-255 for each.  Colors can be
            easily manipulated with members of the Util class.
        \subsection{Locations}
            Locations are stored (x,y), in whatever unit you light system is
            in.  (Whatever unit you use when you define spacing).
        \subsection{Constant Strings (key strings, 'Location', 'Color', etc.)}
            Use the util.Strings module.  It contains many currently in use
            Strings, and ensures consistency. 
    \end{document}