Code Monkey home page Code Monkey logo

cobj's People

Contributors

gprossliner avatar gwalliman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cobj's Issues

Consider "Default References"

In cobj, in order to call interface methods, you need a reference to that very interface, which is itself the result of a queryinterface call.

Consider providing a reference to each implemented interface for a object to be created initialized when an object is initialized.

So you always have to deal with objects and the corresponding interfaces. This makes using cobj harder then in should be, and results in more boilerplate code.

Example:

// init a class
myclass c;
myclass_initialize(&c);

// get references for "interface1" and "interface2", and call the foo function on them:
interface1 i1;
interface2 i2;
interface1_queryinterface(&c.object, &i1);
interface2_queryinterface(&c.object, &i2);
interface1_foo(&i1);
interface2_foo(&i2);

This could become much more readable by:

// init a class. The cobj generator emits a default reference to each implemented interface.
myclass c;
myclass_initialize(&c);

// call methods by using the default references:
interface1_foo(&c.interface1);
interface2_foo(&c.interface2);

As a result of this change, queryinterface may not be needed at all, but this will go into a new issue.

Provide some guidance about the order or #define and #include statements in cobj

When implementing the cobj files for a project, some code was not generated, which was expected to be so. The problem was like:

//class.h
#include "header.h"
...
#define COBJ_INTERFACE_IMPLEMENTATION_MODE
#include "interface.h"
#undef COBJ_INTERFACE_IMPLEMENTATION_MODE

So far everything looks ok, but what if "interface.h" uses a include-guard, and "header.h" includes "interface.h"?:

// header.h
#ifndef _HEADER_H_
#define _HEADER_H_ 

#include "interface.h"

#endif
//interface.h
#ifndef _INTERFACE_H_
#define _INTERFACE_H_ 

#define COBJ_INTERFACE_NAME interface
...
#include "cobj-interface-generator.h"

#endif

The result is, that "interface.h" is included at a time, where COBJ_INTERFACE_IMPLEMENTATION_MODE is not defined. Although it's included again in class.h, this is not effective, since the include guard (#ifndef _INTERFACE_H_), prevents the header to be processed again.

This seems to be related to #8, but even if COBJ_INTERFACE_IMPLEMENTATION_MODE is changed to an automatic check, the order still matters.

Internal #include statements not resolving correclty

If you don't have the cobj directory in your include path directly, but include the generators by specifing a path (like #include "cobj-interface-generator.h"), GCC fails to include the files in the "private" folder.

Consider passing interface references by value instead by reference for interface method calls

In v2 default interfaces will be created for each object (see #10). So you access object.interface_name to get a reference.

Currently in v1, the public interface methods are rendered like:
void interface_name_foo(interface * reference)

So you need to pass pointer to the interface.
This could be changed to passing a copy of the reference:
void interface_name_foo(interface reference)

PROS:

  • Cleaner API
  • No accidental modification of the reference in the implementation

CONT:

  • Instead of passing one pointer-sized field, the compiler has to pass a struct containing two pointer-sized fields (object and methodtable)

Decision is not finally...

COBJ_INTERFACE_IMPLEMENTATION_MODE causing trouble

cobj needs to generate some code for a class implementing an interface, like the methodtable struct. This is currently enabled for an included header, if COBJ_INTERFACE_IMPLEMENTATION_MODE is defined.
This is causing trouble, because one .h file may included other .h files as dependencies, but they are not implemented in the given class.
A solution need to be implemented, that COBJ_INTERFACE_IMPLEMENTATION_MODE is not specified by the user, but that cobj does something like (pseudo-code):

#define COBJ_INTERFACE_IMPLEMENTATION_MODE COBJ_INTERACE_NAME exisits_in COBJ_CLASS_INTERFACES

This would lead to cleaner code anyway, because this symbol defines redundant data.

Allow interface method calls to be inlined

Currently the cobj generator declare a function in the .h file of the interface, and the implementation is in the interface-registry file, like:

// in interface.h
int interface_foo(interface * self, int j);

// in interface_registry.c
int interface_foo(interface * self, int j)
{
   return self->mt->foo(self->object, j);
}

This "forwarder" method could be inlined by the compiler, if the cobj generator would emit it with the "inline" keyword in the header. This would have this advantages:

  • it would reduce the overhead of calling an cobj interface method for one function call
  • if we could just use default references (see #10), then we would not need queryinterface at all, allowing us also to get rid of the interface-descriptor, and so get rid of the interface_registry completely.

COBJ_IMPLEMENTATION_FILE causing trouble

This is similar to #8. The #define COBJ_IMPLEMENTATION_FILE works as long as you don't include any class-header in "another" implementation file. Simply because there is no "another", so cobj will render code for the "another" class.

Change the return value of the class_initialize method to int instead of bool

cobj itself has no dependency to the value of the class_initialize method. cobj just returns whatever is returned from the initialize_impl method. It's up to the caller to check it or not, or to assign any semantic with the value.

Why change to bool?

  • the application could use it to return an error-code instead of just true or false
  • we would not have an internal dependency to <stdbool.h>, which would effect all files getting in touch with cobj
  • in v2 we will no longer need cobj.h, so there will be no need to include any (even standard) .h file

#error conditions are emitted from the preprocessor, making hard to diagnose issues

If a method is declared without using a comma between the type and the name, like:

#define COBJ_INTERFACE_METHODS  \   
    COBJ_INTERFACE_METHOD(void, set_options, gpio_pin_options options)  \

it's very hard to diagnose, because of the following macro:

cobjpvt-generator-framework.h

#define COBJPVT_GEN_METHOD_ARGS_SEPERATOR_1 #error "Invalid Method Signature"

Using an #error within a #define is not possible. It should use some static assertion, if possible, or remote it in total

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.