summaryrefslogtreecommitdiffstatshomepage
path: root/examples/usercmodule/cexample/examplemodule.c
diff options
context:
space:
mode:
authorLaurens Valk <laurens@pybricks.com>2022-11-21 14:10:02 +0100
committerDamien George <damien@micropython.org>2022-11-23 11:46:17 +1100
commita67989aa201817efaaefebdc7fd491358da45df8 (patch)
tree52da627e96de13906b4641f68054152f58f28d3a /examples/usercmodule/cexample/examplemodule.c
parent1d27c7d423f4e7b2c1f2e9b68d99a33ac26d81eb (diff)
downloadmicropython-a67989aa201817efaaefebdc7fd491358da45df8.tar.gz
micropython-a67989aa201817efaaefebdc7fd491358da45df8.zip
examples/usercmodule: Add example of a native C class.
This shows how ports can add their own custom types/classes. It is part of the unix coverage build, so we can use it for tests too. Signed-off-by: Laurens Valk <laurens@pybricks.com>
Diffstat (limited to 'examples/usercmodule/cexample/examplemodule.c')
-rw-r--r--examples/usercmodule/cexample/examplemodule.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/examples/usercmodule/cexample/examplemodule.c b/examples/usercmodule/cexample/examplemodule.c
index 93a58be2ed..b2457b2801 100644
--- a/examples/usercmodule/cexample/examplemodule.c
+++ b/examples/usercmodule/cexample/examplemodule.c
@@ -1,6 +1,9 @@
// Include MicroPython API.
#include "py/runtime.h"
+// Used to get the time in the Timer class example.
+#include "py/mphal.h"
+
// This is the function which will be called from Python as cexample.add_ints(a, b).
STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
// Extract the ints from the micropython input objects.
@@ -13,6 +16,59 @@ STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
// Define a Python reference to the function above.
STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
+// This structure represents Timer instance objects.
+typedef struct _example_Timer_obj_t {
+ // All objects start with the base.
+ mp_obj_base_t base;
+ // Everything below can be thought of as instance attributes, but they
+ // cannot be accessed by MicroPython code directly. In this example we
+ // store the time at which the object was created.
+ mp_uint_t start_time;
+} example_Timer_obj_t;
+
+// This is the Timer.time() method. After creating a Timer object, this
+// can be called to get the time elapsed since creating the Timer.
+STATIC mp_obj_t example_Timer_time(mp_obj_t self_in) {
+ // The first argument is self. It is cast to the *example_Timer_obj_t
+ // type so we can read its attributes.
+ example_Timer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ // Get the elapsed time and return it as a MicroPython integer.
+ mp_uint_t elapsed = mp_hal_ticks_ms() - self->start_time;
+ return mp_obj_new_int_from_uint(elapsed);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(example_Timer_time_obj, example_Timer_time);
+
+// This represents Timer.__new__ and Timer.__init__, which is called when
+// the user instantiates a Timer object.
+STATIC mp_obj_t example_Timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+ // Allocates the new object and sets the type.
+ example_Timer_obj_t *self = m_new_obj(example_Timer_obj_t);
+ self->base.type = (mp_obj_type_t *)type;
+
+ // Initializes the time for this Timer instance.
+ self->start_time = mp_hal_ticks_ms();
+
+ // The make_new function always returns self.
+ return MP_OBJ_FROM_PTR(self);
+}
+
+// This collects all methods and other static class attributes of the Timer.
+// The table structure is similar to the module table, as detailed below.
+STATIC const mp_rom_map_elem_t example_Timer_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&example_Timer_time_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(example_Timer_locals_dict, example_Timer_locals_dict_table);
+
+// This defines the type(Timer) object.
+MP_DEFINE_CONST_OBJ_TYPE(
+ example_type_Timer,
+ MP_QSTR_Timer,
+ MP_TYPE_FLAG_NONE,
+ make_new, example_Timer_make_new,
+ locals_dict, &example_Timer_locals_dict
+ );
+
// Define all properties of the module.
// Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference.
@@ -21,6 +77,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
+ { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) },
};
STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);