Comments (14)
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.
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.
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.
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.
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.
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.
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.
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.
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.
Remove cx_scopeof
function
from corto.
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.
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.
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.
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.
+1 =)
from corto.
Related Issues (20)
- Don't create objects when serializing between content types
- Add C++ template functions for enabling compile-time type safety
- Incorrect Environment Variables causing Installation Failure
- Serializer framework should support relative object identifiers
- Enable selecting/subscribing for unknown objects
- Add a strict option for serializers
- Add support for lazy evaluation of references HOT 1
- Add option to disable alignment of existing objects to subscribers
- Recursive query on a mount from parent of mountpoint produces incorrect results
- Standalone deployment mode
- Not providing initial '/' in type filter works for corto_select, but not for corto_subscribe filter
- Implement by-value and by-reference semantics in corto_value API
- Aliasing a member from a non-hidden base class does not fail until code generation
- Create API for determining initializer order of members HOT 1
- Support dot notation for resolving objects
- Corto observer invalid when notifying during shutdown
- Add support for objective state, observable/optional members to corto_rw API
- Primitive reference type crashes corto_value_binaryOp HOT 2
- Add support for singleton members
- How can the Corto team ease the learning curve for new users?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from corto.