Initial commit.
This commit is contained in:
commit
f59561fdfb
15 changed files with 2516 additions and 0 deletions
107
example/animal.h
Normal file
107
example/animal.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This file is part of libooc.
|
||||
* https://xw3.org/hanez/libooc
|
||||
*
|
||||
* Copyright 2026 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#ifndef ANIMAL_H
|
||||
#define ANIMAL_H
|
||||
|
||||
#include <ooc/ooc.h>
|
||||
|
||||
typedef struct Animal Animal;
|
||||
typedef struct AnimalVTable AnimalVTable;
|
||||
|
||||
/*
|
||||
* Virtual methods inherited by every animal.
|
||||
*
|
||||
* The vtable is a plain struct of function pointers, so dispatch is an ordinary
|
||||
* call through a pointer and needs no support from the compiler. A subclass
|
||||
* fills in its own table and installs it in the instance, which is how `speak`
|
||||
* reaches Dog's implementation when the object is only known as an Animal.
|
||||
*
|
||||
* Each pointer is called with the object as its first argument, so an
|
||||
* implementation casts it back to the class it belongs to.
|
||||
*/
|
||||
struct AnimalVTable {
|
||||
void (*speak)(Animal *self);
|
||||
};
|
||||
|
||||
/*
|
||||
* Base class.
|
||||
*
|
||||
* Every instance starts with an ooc_object header, which the runtime needs
|
||||
* for reference counting and the virtual destructor. Subclasses embed this
|
||||
* struct as their first member, which makes the upcast free.
|
||||
*/
|
||||
struct Animal {
|
||||
ooc_object object;
|
||||
const AnimalVTable *vtable;
|
||||
char *name;
|
||||
int age;
|
||||
|
||||
/*
|
||||
* Two fields that belong to the class alone, told apart by their leading
|
||||
* underscores.
|
||||
*
|
||||
* `_id` is published, so it can be read by name, and ooc_set() refuses to
|
||||
* write it. `__legs` is hidden outright: ooc_get() withholds it as well, so
|
||||
* nothing outside Animal can read or write it by name at all. Both are set
|
||||
* from the struct definition below, where the members are in view.
|
||||
*/
|
||||
int _id;
|
||||
int __legs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Animal's runtime type record, the value ooc_new() takes.
|
||||
*
|
||||
* A subclass names it in its own `super`, which is how field lookup continues
|
||||
* up the chain and how Dog's objects still resolve "name" and "age".
|
||||
*/
|
||||
extern const ooc_class Animal_class;
|
||||
|
||||
/*
|
||||
* Create an Animal named `name` and return it, or NULL.
|
||||
*
|
||||
* Ownership of the result is the caller's, with a reference count of one, so it
|
||||
* has to reach ooc_release() eventually. Returns NULL if the allocation or the
|
||||
* copy of the name fails, in which case there is nothing to release.
|
||||
*/
|
||||
Animal *animal_new(const char *name, int age);
|
||||
|
||||
/*
|
||||
* Read back `_id`, the field ooc_get() also returns.
|
||||
*
|
||||
* Takes a const object, so it can be called where ooc_get() could not.
|
||||
*/
|
||||
int animal_id(const Animal *animal);
|
||||
|
||||
/*
|
||||
* Read back `__legs`, the field ooc_get() withholds.
|
||||
*
|
||||
* This accessor is the only way to learn the value, which is the point of a
|
||||
* two-underscore name. Returns 0 for a NULL object.
|
||||
*/
|
||||
int animal_legs(const Animal *animal);
|
||||
|
||||
/*
|
||||
* Initialise the members Animal owns, so a subclass constructor can build the
|
||||
* base part without duplicating it. Requires zero-initialised member storage
|
||||
* and external synchronization between constructors in different threads.
|
||||
* Returns 0, or -1 for NULL, an already initialised animal, exhausted positive
|
||||
* int IDs, or a failed name copy. Failure leaves the animal unchanged.
|
||||
*/
|
||||
int animal_init(Animal *animal, const char *name, int age);
|
||||
|
||||
/*
|
||||
* Dispatch `speak` through the vtable, so the implementation depends on the
|
||||
* object's runtime type. A NULL object, a NULL vtable and a NULL method are all
|
||||
* tolerated and do nothing.
|
||||
*/
|
||||
void animal_speak(Animal *animal);
|
||||
|
||||
#endif /* ANIMAL_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue