OOP experiment.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15186 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-12-04 10:59:00 +00:00
parent 3203f778f2
commit 1a92311b0c
3 changed files with 330 additions and 0 deletions

View File

@ -0,0 +1,171 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file oop_object.h
* @brief Base object.
* @details This header defines a base class that is the root class of
* the ChibiOS Object Model.
*
* @addtogroup OOP_BASE_OBJECT
* @details ChibiOS uses concepts of Object Oriented Programming even if
* it is written in C. Things like simple inheritance, multiple
* inheritance and interfaces are used through the system.
* This module defines a "base object" class that is the ancestor
* of all classes in the system.<br>
* Class types are denoted by a "_c" suffix, classes contain a
* virtual methods table and data encapsulated into a normal C
* structure.<br>
* Interfaces are denoted by a "_i" suffix, interfaces just have
* a virtual methods table as single member of their C structure.<br>
* The first field of a VMT is the offset between the container
* object and the VMT pointer.<br>
* Multiple inheritance is implemented by composing a class
* structure with the structures of implemented classes or
* interfaces.<br>
* Example:
* <code>
* // Defining a counter interface.
* typedef struct {
* const struct __counter_interface_vmt *vmt;
* } counter_interface_i;
*
* // Defining a beans interface.
* typedef struct {
* const struct __beans_interface_vmt *vmt;
* } beans_interface_i;
*
* // Definition of a class myclass_c implementing interfaces
* // counter_interface_i and beans_interface_i.
* typedef struct {
* const struct __myclass_vmt *vmt;
* // Fields of myclass.
* counter_interface_i counter;
* beans_interface_i beans;
* } myclass_c;
* </code>
* @{
*/
#ifndef OOP_OBJECT_H
#define OOP_OBJECT_H
#include "ccportab.h"
#include "osal.h"
/**
* @brief Type of a base object class.
* @details This class represents a generic object including a virtual
* methods table (VMT).
* @note This class is compatible with the legacy HAL @p BaseObject class.
*/
typedef struct base_object base_object_c;
/**
* @brief @p base_object_c specific methods.
* @note This object defines no methods.
*/
#define __base_object_methods \
/* Instance offset, used for multiple inheritance, normally zero. It
represents the offset between the current object and the container
object*/ \
size_t instance_offset;
/**
* @brief @p base_object_c specific data.
* @note This object defines no data.
*/
#define __base_object_data
/**
* @brief @p base_object_c virtual methods table.
*/
struct __base_object_vmt {
__base_object_methods
};
/**
* @brief Structure representing a base object class.
*/
typedef struct base_object {
/**
* @brief Virtual Methods Table.
*/
const struct __base_object_vmt *vmt;
__base_object_data
} base_object_c;
/**
* @name Methods implementations
* @{
*/
/**
* @brief Object creation implementation.
*
* @param[in] ip Pointer to a @p referenced_object_c structure to be
* initialized.
* @return A new reference to the object.
*/
CC_FORCE_INLINE
static inline base_object_c *__base_object_objinit_impl(base_object_c *ip,
const void *vmt) {
ip->vmt = (struct __base_object_vmt *)vmt;
return ip;
}
/**
* @brief Object finalization implementation.
*
* @param[in] ip Pointer to a @p referenced_object_c structure to be
* disposed.
*/
CC_FORCE_INLINE
static inline void __base_object_dispose_impl(base_object_c *ip) {
(void) ip;
/* Nothing.*/
}
/** @} */
/**
* @name OOP Utility macros
* @{
*/
/**
* @brief Returns the object instance pointer starting from an interface
* pointer.
* @details Because multiple inheritance, an object can be composed by
* multiple interfaces and/or classes (its ancestors).<br>
* This function returns the pointer to the base object starting
* from a pointer to any of its composing classes or interfaces.<br>
* This is done by leveraging the offset field into each VMT table.
*
* @param[in] c The class type of the object.
* @param[in] ip A pointer to one of the object composing classes or
* interfaces.
* @return A pointer to an object of type @p type implementing
* the interface @p ip.
*/
#define oopGetInstance(c, ip) \
(c)(((size_t)(ip)) - (ip)->vmt->instance_offset)
/** @} */
#endif /* OOP_OBJECT_H */
/** @} */

View File

@ -0,0 +1,151 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file oop_referenced_object.h
* @brief Base class for objects with a reference counter.
* @details This header defines a base class for classes requiring a
* a reference counter and a disposing mechanism.
*
* @addtogroup OOP_REFERENCED_OBJECT
* @details Base class for objects that implement a reference counter and
* are disposed when the number of references reaches zero.
* @{
*/
#ifndef OOP_REFERENCED_OBJECT_H
#define OOP_REFERENCED_OBJECT_H
#include "oop_object.h"
/**
* @brief Type of a referenced object class.
*/
typedef struct referenced_object referenced_object_c;
/**
* @brief @p referenced_object_c specific methods.
* @note This object defines no methods.
*/
#define __referenced_object_methods \
__base_object_methods
/**
* @brief @p referenced_object_c specific data.
*/
#define __referenced_object_data \
__base_object_data \
unsigned references;
/**
* @brief @p referenced_object_c virtual methods table.
*/
struct __referenced_object_vmt { \
__referenced_object_methods \
unsigned (*release)(referenced_object_c *ip);
};
/**
* @brief Structure representing a referenced object class.
*/
typedef struct referenced_object {
/**
* @brief Virtual Methods Table.
*/
const struct __referenced_object_vmt *vmt;
__referenced_object_data
} referenced_object_c;
/**
* @name Methods implementations
* @{
*/
/**
* @brief Object creation implementation.
*
* @param[in] ip Pointer to a @p referenced_object_c structure to be
* initialized.
* @return A new reference to the object.
*/
CC_FORCE_INLINE
static inline referenced_object_c *__referenced_object_objinit_impl(referenced_object_c *ip,
const void *vmt) {
__base_object_objinit_impl((base_object_c *)ip, vmt);
ip->references = 1U;
return ip;
}
/**
* @brief Object finalization implementation.
*
* @param[in] ip Pointer to a @p referenced_object_c structure to be
* disposed.
*/
CC_FORCE_INLINE
static inline void __referenced_object_dispose_impl(referenced_object_c *ip) {
__base_object_dispose_impl((base_object_c *)ip);
/* Nothing.*/
}
/**
* @brief Reference creation implementation.
*
* @param[in] ip An existing reference to the object.
* @return A new reference to the object.
*/
CC_FORCE_INLINE
static inline referenced_object_c *__referenced_object_addref_impl(referenced_object_c *ip) {
ip->references++;
return ip;
}
/**
* @brief References count implementation.
*/
CC_FORCE_INLINE
static inline unsigned __referenced_object_getcount_impl(referenced_object_c *ip) {
return ip->references;
}
/**
* @brief Reference release implementation.
*
* @param[in] ip A reference to the object.
* @return Remaining references.
*/
CC_FORCE_INLINE
static inline unsigned __referenced_object_release_impl(referenced_object_c *ip) {
osalDbgAssert(ip->references > 0U, "zero references");
if (--ip->references == 0U) {
__referenced_object_dispose_impl(ip);
}
return ip->references;
}
/** @} */
#endif /* OOP_REFERENCED_OBJECT_H */
/** @} */

8
os/common/utils/utils.mk Normal file
View File

@ -0,0 +1,8 @@
# List of the ChibiOS OOP module.
UTILSSRC =
UTILSINC = ${CHIBIOS}/os/common/utils/oop/include
# Shared variables
ALLCSRC += $(UTILSSRC)
ALLINC += $(UTILSINC)