Git Product home page Git Product logo

Comments (14)

SanderMertens avatar SanderMertens commented on June 14, 2024

A number of functions will be renamed to better fit the CRUD operations:

cx_new -> cx_create
cx_destruct -> cx_delete

New functions shall be added for read-locking an object:

void cx_readBegin(cx_object o);
void cx_readEnd(cx_object o);

Additionally, cx_delete will become the default operation to delete an object. Reference counting is not done manually by users - not even in C. Instead, users should use the cx_set function. Therefore, the cx_free and cx_keep functions will only be used internally and should no longer be part of the public API.

In summary, the object management primitives shall be:

cx_object cx_create(cx_type t);
cx_object cx_declare(cx_object parent, cx_string name, cx_type type);
cx_int16 cx_define(cx_object o);
void cx_readBegin(cx_object o);
void cx_readEnd(cx_object o);
void cx_update(cx_object o);
void cx_updateBegin(cx_object o);
void cx_updateEnd(cx_object o);
void cx_delete(cx_object o);

We need a set function for references and strings. Therefore, in place of cx_set two other functions shall be added:

void cx_setstr(void *ptr, cx_string str);
void cx_setref(void *ptr, cx_object obj);

For consistency purposes, cx_malloc shall be renamed to cx_alloc.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

A new convenience function should be generated by the C binding to update an object with a new value. For example:

t = Temperature__create(50);
Temperature__update(t, 60); // New function
cx_delete(t);

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

I mentioned above that cx_keep and cx_free should be made private. That is actually not possible. The reason for this is that cx_resolve and cx_lookup increase the refcount, which will have to be released by an application. Additionally, eventually all functions that return objects should increase refcount.

Proposed to rename cx_keep to cx_claim, and rename cx_free to cx_release. This will increase consistency with the cx_scopeClaim and cx_scopeRelease functions.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

The __define convenience function should be rewritten to the following signature:

Foo Foo__define(cx_object _this, cx_string _name, cx_int32 member1, cx_int32 member2);

This function shall serve two purposes. First of all, it shall be able to create & define a new scoped object:

Foo o = Foo__define(root_o, "myObject", 10, 20);

Secondly, it shall allow for defining an object that already has been declared. This is useful when forward declaring objects. Consider:

Foo o = Foo__declare(root_o, "myObject");
Foo__define(o, NULL, 10, 20);

Thus, when NULL is provided to the name parameter, the first argument will be interpreted as the object to be defined, rather than the parent.

When the define fails, __define will return NULL. The object should be deleted when __define fails.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

All API convenience functions should be generated for all relevant types instead of the arbitrary subset the generator picks today. The functions should be (for a type Foo):

// For all types
Foo Foo__create(<value>); // cx_create + cx_define
Foo Foo__createChild(cx_object parent, cx_string name, <value>); // cx_declare + cx_define

// For non-VOID types
Foo Foo__declare(); // cx_create
Foo Foo__declareChild(cx_object parent, cx_string name); // cx_declare
cx_int16 Foo__define(Foo _this, <value>); // cx_define
void Foo__set(Foo _this, <value>);
void Foo__update(Foo _this, <value>); // cx_updateBegin + cx_updateEnd OR cx_update
cx_string Foo__str(Foo _this); // cx_toString
Foo Foo__fromStr(Foo _this, cx_string str); // cx_fromStr OR cx_create + cx_fromStr
cx_int16 Foo__copy(Foo dst, Foo src); // cx_copyValue
cx_equalityKind Foo__compare(Foo v1, Foo v2); // cx_compareValue

// For non-reference types
cx_int16 Foo__init(Foo _this); // cx_initValue
void Foo__deinit(Foo _this); // cx_deinitValue

// For collection values, the <value> becomes a varargs list
Foo FooList__create(cx_uint32 size, ...);

// For all {postfix} collection types with numeric index
#define Foo{postfix}__foreach(collection, element)
Foo Foo{postfix}__get(Foo{postfix} _this, cx_uint32 index);

// For all reference and scalar collections
void Foo{postfix}__replace(Foo{postfix} _this, Foo replace, Foo with);

// For sequence types
Foo* FooSeq__append(FooSeq _this);
void FooSeq__size(FooSeq _this, cx_uint32 length);
void FooSeq__clear(FooSeq _this);

// For all list types
Foo FooList__takeFirst(FooList _this);
Foo FooList__last(FooList _this);
void FooList__clear(FooList _this);

// For list types of which elements require no alloc
void FooList__insert(FooList _this, Foo value);
void FooList__append(FooList _this, Foo value);

// For list types of which elements require an alloc
Foo* FooList__insert(FooList _this);
Foo* FooList__append(FooList _this);

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

Remove the *_ext functions for adding memory refcounting metadata (source and context). Instead, add a function cx_setcontext(cx_object src, cx_string context) that can be called before a cx_claim that will set the context in thread specific memory for a single claim.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

As described in issue #275, apply the same strategy to core functions, so that when providing for example type to cx_create, one can type:

cx_object o = cx_create(cx_int32_o);

instead of:

cx_object o = cx_create(cx_type(cx_int32_o));

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

Remove cx_create_ext function that has additional attr parameter. Replace this with a cx_setDefaultAttr function which set the attributes which the next cx_create/cx_declare is going to use. By default, these functions will use CX_ATTR_DEFAULT.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

Remove cx_declareFrom, cx_defineFrom, cx_updateFrom, cx_updateEndFrom functions, and replace with a single cx_setSource function that needs to be invoked when any of these functions needs to be annotated with a source.

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

Remove cx_scopeof function

from corto.

SanderMertens avatar SanderMertens commented on June 14, 2024

To increase consistency, the object management API should be further "crudified". The proposed scheme for the generated code (see above) should be applied to the core API as well.

Changes apply only to object creation. The new names will look like this:

cx_object cx_create(cx_type type);
cx_object cx_createChild(cx_object parent, cx_string name, cx_type type);

cx_object cx_declare(cx_type type);
cx_object cx_declareChild(cx_object parent, cx_string name, cx_type type);

cx_object cx_define(cx_object o);

A code example:

cx_string *myStr = cx_create(cx_string_o);
cx_update(myStr);
cx_delete(myStr);

from corto.

jleeothon avatar jleeothon commented on June 14, 2024

Casting arguments in function calls is often bothersome and code becomes unreadable, e.g.

zoo_Animal_eat(mycat);
// needs to be written as
zoo_Animal_eat(zoo_Animal(mycat)); // cats don't belong to zoo's though

We propose to write macros for every function in the C binding such that all arguments are automatically (and safely) cast to the appropriate type, something like:

// package_Animal.h
cx_void _zoo_Animal_eat(Animal _this);
#define zoo_Animal_eat(_this) _zoo_Animal_eat(Animal(_this))
// package_Animal.c
cx_void _zoo_Animal_eat(Animal _this) { }

from corto.

jleeothon avatar jleeothon commented on June 14, 2024

One problem with the above approach is that the symbol zoo_Animal_eat is nowhere defined by itself if not a function call, e.g.

screen shot 2015-08-12 at 16 14 23

That one, however, is the only instance in the current code base where a function pointer is being passed. We can stick to the above simple design, or we can both force the existence of zoo_Animal_eat() and zoo_Animal_eat.

Writing two define's together in the header file doesn't work well!

Let's consider:

/* CURRENTLY */

// package.h
#include "package_foo.h"

// package_foo.h
cx_void _package_foo_bar(package_foo _this);
#define package_foo_bar(_this) _package_foo_bar(package_foo(_this))

// package_foo.c
#include "package.h"
cx_void _package_foo_bar(package_foo _this) {}

// third-party code
#include "package.h"
// the symbol package_foo_bar doesn't exist

/**********************/

/* WITH EXTRA FILE, MAYBE? */

// package.h // public main header
#include "_package.h"
#define package_foo_bar _package_foo_bar

// _package.h // private main header
#include "package_foo.h"

// package_foo.h
cx_void _package_foo_bar(package_foo _this);
#define package_foo_bar(_this) _package_foo_bar(package_foo(_this))

// package_foo.c
#include "package.h" // import private main header
cx_void _package_foo_bar(package_foo _this) {}

// third-party code
#include "package.h"
// I wonder if package_foo_bar() will get macro-replaced with the normal macro
// or the function-like macro;
// the function-like macro will be run first, if I'm not mistaken.

So that in third-party code:

package_foo_bar(o);
package_foo_bar;

becomes after the pass of function-like casting macro:

_package_foo_bar(package_foo(o));
package_foo_bar;

then after passing of the type casting macro:

_package_foo_bar((package_foo)cx_assertType((cx_type)package_foo_o, o));
package_foo_bar;

then after passing of the public header macro

_package_foo_bar((package_foo)cx_assertType((cx_type)package_foo_o, o));
_package_foo_bar;

from corto.

jleeothon avatar jleeothon commented on June 14, 2024

+1 =)

from corto.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.