mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-07 02:12:07 +03:00
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:
committed by
Rémi Verschelde
parent
6a730cb057
commit
5e05011eae
183
development/cpp/configuring_an_ide.rst
Normal file
183
development/cpp/configuring_an_ide.rst
Normal 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.
|
||||
236
development/cpp/core_types.rst
Normal file
236
development/cpp/core_types.rst
Normal 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>`__
|
||||
397
development/cpp/creating_android_modules.rst
Normal file
397
development/cpp/creating_android_modules.rst
Normal 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>`__.
|
||||
343
development/cpp/custom_modules_in_cpp.rst
Normal file
343
development/cpp/custom_modules_in_cpp.rst
Normal 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.
|
||||
29
development/cpp/inheritance_class_tree.rst
Normal file
29
development/cpp/inheritance_class_tree.rst
Normal 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>`.
|
||||
40
development/cpp/introduction_to_godot_development.rst
Normal file
40
development/cpp/introduction_to_godot_development.rst
Normal 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
|
||||
310
development/cpp/object_class.rst
Normal file
310
development/cpp/object_class.rst
Normal 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>`__
|
||||
62
development/cpp/variant_class.rst
Normal file
62
development/cpp/variant_class.rst
Normal 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>`__
|
||||
Reference in New Issue
Block a user