Revamping of the docs organisation for a more coherent TOC

Only the pages were moved so far and some empty ones created,
the up-to-date toctrees come in the next commit.

(cherry picked from commit b408bdb918)
This commit is contained in:
Julian Murgia
2017-03-29 13:59:20 +02:00
committed by Rémi Verschelde
parent 6a730cb057
commit 5e05011eae
148 changed files with 0 additions and 376 deletions

View File

@@ -0,0 +1,183 @@
.. _doc_configuring_an_ide:
Configuring an IDE
==================
We assume that you already `cloned <https://github.com/godotengine/godot>`_
and :ref:`compiled <toc-compiling>` Godot.
Kdevelop
--------
It is a free, open source IDE (Integrated Development Environment)
for Linux, Solaris, FreeBSD, Mac OS X and other Unix flavors.
You can find a video tutorial `here <https://www.youtube.com/watch?v=yNVoWQi9TJA>`_.
Or you may follow this text version tutorial.
Start by opening Kdevelop and choosing "open project".
.. image:: /img/kdevelop_newproject.png
Choose the directory where you cloned Godot.
.. image:: /img/kdevelop_openproject.png
For the build system, choose "custom build system".
.. image:: /img/kdevelop_custombuild.png
Now that the project has been imported, open the project configuration.
.. image:: /img/kdevelop_openconfig.png
Add the following includes/imports:
::
. // a dot to indicate the root of the Godot project
core/
core/os/
core/math/
tools/
drivers/
platform/x11/ // make that platform/osx/ is you're using OS X
.. image:: /img/kdevelop_addincludes.png
Apply the changes then switch to the "Custom Buildsystem" tab.
Leave the build directory blank. Enable build tools and add ``scons``
as the executable and add ``platform=x11 target=debug`` (``platform=osx``
if you're on OS X).
.. image:: /img/kdevelop_buildconfig.png
Next we need to tell KDevelop where to find the binary.
From the "run" menu, choose "Configure Launches".
.. image:: /img/kdevelop_configlaunches.png
Click "Add new" if no launcher exists. Then add the path to your
executable in the executable section. Your executable should be located
in the ``bin/`` sub-directory and should be named something like
``godot.x11.tools.64`` (the name could be different depending on your
platform and depending on your build options).
.. image:: /img/kdevelop_configlaunches2.png
That's it! Now you should be good to go :)
Eclipse
-------
TODO.
QtCreator
---------
Importing the project
^^^^^^^^^^^^^^^^^^^^^
- Choose *New Project* -> *Import Project* -> *Import Existing Project*.
- Set the path to your Godot root directory and enter the project name.
- Here you can choose which folders and files will be visible to the project. C/C++ files
are added automatically. Potentially useful additions: \*.py for buildsystem files, \*.java for Android development,
\*.mm for OSX. Click "Next".
- Click *Finish*.
- Add a line containing ``.`` to *project_name.includes* to get working code completion.
Build and run
^^^^^^^^^^^^^
Build configuration:
- Click on *Projects* and open the *Build* tab.
- Delete the pre-defined ``make`` build step.
- Click *Add Build Step* -> *Custom Process Step*.
- Type ``scons`` in the *Command* field.
- Fill the *Arguments* field with your compilation options. (e.g.: ``p=x11 target=debug -j 4``)
Run configuration:
- Open the *Run* tab.
- Point the *Executable* to your compiled Godot binary (e.g: ``%{buildDir}\bin\godot.windows.tools.64.exe``)
- If you want to run a specific game or project, point *Working directory* to the game directory.
- If you want to run the editor, add ``-e`` to the *Command line arguments* field.
Xcode
-----
Project Setup
^^^^^^^^^^^^^
- Create an |xcode external build| project anywhere
- Set the *Build tool* to the path to scons
Modify Build Target's |xcode Info Tab|:
- Set *Arguments* to something like: platform=osx tools=yes bits=64 target=debug
- Set *Directory* to the path to Godot's source folder. Keep it blank if project is already there.
- You may uncheck *Pass build settings in environment*
Add a Command Line Target:
- Go to |xcode File > New > Target...| and add a new |xcode command line target|
- Name it something so you know not to compile with this target
- e.g. GodotXcodeIndex
- Goto the newly created target's *Build Settings* tab and search for *Header Search Paths*
- Set *Header Search Paths* to an absolute path to Godot's source folder
- Make it recursive by adding two \*'s to the end of the path
- e.g. /Users/me/repos/godot-source/\**
Add Godot Source to the Project:
- Drag and drop godot source into project file browser.
- |xcode Uncheck| *Create External Build System*
- Click Next
- |xcode Select| *create groups*
- Check off only your command line target in the *Add to targets* section
- Click finish. Xcode will now index the files.
- Grab a cup of coffee... Maybe make something to eat, too
- You should have jump to definition, auto completion, and full syntax highlighting when it is done.
Scheme Setup
^^^^^^^^^^^^
Edit Build Scheme of External Build Target:
- Open scheme editor of external build target
- Expand the *Build* menu
- Goto *Post Actions*
- Add a new script |xcode run action|
- Write a script that gives the binary a name that Xcode will recognize
- e.g. ln -f "$SRCROOT"/bin/godot.osx.tools.64 "$SRCROOT"/bin/godot
- Build the external build target
Edit Run Scheme of External Build Target:
- Open the scheme editor again
- |xcode Click Run|
- Set the *Executable* to the file you linked in your post build action script
- Check *Debug executable* if it isn't already
- You can go to *Arguments* tab and add an -e and a -path to a project to debug the editor
not the project selection screen
Test It:
- set a breakpoint in platform/osx/godot_main_osx.mm
- it should break at the point!
.. |xcode external build| replace:: :download:`external build </img/xcode_1_create_external_build_project.png>`
.. |xcode Info Tab| replace:: :download:`Info Tab </img/xcode_2_configure_scons.png>`
.. |xcode File > New > Target...| replace:: :download:`File > New > Target... </img/xcode_3_add_new_target.png>`
.. |xcode command line target| replace:: :download:`command line target </img/xcode_4_select_command_line_target.png>`
.. |xcode Uncheck| replace:: :download:`Uncheck </img/xcode_5_after_add_godot_source_to_project.png>`
.. |xcode Select| replace:: :download:`Select </img/xcode_6_after_add_godot_source_to_project_2.png>`
.. |xcode run action| replace:: :download:`run action </img/xcode_7_setup_build_post_action.png>`
.. |xcode Click Run| replace:: :download:`Click Run </img/xcode_8_setup_run_scheme.png>`
Other editors (vim, emacs, Atom...)
-----------------------------------
TODO.

View File

@@ -0,0 +1,236 @@
.. _doc_core_types:
Core types
==========
Godot has a rich set of classes and templates that compose its core,
and everything is built upon them.
This reference will try to list them in order for their better
understanding.
Definitions
-----------
Godot uses the standard C98 datatypes, such as ``uint8_t``,
``uint32_t``, ``int64_t``, etc. which are nowadays supported by every
compiler. Reinventing the wheel for those is not fun, as it makes code
more difficult to read.
In general, care is not taken to use the most efficient datatype for a
given task unless using large structures or arrays. ``int`` is used
through most of the code unless necessary. This is done because nowadays
every device has at least a 32 bits bus and can do such operations in
one cycle. It makes code more readable too.
For files or memory sizes, ``size_t`` is used, which is warranted to be
64 bits.
For Unicode characters, CharType instead of wchar_t is used, because
many architectures have 4 bytes long wchar_t, where 2 bytes might be
desired. However, by default, this has not been forced and CharType maps
directly to wchar_t.
References:
~~~~~~~~~~~
- `core/typedefs.h <https://github.com/godotengine/godot/blob/master/core/typedefs.h>`__
Memory model
------------
PC is a wonderful architecture. Computers often have gigabytes of RAM,
terabytes of storage and gigahertz of CPU, and when an application needs
more resources the OS will just swap out the inactive ones. Other
architectures (like mobile or consoles) are in general more limited.
The most common memory model is the heap, where an application will
request a region of memory, and the underlying OS will try to fit it
somewhere and return it. This often works best and is very flexible,
but over time and with abuse, this can lead to segmentation.
Segmentation slowly creates holes that are too small for most common
allocations, so that memory is wasted. There is a lot of literature
about heap and segmentation, so this topic will not be developed
further here. Modern operating systems use paged memory, which helps
mitigate the problem of segmentation but doesn't solve it.
However, in many studies and tests, it is shown that given enough
memory, if the maximum allocation size is below a given threshold in
proportion to the maximum heap size and proportion of memory intended to
be unused, segmentation will not be a problem over time as it will
remain constant. In other words, just leave 10-20% of your memory free
and perform all small allocations and you are fine.
Godot ensures that all objects that can be allocated dynamically are
small (less than a few kb at most). But what happens if an allocation is
too large (like an image or mesh geometry or large array)? In this case
Godot has the option to use a dynamic memory pool. This memory needs to
be locked to be accessed, and if an allocation runs out of memory, the
pool will be rearranged and compacted on demand. Depending on the need
of the game, the programmer can configure the dynamic memory pool size.
Allocating memory
-----------------
Godot has many tools for tracking memory usage in a game, specially
during debug. Because of this, the regular C and C++ library calls
should not be used. Instead, a few other ones are provided.
For C-style allocation, Godot provides a few macros:
.. code:: cpp
memalloc()
memrealloc()
memfree()
These are equivalent to the usual malloc, realloc, free of the standard
library.
For C++-style allocation, special macros are provided:
.. code:: cpp
memnew( Class / Class(args) )
memdelete( instance )
memnew_arr( Class , amount )
memdelete_arr( pointer to array )
which are equivalent to new, delete, new[] and delete[].
memnew/memdelete also use a little C++ magic and notify Objects right
after they are created, and right before they are deleted.
For dynamic memory, the DVector<> template is provided. Just use it
like:
.. code:: cpp
DVector<int>
DVector is just a standard vector class, it can be accessed using the []
operator, but that's probably slow for large amount of accesses (as it
has to lock internally). A few helpers exist for this:
.. code:: cpp
DVector<int>::Read r = dvector.read()
int someint = r[4]
and
.. code:: cpp
DVector<int>::Write w = dvector.write()
w[4]=22;
respectively. These allow fast read/write from DVectors and keep it
locked until they go out of scope.
References:
~~~~~~~~~~~
- `core/os/memory.h <https://github.com/godotengine/godot/blob/master/core/os/memory.h>`__
- `core/dvector.h <https://github.com/godotengine/godot/blob/master/core/dvector.h>`__
Containers
----------
Godot provides also a set of common containers:
- Vector
- List
- Set
- Map
They are very simple and aim to be as minimal as possible, as templates
in C++ are often inlined and make the binary size much fatter, both in
debug symbols and code. List, Set and Map can be iterated using
pointers, like this:
.. code:: cpp
for(List<int>::Element *E=somelist.front();E;E=E->next()) {
print_line(E->get()); //print the element
}
The Vector<> class also has a few nice features:
- It does copy on write, so making copies of it is cheap as long as
they are not modified.
- It supports multi-threading, by using atomic operations on the
reference counter.
References:
~~~~~~~~~~~
- `core/vector.h <https://github.com/godotengine/godot/blob/master/core/vector.h>`__
- `core/list.h <https://github.com/godotengine/godot/blob/master/core/list.h>`__
- `core/set.h <https://github.com/godotengine/godot/blob/master/core/set.h>`__
- `core/map.h <https://github.com/godotengine/godot/blob/master/core/map.h>`__
String
------
Godot also provides a String class. This class has a huge amount of
features, full Unicode support in all the functions (like case
operations) and utf8 parsing/extracting, as well as helpers for
conversion and visualization.
References:
~~~~~~~~~~~
- `core/ustring.h <https://github.com/godotengine/godot/blob/master/core/ustring.h>`__
StringName
----------
StringNames are like a String, but they are unique. Creating a
StringName from a string results in a unique internal pointer for all
equal strings. StringNames are really useful for using strings as
identifier, as comparing them is basically comparing a pointer.
Creation of a StringName (specially a new one) is slow, but comparison
is fast.
References:
~~~~~~~~~~~
- `core/string_db.h <https://github.com/godotengine/godot/blob/master/core/string_db.h>`__
Math types
----------
There are several linear math types available in the core/math
directory, they are basically just that.
References:
~~~~~~~~~~~
- `core/math <https://github.com/godotengine/godot/blob/master/core/math>`__
NodePath
--------
This is a special datatype used for storing paths in a scene tree and
referencing them fast.
References:
~~~~~~~~~~~
- `core/path_db.h <https://github.com/godotengine/godot/blob/master/core/path_db.h>`__
RID
---
RIDs are resource IDs. Servers use these to reference data stored in
them. RIDs are opaque, meaning that the data they reference can't be
accessed directly. RIDs are unique, even for different types of
referenced data.
References:
~~~~~~~~~~~
- `core/rid.h <https://github.com/godotengine/godot/blob/master/core/rid.h>`__

View File

@@ -0,0 +1,397 @@
.. _doc_creating_android_modules:
Creating Android modules
========================
Introduction
------------
Making video games portable is all fine and dandy, until mobile
gaming monetization shows up.
This area is complex, usually a mobile game that monetizes needs
special connections to a server for stuff such as:
- Analytics
- In-app purchases
- Receipt validation
- Install tracking
- Ads
- Video ads
- Cross-promotion
- In-game soft & hard currencies
- Promo codes
- A/B testing
- Login
- Cloud saves
- Leaderboards and scores
- User support & feedback
- Posting to Facebook, Twitter, etc.
- Push notifications
Oh yeah, developing for mobile is a lot of work. On iOS, you can just
write a C++ module and take advantage of the C++/ObjC
intercommunication, so this is rather easy.
For C++ developers Java is a pain, the build system is severely bloated
and interfacing it with C++ through JNI (Java Native Interface) is more
pain that you don't want even for your worst enemy.
Maybe REST?
-----------
Most of these APIs allow communication via REST+JSON APIs. Godot has
great support for HTTP, HTTPS and JSON, so consider this as an option
that works in every platform. Only write the code once and you are set
to go.
Popular engines that have half the share of apps published on mobile get
special plugins written just for them. Godot does not have that luxury
yet. So, if you write a REST implementation of a SDK for Godot, please
share it with the community.
Android module
--------------
Writing an Android module is similar to :ref:`doc_custom_modules_in_c++`, but
needs a few more steps.
Make sure you are familiar with building your own :ref:`Android export templates <doc_compiling_for_android>`,
as well as creating :ref:`doc_custom_modules_in_c++`.
config.py
~~~~~~~~~
In the config.py for the module, some extra functions are provided for
convenience. First, it's often wise to detect if android is being built
and only enable building in this case:
.. code:: python
def can_build(plat):
return plat=="android"
If more than one platform can be built (typical if implementing the
module also for iOS), check manually for Android in the configure
functions:
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# android specific code
Java singleton
--------------
An android module will usually have a singleton class that will load it,
this class inherits from ``Godot.SingletonBase``. Resource identifiers for
any additional resources you have provided for the module will be in the
``com.godot.game.R`` class, so you'll likely want to import it.
A singleton object template follows:
.. code:: java
// package com.android.godot; // for 1.1
package org.godotengine.godot; // for 2.0
import com.godot.game.R;
public class MySingleton extends Godot.SingletonBase {
public int myFunction(String p_str) {
// a function to bind
}
static public Godot.SingletonBase initialize(Activity p_activity) {
return new MySingleton(p_activity);
}
public MySingleton(Activity p_activity) {
//register class name and functions to bind
registerClass("MySingleton", new String[]{"myFunction"});
// you might want to try initializing your singleton here, but android
// threads are weird and this runs in another thread, so you usually have to do
activity.runOnUiThread(new Runnable() {
public void run() {
//useful way to get config info from engine.cfg
String key = GodotLib.getGlobal("plugin/api_key");
SDK.initializeHere();
}
});
}
// forwarded callbacks you can reimplement, as SDKs often need them
protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {}
protected void onMainPause() {}
protected void onMainResume() {}
protected void onMainDestroy() {}
protected void onGLDrawFrame(GL10 gl) {}
protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // singletons will always miss first onGLSurfaceChanged call
}
Calling back to Godot from Java is a little more difficult. The instance
ID of the script must be known first, this is obtained by calling
``get_instance_ID()`` on the script. This returns an integer that can be
passed to Java.
From Java, use the ``calldeferred`` function to communicate back with Godot.
Java will most likely run in a separate thread, so calls are deferred:
.. code:: java
GodotLib.calldeferred(<instanceid>, "<function>", new Object[]{param1,param2,etc});
Add this singleton to the build of the project by adding the following
to config.py:
(Before Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_module_file("MySingleton.java")
#env.android_module_file("MySingleton2.java") call again for more files
(After Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_add_java_dir("Directory that contain MySingleton.java")
AndroidManifest
---------------
Some SDKs need custom values in AndroidManifest.xml. Permissions can be
edited from the godot exporter so there is no need to add those, but
maybe other functionalities are needed.
Create the custom chunk of android manifest and put it inside the
module, add it like this:
(Before Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_module_file("MySingleton.java")
env.android_module_manifest("AndroidManifestChunk.xml")
(After Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_add_java_dir("Directory that contain MySingelton.java")
env.android_add_to_manifest("AndroidManifestChunk.xml")
Resources
---------
In order to provide additional resources with your module you have to
add something like this:
.. code:: python
def configure(env):
if env['platform'] == 'android':
# [...]
env.android_add_res_dir("Directory that contains resource subdirectories (values, drawable, etc.)")
Now you can refer to those resources by their id (``R.string.my_string``, and the like)
by importing the ``com.godot.game.R`` class in your Java code.
SDK library
-----------
So, finally it's time to add the SDK library. The library can come in
two flavors, a JAR file or an Android project for ant. JAR is the
easiest to integrate, just put it in the module directory and add it:
(Before Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_module_file("MySingleton.java")
env.android_module_manifest("AndroidManifestChunk.xml")
env.android_module_library("MyLibrary-3.1.jar")
(After Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_add_java_dir("Directory that contain MySingelton.java")
env.android_add_to_manifest("AndroidManifestChunk.xml")
env.android_add_dependency("compile files('something_local.jar')") # if you have a jar, the path is relative to platform/android/java/gradlew, so it will start with ../../../modules/module_name/
env.android_add_maven_repository("maven url") #add a maven url
env.android_add_dependency("compile 'com.google.android.gms:play-services-ads:8'") #get dependency from maven repository
SDK project
-----------
When this is an Android project, things usually get more complex. Copy
the project folder inside the module directory and configure it:
::
c:\godot\modules\mymodule\sdk-1.2> android -p . -t 15
As of this writing, Godot uses minsdk 10 and target sdk 15. If this ever
changes, it should be reflected in the manifest template:
`AndroidManifest.xml.template <https://github.com/godotengine/godot/blob/master/platform/android/AndroidManifest.xml.template>`
Then, add the module folder to the project:
(Before Version 2.0)
.. code:: python
def can_build(plat):
return plat=="android" or plat=="iphone"
def configure(env):
if env['platform'] == 'android':
# will copy this to the java folder
env.android_module_file("MySingleton.java")
env.android_module_manifest("AndroidManifestChunk.xml")
env.android_module_source("sdk-1.2","")
(After Version 2.0)
Building
--------
As you probably modify the contents of the module, and modify your .java
inside the module, you need the module to be built with the rest of
Godot, so compile android normally.
::
c:\godot> scons p=android
This will cause your module to be included, the .jar will be copied to
the java folder, the .java will be copied to the sources folder, etc.
Each time you modify the .java, scons must be called.
Afterwards, just continue the steps for compiling android :ref:`doc_compiling_for_android`.
Using the module
~~~~~~~~~~~~~~~~
To use the module from GDScript, first enable the singleton by adding
the following line to engine.cfg (Godot Engine 2.0 and greater):
::
[android]
modules="org/godotengine/godot/MySingleton"
For Godot Engine 1.1 is
::
[android]
modules="com/android/godot/MySingleton"
More than one singleton module can be enabled by separating with commas:
::
[android]
modules="com/android/godot/MySingleton,com/android/godot/MyOtherSingleton"
Then just request the singleton Java object from Globals like this:
::
# in any file
var singleton = null
func _init():
singleton = Globals.get_singleton("MySingleton")
print(singleton.myFunction("Hello"))
Troubleshooting
---------------
(This section is a work in progress, report your problems here!)
Godot crashes upon load
~~~~~~~~~~~~~~~~~~~~~~~
Check ``adb logcat`` for possible problems, then:
- Make sure libgodot_android.so is in the ``libs/armeabi`` folder
- Check that the methods used in the Java singleton only use simple
Java datatypes, more complex ones are not supported.
Future
------
Godot has an experimental Java API Wrapper that allows to use the
entire Java API from GDScript.
It's simple to use and it's used like this:
::
class = JavaClassWrapper.wrap(<javaclass as text>)
This is most likely not functional yet, if you want to test it and help
us make it work, contact us through the `developer mailing
list <https://groups.google.com/forum/#!forum/godot-engine>`__.

View File

@@ -0,0 +1,343 @@
.. _doc_custom_modules_in_c++:
Custom modules in C++
=====================
Modules
-------
Godot allows extending the engine in a modular way. New modules can be
created and then enabled/disabled. This allows for adding new engine
functionality at every level without modifying the core, which can be
split for use and reuse in different modules.
Modules are located in the ``modules/`` subdirectory of the build system.
By default, two modules exist, GDScript (which, yes, is not part of the
core engine), and the GridMap. As many new modules as desired can be
created and combined, and the SCons build system will take care of it
transparently.
What for?
---------
While it's recommended that most of a game is written in scripting (as
it is an enormous time saver), it's perfectly possible to use C++
instead. Adding C++ modules can be useful in the following scenarios:
- Binding an external library to Godot (like Bullet, Physx, FMOD, etc).
- Optimize critical parts of a game.
- Adding new functionality to the engine and/or editor.
- Porting an existing game.
- Write a whole, new game in C++ because you can't live without C++.
Creating a new module
---------------------
Before creating a module, make sure to download the source code of Godot
and manage to compile it. There are tutorials in the documentation for this.
To create a new module, the first step is creating a directory inside
``modules/``. If you want to maintain the module separately, you can checkout
a different VCS into modules and use it.
The example module will be called "sumator", and is placed inside the
Godot source tree (``C:\godot`` refers to wherever the Godot sources are
located):
::
C:\godot> cd modules
C:\godot\modules> mkdir sumator
C:\godot\modules> cd sumator
C:\godot\modules\sumator>
Inside we will create a simple sumator class:
.. code:: cpp
/* sumator.h */
#ifndef SUMATOR_H
#define SUMATOR_H
#include "reference.h"
class Sumator : public Reference {
OBJ_TYPE(Sumator,Reference);
int count;
protected:
static void _bind_methods();
public:
void add(int value);
void reset();
int get_total() const;
Sumator();
};
#endif
And then the cpp file.
.. code:: cpp
/* sumator.cpp */
#include "sumator.h"
void Sumator::add(int value) {
count+=value;
}
void Sumator::reset() {
count=0;
}
int Sumator::get_total() const {
return count;
}
void Sumator::_bind_methods() {
ObjectTypeDB::bind_method("add",&Sumator::add);
ObjectTypeDB::bind_method("reset",&Sumator::reset);
ObjectTypeDB::bind_method("get_total",&Sumator::get_total);
}
Sumator::Sumator() {
count=0;
}
Then, the new class needs to be registered somehow, so two more files
need to be created:
::
register_types.h
register_types.cpp
With the following contents:
.. code:: cpp
/* register_types.h */
void register_sumator_types();
void unregister_sumator_types();
/* yes, the word in the middle must be the same as the module folder name */
.. code:: cpp
/* register_types.cpp */
#include "register_types.h"
#include "object_type_db.h"
#include "sumator.h"
void register_sumator_types() {
ObjectTypeDB::register_type<Sumator>();
}
void unregister_sumator_types() {
//nothing to do here
}
Next, we need to create a ``SCsub`` file so the build system compiles
this module:
.. code:: python
# SCsub
Import('env')
env.add_source_files(env.modules_sources,"*.cpp") # just add all cpp files to the build
If you want to add custom compiler flags when building your module, you need to clone
`env` first, so it won't add those flags to whole Godot build (which can cause errors).
Example `SCsub` with custom flags:
.. code:: python
# SCsub
Import('env')
module_env = env.Clone()
module_env.add_source_files(env.modules_sources,"*.cpp")
module_env.Append(CXXFLAGS=['-O2', '-std=c++11'])
And finally, the configuration file for the module, this is a simple
python script that must be named ``config.py``:
.. code:: python
# config.py
def can_build(platform):
return True
def configure(env):
pass
The module is asked if it's ok to build for the specific platform (in
this case, True means it will build for every platform).
And that's it. Hope it was not too complex! Your module should look like
this:
::
godot/modules/sumator/config.py
godot/modules/sumator/sumator.h
godot/modules/sumator/sumator.cpp
godot/modules/sumator/register_types.h
godot/modules/sumator/register_types.cpp
godot/modules/sumator/SCsub
You can then zip it and share the module with everyone else. When
building for every platform (instructions in the previous sections),
your module will be included.
Using the module
----------------
Using your newly created module is very easy, from any script you can
now do:
::
var s = Sumator.new()
s.add(10)
s.add(20)
s.add(30)
print(s.get_total())
s.reset()
And the output will be ``60``.
Improving the build system for development
------------------------------------------
So far we defined a clean and simple SCsub that allows us to add the sources
of our new module as part of the Godot binary.
This static approach is fine when we want to build a release version of our
game given we want all the modules in a single binary.
However the trade-of is every single change means a full recompilation of the
game. Even if SCons is able to detect and recompile only the file that have
changed, finding such files and eventually linking the final binary is a
long and costly part.
The solution to avoid such a cost is to build our own module as a shared
library that will be dynamically loaded when starting our game's binary.
.. code:: python
# SCsub
Import('env')
sources = [
"register_types.cpp",
"sumator.cpp"
]
# First, create a custom env for the shared library.
module_env = env.Clone()
module_env.Append(CXXFLAGS='-fPIC') # Needed to compile shared library
# We don't want godot's dependencies to be injected into our shared library.
module_env['LIBS'] = []
# Now define the shared library. Note that by default it would be built
# into the module's folder, however it's better to output it into `bin`
# next to the godot binary.
shared_lib = module_env.SharedLibrary(target='#bin/sumator', source=sources)
# Finally notify the main env it has our shared lirary as a new dependency.
# To do so, SCons wants the name of the lib with it custom suffixes
# (e.g. ".x11.tools.64") but without the final ".so".
# We pass this along with the directory of our library to the main env.
shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
env.Append(LIBS=[shared_lib_shim])
env.Append(LIBPATH=['#bin'])
Once compiled, we should end up with a ``bin`` directory containing both the
``godot*`` binary and our ``libsumator*.so``. However given the .so is not in
a standard directory (like ``/usr/lib``), we have to help our binary find it
during runtime with the ``LD_LIBRARY_PATH`` environ variable:
::
user@host:~/godot$ export LD_LIBRARY_PATH=`pwd`/bin/
user@host:~/godot$ ./bin/godot*
**note**: Pay attention you have to ``export`` the environ variable otherwise
you won't be able to play you project from within the editor.
On top of that, it would be nice to be able to select whether to compile our
module as shared library (for development) or as a part of the godot binary
(for release). To do that we can define a custom flag to be passed to SCons
using the `ARGUMENT` command:
.. code:: python
# SCsub
Import('env')
sources = [
"register_types.cpp",
"sumator.cpp"
]
module_env = env.Clone()
module_env.Append(CXXFLAGS=['-O2', '-std=c++11'])
if ARGUMENTS.get('sumator_shared', 'no') == 'yes':
# Shared lib compilation
module_env.Append(CXXFLAGS='-fPIC')
module_env['LIBS'] = []
shared_lib = module_env.SharedLibrary(target='#bin/sumator', source=sources)
shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
env.Append(LIBS=[shared_lib_shim])
env.Append(LIBPATH=['#bin'])
else:
# Static compilation
module_env.add_source_files(env.modules_sources, sources)
Now by default ``scons`` command will build our module as part of godot's binary
and as a shared library when passing ``sumator_shared=yes``.
Finally you can even speedup build further by explicitly specifying your
shared module as target in the scons command:
::
user@host:~/godot$ scons sumator_shared=yes bin/sumator.x11.tools.64.so
Summing up
----------
As you see, it's really easy to develop Godot in C++. Just write your
stuff normally and remember to:
- use ``OBJ_TYPE`` macro for inheritance, so Godot can wrap it
- use ``_bind_methods`` to bind your functions to scripting, and to
allow them to work as callbacks for signals.
But this is not all, depending what you do, you will be greeted with
some surprises.
- If you inherit from :ref:`class_Node` (or any derived node type, such as
Sprite), your new class will appear in the editor, in the inheritance
tree in the "Add Node" dialog.
- If you inherit from :ref:`class_Resource`, it will appear in the resource
list, and all the exposed properties can be serialized when
saved/loaded.
- By this same logic, you can extend the Editor and almost any area of
the engine.

View File

@@ -0,0 +1,29 @@
Inheritance class tree
======================
Object
------
.. image:: /img/Object.png
Reference
---------
.. image:: /img/Reference.png
Control
-------
.. image:: /img/Control.png
Node2D
------
.. image:: /img/Node2D.png
Spatial
-------
.. image:: /img/Spatial.png
Source files: :download:`class_tree.zip </files/class_tree.zip>`.

View File

@@ -0,0 +1,40 @@
.. _doc_introduction_to_godot_development:
Introduction to Godot development
=================================
This page is meant to introduce the global organization of Godot Engine's
source code, and give useful tips for extending/fixing the engine on the
C++ side.
Architecture diagram
--------------------
The following diagram describes the architecture used by Godot, from the
core components down to the abstracted drivers, via the scene
structure and the servers.
.. image:: /img/architecture_diagram.jpg
Debugging the editor with gdb
-----------------------------
If you are writing or correcting bugs affecting Godot Engine's editor,
remember that the binary will by default run the project manager first,
and then only run the editor in another process once you've selected a
project. To launch a project directly, you need to run the editor by
passing the ``-e`` argument to Godot Engine's binary from within your
project's folder. Typically:
.. code:: bash
$ cd ~/myproject
$ gdb godot
> run -e
Or:
.. code:: bash
$ gdb godot
> run -e -path ~/myproject

View File

@@ -0,0 +1,310 @@
.. _doc_object_class:
Object class
============
General definition
------------------
:ref:`Object <class_object>` is the base class for almost everything. Most classes in Godot
inherit directly or indirectly from it. Objects provide reflection and
editable properties, and declaring them is a matter of using a single
macro like this.
.. code:: cpp
class CustomObject : public Object {
OBJ_TYPE(CustomObject,Object); // this is required to inherit
};
This makes Objects gain a lot of functionality, like for example
.. code:: cpp
obj = memnew(CustomObject);
print_line("Object Type: ",obj->get_type()); //print object type
obj2 = obj->cast_to<OtherType>(); // converting between types, this also works without RTTI enabled.
References:
~~~~~~~~~~~
- `core/object.h <https://github.com/godotengine/godot/blob/master/core/object.h>`__
Registering an Object
---------------------
ObjectTypeDB is a static class that holds the entire list of registered
classes that inherit from Object, as well as dynamic bindings to all
their methods properties and integer constants.
Classes are registered by calling:
.. code:: cpp
ObjectTypeDB::register_type<MyCustomType>()
Registering it will allow the type to be instanced by scripts, code, or
creating them again when deserializing.
Registering as virtual is the same but it can't be instanced.
.. code:: cpp
ObjectTypeDB::register_virtual_type<MyCustomType>()
Object-derived classes can override the static function
``static void _bind_methods()``. When one class is registered, this
static function is called to register all the object methods,
properties, constants, etc. It's only called once. If an Object derived
class is instanced but has not been registered, it will be registered as
virtual automatically.
Inside ``_bind_methods``, there are a couple of things that can be done.
Registering functions is one:
.. code:: cpp
ObjectTypeDB::register_method(_MD("methodname","arg1name","arg2name"),&MyCustomMethod);
Default values for arguments can be passed in reverse order:
.. code:: cpp
ObjectTypeDB::register_method(_MD("methodname","arg1name","arg2name"),&MyCustomType::method,DEFVAL(-1)); //default value for arg2name
``_MD`` is a macro that converts "methodname" to a StringName for more
efficiency. Argument names are used for introspection, but when
compiling on release, the macro ignores them, so the strings are unused
and optimized away.
Check ``_bind_methods`` of Control or Object for more examples.
If just adding modules and functionality that is not expected to be
documented as thoroughly, the ``_MD()`` macro can safely be ignored and a
string passing the name can be passed for brevity.
References:
~~~~~~~~~~~
- `core/object_type_db.h <https://github.com/godotengine/godot/blob/master/core/object_type_db.h>`__
Constants
---------
Classes often have enums such as:
.. code:: cpp
enum SomeMode {
MODE_FIRST,
MODE_SECOND
};
For these to work when binding to methods, the enum must be declared
convertible to int, for this a macro is provided:
.. code:: cpp
VARIANT_ENUM_CAST( MyClass::SomeMode ); // now functions that take SomeMode can be bound.
The constants can also be bound inside ``_bind_methods``, by using:
.. code:: cpp
BIND_CONSTANT( MODE_FIRST );
BIND_CONSTANT( MODE_SECOND );
Properties (set/get)
--------------------
Objects export properties, properties are useful for the following:
- Serializing and deserializing the object.
- Creating a list of editable values for the Object derived class.
Properties are usually defined by the PropertyInfo() class. Usually
constructed as:
.. code:: cpp
PropertyInfo(type,name,hint,hint_string,usage_flags)
For example:
.. code:: cpp
PropertyInfo(Variant::INT,"amount",PROPERTY_HINT_RANGE,"0,49,1",PROPERTY_USAGE_EDITOR)
This is an integer property, named "amount", hint is a range, range goes
from 0 to 49 in steps of 1 (integers). It is only usable for the editor
(edit value visually) but won't be serialized.
Another example:
.. code:: cpp
PropertyInfo(Variant::STRING,"modes",PROPERTY_HINT_ENUM,"Enabled,Disabled,Turbo")
This is a string property, can take any string but the editor will only
allow the defined hint ones. Since no usage flags were specified, the
default ones are PROPERTY_USAGE_STORAGE and PROPERTY_USAGE_EDITOR.
There are plenty of hints and usage flags available in object.h, give them a
check.
Properties can also work like C# properties and be accessed from script
using indexing, but this usage is generally discouraged, as using
functions is preferred for legibility. Many properties are also bound
with categories, such as "animation/frame" which also make indexing
impossible unless using operator [].
From ``_bind_methods()``, properties can be created and bound as long as
set/get functions exist. Example:
.. code:: cpp
ADD_PROPERTY( PropertyInfo(Variant::INT,"amount"), _SCS("set_amount"), _SCS("get_amount") )
This creates the property using the setter and the getter. ``_SCS`` is a
macro that creates a StringName efficiently.
Binding properties using ``_set``/``_get``/``_get_property_list``
-----------------------------------------------------------------
An additional method of creating properties exists when more flexibility
is desired (i.e. adding or removing properties on context).
The following functions can be overridden in an Object derived class,
they are NOT virtual, DO NOT make them virtual, they are called for
every override and the previous ones are not invalidated (multilevel
call).
.. code:: cpp
void _get_property_info(List<PropertyInfo> *r_props); //return list of properties
bool _get(const StringName& p_property, Variany& r_value) const; //return true if property was found
bool _set(const StringName& p_property, const Variany& p_value); //return true if property was found
This is also a little less efficient since ``p_property`` must be
compared against the desired names in serial order.
Dynamic casting
---------------
Godot provides dynamic casting between Object-derived classes, for
example:
.. code:: cpp
void somefunc(Object *some_obj) {
Button *button = some_obj->cast_to<Button>();
}
If cast fails, NULL is returned. This system uses RTTI, but it also
works fine (although a bit slower) when RTTI is disabled. This is useful
on platforms where a very small binary size is ideal, such as HTML5 or
consoles (with low memory footprint).
Signals
-------
Objects can have a set of signals defined (similar to Delegates in other
languages). Connecting to them is rather easy:
.. code:: cpp
obj->connect(<signal>,target_instance,target_method)
//for example
obj->connect("enter_tree",this,"_node_entered_tree")
The method ``_node_entered_tree`` must be registered to the class using
``ObjectTypeDB::register_method`` (explained before).
Adding signals to a class is done in ``_bind_methods``, using the
``ADD_SIGNAL`` macro, for example:
.. code:: cpp
ADD_SIGNAL( MethodInfo("been_killed") )
References
----------
:ref:`Reference <class_reference>` inherits from Object and holds a
reference count. It is the base for reference counted object types.
Declaring them must be done using Ref<> template. For example:
.. code:: cpp
class MyReference: public Reference {
OBJ_TYPE( MyReference,Reference );
};
Ref<MyReference> myref = memnew( MyReference );
``myref`` is reference counted. It will be freed when no more Ref<>
templates point to it.
References:
~~~~~~~~~~~
- `core/reference.h <https://github.com/godotengine/godot/blob/master/core/reference.h>`__
Resources:
----------
:ref:`Resource <class_resource>` inherits from Reference, so all resources
are reference counted. Resources can optionally contain a path, which
reference a file on disk. This can be set with ``resource.set_path(path)``.
This is normally done by the resource loader though. No two different
resources can have the same path, attempt to do so will result in an error.
Resources without a path are fine too.
References:
~~~~~~~~~~~
- `core/resource.h <https://github.com/godotengine/godot/blob/master/core/resource.h>`__
Resource loading
----------------
Resources can be loaded with the ResourceLoader API, like this:
.. code:: cpp
Ref<Resource> res = ResourceLoader::load("res://someresource.res")
If a reference to that resource has been loaded previously and is in
memory, the resource loader will return that reference. This means that
there can be only one resource loaded from a file referenced on disk at
the same time.
- resourceinteractiveloader (TODO)
References:
~~~~~~~~~~~
- `core/io/resource_loader.h <https://github.com/godotengine/godot/blob/master/core/io/resource_loader.h>`__
Resource saving
---------------
Saving a resource can be done with the resource saver API:
.. code:: cpp
ResourceSaver::save("res://someresource.res",instance)
Instance will be saved. Sub resources that have a path to a file will be
saved as a reference to that resource. Sub resources without a path will
be bundled with the saved resource and assigned sub-IDs, like
"res://someresource.res::1". This also helps to cache them when loaded.
References:
~~~~~~~~~~~
- `core/io/resource_saver.h <https://github.com/godotengine/godot/blob/master/core/io/resource_saver.h>`__

View File

@@ -0,0 +1,62 @@
.. _doc_variant_class:
Variant class
=============
About
-----
Variant is the most important datatype of Godot, it's the most important
class in the engine. A Variant takes up only 20 bytes and can store
almost any engine datatype inside of it. Variants are rarely used to
hold information for long periods of time, instead they are used mainly
for communication, editing, serialization and generally moving data
around.
A Variant can:
- Store almost any datatype
- Perform operations between many variants (GDScript uses Variant as
its atomic/native datatype).
- Be hashed, so it can be compared quickly to over variants
- Be used to convert safely between datatypes
- Be used to abstract calling methods and their arguments (Godot
exports all its functions through variants)
- Be used to defer calls or move data between threads.
- Be serialized as binary and stored to disk, or transferred via
network.
- Be serialized to text and use it for printing values and editable
settings.
- Work as an exported property, so the editor can edit it universally.
- Be used for dictionaries, arrays, parsers, etc.
Basically, thanks to the Variant class, writing Godot itself was a much,
much easier task, as it allows for highly dynamic constructs not common
of C++ with little effort. Become a friend of Variant today.
References:
~~~~~~~~~~~
- `core/variant.h <https://github.com/godotengine/godot/blob/master/core/variant.h>`__
Dictionary and Array
--------------------
Both are implemented using variants. A Dictionary can match any datatype
used as key to any other datatype. An Array just holds an array of
Variants. Of course, a Variant can also hold a Dictionary and an Array
inside, making it even more flexible.
Both have a shared mode and a COW mode. Scripts often use them in shared
mode (meaning modifications to a container will modify all references to
it), or COW mode (modifications will always alter the local copy, making
a copy of the internal data if necessary, but will not affect the other
copies). In COW mode, Both Dictionary and Array are thread-safe,
otherwise a Mutex should be created to lock if multi thread access is
desired.
References:
~~~~~~~~~~~
- `core/dictionary.h <https://github.com/godotengine/godot/blob/master/core/dictionary.h>`__
- `core/array.h <https://github.com/godotengine/godot/blob/master/core/array.h>`__