Skip to content

MobiusHorizons/closure_module

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Closure

Closure is a simple interface for stateful callbacks in C.

It can be installed using clib

clib install mobiushorizons/closure_module

It has a simple API

C API

closure_new

closure_t closure_new(void * (*fn)(void * ctx, void * arg), void * ctx);

This function creates a closure_t which can be called with closure_call

The function pointer passed to closure_new is of the form

void * callback(void * ctx, void * arg);

where ctx refers to the context argument passed to closure_new, which will be the same across calls, and arg is the void *argument passed to closure_call

closure_call

void * closure_call(closure_t c, void * arg);

Calls the closure passing it both the ctx context argument set up on initialization, and the arg argument.

C Module API (for use with cbuild the C module builder )

new

closure.t closure.new(void * (*fn)(void * ctx, void * arg), void * ctx);

This function creates a closure.t which can be called with closure.call

The function pointer passed to closure.new is of the form

void * callback(void * ctx, void * arg);

where ctx refers to the context argument passed to closure.new, which will be the same across calls, and arg is the void *argument passed to closure.call

call

void * call(closure_t c, void * arg);

Calls the closure passing it both the ctx context argument set up on initialization, and the arg argument.

Examples

If you are including this with cbuild the modular C preprocessor, use the first syntax, otherwise, the generated header and c files are included to work in any normal build system.

Modular Example

/* test-closure.module.c */
package "main";

import closure from "./deps/closure/closure.module.c";
#include <stdio.h>

struct state {
  int count;
};

void * callback(void * ctx, void * arg){
  if (ctx == NULL) return NULL;
  struct state * state = (struct state *)ctx;
  state->count++; // increment invocation counter

  printf("callback has been called %d times, Message was '%s'\n", state->count, (char*) arg);
  return NULL;
}

int main(){
  struct state state = {
    .count = 0,
  };

  closure.t cb = closure.new(callback, &state);

  closure.call(cb, "Hello World!!");
  closure.call(cb, "Lorem");
  closure.call(cb, "Ipsum ...");
  closure.call(cb, "You Get the picture.");

  printf("Our callback was called %d times\n", state.count);
}

compile with mpp -m test-closure.module.c, which will produce a test-closure binary in the same directory.

Standard C example

/* test-closure-standard-c.c */
#include "./deps/closure/closure.h"
#include <stdio.h>

struct state {
  int count;
};

void * callback(void * ctx, void * arg){
  if (ctx == NULL) return NULL;
  struct state * state = (struct state *)ctx;
  state->count++; // increment invocation counter

  printf("callback has been called %d times, Message was '%s'\n", state->count, (char*) arg);
  return NULL;
}

int main(){
  struct state state = {
    .count = 0,
  };

  closure_t cb = closure_new(callback, &state);

  closure_call(cb, "Hello World!!");
  closure_call(cb, "Lorem");
  closure_call(cb, "Ipsum ...");
  closure_call(cb, "You Get the picture.");

  printf("Our callback was called %d times\n", state.count);
}

compile with cc ./deps/closure/closure.c test-closure-standard-c.c -o test-closure-standard-c;