Initial commit
This commit is contained in:
commit
f222bb92af
9 changed files with 359 additions and 0 deletions
24
example/CMakeLists.txt
Normal file
24
example/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
add_executable(
|
||||
example
|
||||
main.c
|
||||
MObject.c
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
example
|
||||
PROPERTIES
|
||||
C_STANDARD 23
|
||||
C_STANDARD_REQUIRED ON
|
||||
C_EXTENSIONS OFF
|
||||
)
|
||||
target_link_libraries(
|
||||
example
|
||||
PRIVATE
|
||||
${PROJECT_NAME}
|
||||
)
|
||||
target_include_directories(
|
||||
example
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
|
||||
86
example/MObject.c
Normal file
86
example/MObject.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include "MObject.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static struct Object* alloc(struct Object* self);
|
||||
static struct Object* retain(struct Object* self);
|
||||
static struct Object* release(struct Object* self);
|
||||
|
||||
struct Method MObject_meta_methods[] = {
|
||||
{ .sel = "alloc", .impl = alloc },
|
||||
};
|
||||
struct Class MObjectMetaClass = {
|
||||
.class = &MObjectMetaClass,
|
||||
.name = "MObject(meta)",
|
||||
.super = nullptr,
|
||||
.methods = MObject_meta_methods,
|
||||
.methods_count = sizeof(MObject_meta_methods) / sizeof(struct Method),
|
||||
};
|
||||
|
||||
struct Method MObject_methods[] = {
|
||||
{ .sel = "retain", .impl = retain },
|
||||
{ .sel = "release", .impl = release },
|
||||
};
|
||||
struct Class MObject = {
|
||||
.class = &MObjectMetaClass,
|
||||
.name = "MObject",
|
||||
.super = nullptr,
|
||||
.methods = MObject_methods,
|
||||
.methods_count = sizeof(MObject_methods) / sizeof(struct Method),
|
||||
};
|
||||
|
||||
struct Header
|
||||
{
|
||||
size_t retain_count;
|
||||
};
|
||||
|
||||
static struct Object* alloc(struct Object* self)
|
||||
{
|
||||
if (!self) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct Class* class = (struct Class*)self;
|
||||
|
||||
auto size = sizeof(struct Header) + sizeof(struct Object);
|
||||
void* mem = malloc(size);
|
||||
memset(mem, 0, size);
|
||||
|
||||
struct Header* header = (struct Header*)mem;
|
||||
header->retain_count = 1;
|
||||
|
||||
struct Object* obj = (struct Object*)((uintptr_t)mem + sizeof(struct Header));
|
||||
obj->class = class;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static struct Object* retain(struct Object* self)
|
||||
{
|
||||
if (!self) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct Header* header = (struct Header*)((uintptr_t)self - sizeof(struct Header));
|
||||
header->retain_count += 1;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static struct Object* release(struct Object* self)
|
||||
{
|
||||
if (!self) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct Header* header = (struct Header*)((uintptr_t)self - sizeof(struct Header));
|
||||
header->retain_count -= 1;
|
||||
if (header->retain_count <= 0) {
|
||||
free(header);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
5
example/MObject.h
Normal file
5
example/MObject.h
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include <mini-obj-c.h>
|
||||
|
||||
extern struct Class MObjectMetaClass;
|
||||
extern struct Class MObject;
|
||||
|
||||
55
example/main.c
Normal file
55
example/main.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <mini-obj-c.h>
|
||||
|
||||
#include "MObject.h"
|
||||
|
||||
static struct Object* static_method(struct Object* self);
|
||||
static struct Object* instance_method(struct Object* self);
|
||||
|
||||
int main()
|
||||
{
|
||||
struct Method Test_meta_methods[] = {
|
||||
{ .sel = "staticMethod", .impl = static_method },
|
||||
};
|
||||
struct Class TestMetaClass = {
|
||||
.class = &TestMetaClass,
|
||||
.name = "Test(meta)",
|
||||
.super = &MObjectMetaClass,
|
||||
.methods = Test_meta_methods,
|
||||
.methods_count = sizeof(Test_meta_methods) / sizeof(struct Method),
|
||||
};
|
||||
|
||||
struct Method Test_methods[] = {
|
||||
{ .sel = "instanceMethod", .impl = instance_method },
|
||||
};
|
||||
struct Class Test = {
|
||||
.class = &TestMetaClass,
|
||||
.name = "Test",
|
||||
.super = &MObject,
|
||||
.methods = Test_methods,
|
||||
.methods_count = sizeof(Test_methods) / sizeof(struct Method),
|
||||
};
|
||||
|
||||
msg_send((struct Object*)&Test, "staticMethod");
|
||||
|
||||
struct Object* obj = msg_send((struct Object*)&Test, "alloc");
|
||||
msg_send(obj, "instanceMethod");
|
||||
msg_send(obj, "release");
|
||||
}
|
||||
|
||||
static struct Object* static_method(struct Object* self)
|
||||
{
|
||||
struct Class* class = (struct Class*)self;
|
||||
printf("Hello from class '%s'\n", class->name);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static struct Object* instance_method(struct Object* self)
|
||||
{
|
||||
printf("Hello from instance of '%s'\n", self->class->name);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue