From a26c19e6bf7f0d5ad8ed4048ca458cd91e87fe7d Mon Sep 17 00:00:00 2001 From: Christopher Denter Date: Tue, 11 Jan 2011 17:31:43 +0100 Subject: [PATCH] Docs: Begin architectural overview and add 'isnt python slow' FAQ entry --- doc/sources/architecture.rst | 124 +++++++++++++++++++++++++++++++++++ doc/sources/faq.rst | 54 +++++++++++++++ doc/sources/index.rst | 6 +- doc/sources/philosophy.rst | 21 +++--- 4 files changed, 193 insertions(+), 12 deletions(-) create mode 100644 doc/sources/architecture.rst diff --git a/doc/sources/architecture.rst b/doc/sources/architecture.rst new file mode 100644 index 000000000..fd93adde8 --- /dev/null +++ b/doc/sources/architecture.rst @@ -0,0 +1,124 @@ +Architectural Overview +====================== + +From a software engineering point of view, Kivy is a pretty well-designed product. +If you just look at the code, chances are you will get a rough idea already, but +since this approach certainly is daunting for most users, this section explains +the basic ideas of the implementation. + + +Core Providers and Input Providers +---------------------------------- + +One idea that is key to understanding Kivy's internals is that of modularity and +abstraction. We try to abstract from basic tasks such as opening a window, +displaying images and text, playing audio, getting images from a camera, +spelling correction and so on. We call these *core* tasks. +This makes the API both easy to use and easy to extend. Most importantly, it +allows us to use -- what we call -- specific providers for the respective +scenario in which your app is being run. +For example, on OSX, Linux and Windows, there are different native APIs for the +different core tasks. A piece of code that uses one of these specific APIs to +talk to the operating system on one side and to Kivy on the other (acting as an +intermediate communication layer) is what we call a *core provider*. +The advantage of using specialized core providers for each platform is that we +can fully leverage the functionality exposed by the operating system and act as +efficiently as possible. It also gives users a choice. Furthermore, by using +libraries that are shipped with any one platform, we effectively reduce the size +of the Kivy distribution and make packaging easier. It's also easier to port +Kivy to other platforms. The Android port did greatly benefit from this. + +We follow the same concept with input handling. *An input provider* is a piece +of code that adds support for a specific input device, such as Apple's +trackpads, TUIO or a mouse emulator. +If you need to add support for a new input device, you can simply provide a new +class that reads your input data from your device and transforms them into Kivy +basic events. + + +Input Events (Touches) +---------------------- + +Kivy abstracts from different input types and sources such as touches, mice, +TUIO or similar. What all of these input types have in common is that you +can associate a 2D onscreen-position with any individual input event. (There are +other input devices such as accelerometers where you cannot easily find a +2D position for e.g. a tilt of your device. This kind of input is handled +separately. In the following we describe the former types.) + +All of these input types are represented by instances of the Touch() +class. (Note that this does not only refer to finger touches, but all the other +input types as well. We just called it *Touch* for the sake of simplicity. +Think of it of something that *touches* the user interface or your screen.) +A touch instance, or object, can be in one of three states. When a touch +enters one of these states, your program is informed that the event +occurred. +The three states a touch can be in are: + + Down + A touch is down only once, at the very moment where it first + appears. + Move + A touch can be in this state for a potentially unlimited time. + A touch does not have to be in this state during its lifetime. + A 'Move' happens whenever the 2D position of a touch changes. + Up + A touch goes up at most once, or never. + In practice you will almost always receive an up event because + nobody is going to hold a finger on the screen for all eternity, + but it is not guaranteed. If you know the input sources your users + will be using, you will know whether or not you can rely on this + state being entered. + + +Widgets and Event Dispatching +----------------------------- + +The term *widget* is often used in GUI programming contexts to describe +some part of the program that the user interacts with. +For Kivy, a widget is an object that receives input events. It does not +necessarily have to have a visible representation on the screen. +All widgets are arranged in a *widget tree* (which is a tree data structure +as known from computer science classes): One widget can have any number of +child widgets or none. There is exactly one *root widget* at the top of the +tree that has no parent widget, and all other widgets are directly or +indirectly children of this widget (which is why it's called the root). + +When new input data is available, Kivy sends out one event per touch. +The root widget of the widget tree first receives the event. +Depending on the state of the touch, the on_touch_down, +on_touch_move or on_touch_up event is dispatched (with the touch as the +argument) to the root widget, which results in the root widget's +corresponding on_touch_down, on_touch_move or on_touch_up event handler +being called. + +Each widget (this includes the root widget) in the tree can choose to +either digest or pass the event further. If an event handler returns True +it means that the event has been digested and handled properly. No further +processing will happen with that event. Otherwise, the event handler +passes the widget on to its own children by calling its superclass's +implementation of the respective event handler. This goes all the way up +to the base Widget class, which -- in its touch event handlers -- does +nothing but pass the touches to its children:: + + def on_touch_down(self, touch): # This is the same for move/up + for child in reversed(self.children[:]): + if child.dispatch('on_touch_down', touch): + return True + +This really is much easier than it first seems. Let's take a look at a +simple example. If you want to implement a line drawing program, you will +want to know when a touch starts, moves and ends. You keep track of the +touch's positions and draw a line through those points:: + + TODO PAINTER WIDGET + +As you can see, this widget does not really care where the touch occurred. +Often times you will want to restrict the *area* on the screen that a +widget watches for touches. You can use a widget's collide_point() method +to achieve this. You simply pass it the touches position and it returns +True if the touch is within the 'watched area' or False otherwise. By +default, this checks the rectangular region on the screen that's described +by the widget's pos (for position; x & y) and size (width & height), but +you can override this behaviour in your own class. + diff --git a/doc/sources/faq.rst b/doc/sources/faq.rst index 5246d8264..3b243cf4a 100644 --- a/doc/sources/faq.rst +++ b/doc/sources/faq.rst @@ -1,6 +1,60 @@ Frequently Asked Questions ========================== +Why do you use Python? Isn't it slow? + Let us try to give a thorough answer; please bear with us. + + Python is a very agile language that allows you to do many things + in (by comparison) short time. + For many development scenarios, we strongly prefer writing our + application quickly in a high-level language such as Python, testing + it, then optionally optimizing it. + + But what about speed? + If you compare execution speeds of implementations for a certain set of + algorithms (esp. number crunching) you will find that Python is a lot + slower than say, C++. + Now you may be even more convinced that it's not a good idea in our + case to use Python. Drawing sophisticated graphics (and we are + not talking about your grandmother's OpenGL here) is computationally + quite expensive and given that we often want to do that for rich user + experiences, that would be a fair argument. + **But**, in virtually every case your application ends up spending + most of the time (by far) executing the same part of the code. + For Kivy for example, these parts are event dispatching and graphics + drawing. Now Python allows you to do something to make these parts + much faster. + + By using Cython, you can compile your code down to the C level, + and from there your usual C compiler optimizes things. This is + a pretty pain free process and if you add some hints to your + code, the result becomes even faster. We are talking about a speed up + in performance by a factor of anything in between 1x and up to more + than 1000x (greatly depends on your code). In Kivy, we did this for + you and implemented the portions of our code where efficiency really + is critical on the C level. + + For graphics drawing, we also leverage today's GPUs which are, for + some tasks such as graphics rasterization, much more efficent than a + CPU. Kivy does as much as is reasonable on the GPU to maximize + performance. If you use our Canvas API to do the drawing, there is + even a compiler that we invented which optimizes your drawing code + automatically. If you keep your drawing on the GPU mostly, + much of your program's execution speed is not determined by the + programming language used, but by the graphics hardware you throw at + it. + + We believe that these (and other) optimizations that Kivy does for you + already make most applications fast enough by far. Often you will even + want to limit the speed of the application in order not to waste + resources. + But even if this is not sufficient, you still have the option of using + Cython for your own code to *greatly* speed it up. + + Trust us when we say that we have given this very careful thought. + We have performed many different benchmarks and came up with quite + some clever optimizations to make your application run smoothly. + Does Kivy support Python 3.x? No. Not yet. Python 3 is certainly a good thing; However, it broke backwards compatibility (for good reasons) which means that some diff --git a/doc/sources/index.rst b/doc/sources/index.rst index 69dc7173c..aa564b246 100644 --- a/doc/sources/index.rst +++ b/doc/sources/index.rst @@ -6,17 +6,19 @@ development of applications equipped with novel user interfaces, such as multi-touch apps. You are probably wondering why you'd be interested in using Kivy. There is -a document outlining our :res:`philosophy` we encourage you to read. +a document outlining our :ref:`philosophy` we encourage you to read. We recommend that you get started with :ref:`installation` and then head over to the :ref:`quickstart` document. Besides the quickstart, there is also a more -detailed :ref:`tutorial` that shows how to create an application with Kivy. +detailed :ref:`architecture overview` and a :ref:`tutorial` that shows how to +create an application with Kivy. We also have a list of :ref:`frequently asked questions`. .. include:: philosophy.rst .. include:: faq.rst .. include:: guide-index.rst +.. include:: architecture.rst .. include:: api-index.rst Indices and tables diff --git a/doc/sources/philosophy.rst b/doc/sources/philosophy.rst index a52565286..d3d51a83a 100644 --- a/doc/sources/philosophy.rst +++ b/doc/sources/philosophy.rst @@ -14,7 +14,7 @@ these numerous solutions already support Multi-Touch. So what is it that makes Kivy special and worth using? - * **Fresh**: + Fresh Kivy is made for today and tomorrow. Novel input methods such as Multi-Touch become increasingly important. We created Kivy from scratch, specifically @@ -29,7 +29,7 @@ So what is it that makes Kivy special and worth using? possibilities. *This* is what really sets Kivy apart. - * **Fast**: + Fast Kivy is fast. This applies to both: *application development* and *application execution* speeds. We have optimized Kivy in many ways. We implement time-critical @@ -43,14 +43,14 @@ So what is it that makes Kivy special and worth using? That's why we try to let the GPU do as much of the work as possible, thus increasing performance considerably. - * **Flexible**: + Flexible Kivy is flexible. This means it can be run on *a variety of different devices*, including Android powered smartphones and tablets. We support *all major operating systems* (Windows, Linux, OS X). - This also means that Kivy's fast-paced development - allows it to *adapt to new technologies quickly*. More - than once have we added support for new external + Being flexible also means that Kivy's fast-paced development + allows it to *adapt to new technologies quickly*. + More than once have we added support for new external devices and software protocols; sometimes even before they were released. Lastly, Kivy is also flexible in that it is possible @@ -64,13 +64,14 @@ So what is it that makes Kivy special and worth using? In addition to that, we support TUIO and a number of other input sources. - * **Focused**: + Focused Kivy is focused. You can write a simple application with a few lines of code. Kivy programs are created by using the *Python* programming language, which is incredibly versatile, powerful yet easy to use. In addition, we created our own description language, - the *Kivy Language*, for creating sophisticated user interfaces. This + the *Kivy Language*, for creating sophisticated user + interfaces. This language allows you to set up, connect and arrange your application elements quickly. We feel that allowing you to focus on the essence of @@ -78,7 +79,7 @@ So what is it that makes Kivy special and worth using? fiddle with compiler settings. We took that burden off your shoulders. - * **Funded**: + Funded Kivy is actively developed by professionals in their field. Kivy is a community-influenced, professionally developed and commercially backed solution. Some of @@ -86,7 +87,7 @@ So what is it that makes Kivy special and worth using? Kivy is here to stay. It's not a small, vanishing student project. - * **Free**: + Free Kivy is free to use. You don't have to pay for it. You don't even have to pay for it if you're making money out of selling an application that uses Kivy.