|
// c_src/counter_nif.cpp |
|
|
|
#include <new> |
|
#include <erl_nif.h> |
|
|
|
#include "counter.h" |
|
|
|
ErlNifResourceType* CounterType; |
|
|
|
void destruct_counter(ErlNifEnv* caller_env, void* obj) { |
|
Counter* counter = static_cast<Counter*>(obj); |
|
counter->~Counter(); |
|
} |
|
|
|
int load(ErlNifEnv* caller_env, void** priv_data, ERL_NIF_TERM load_info) { |
|
CounterType = enif_open_resource_type(caller_env, "Counter", "Counter", destruct_counter, ERL_NIF_RT_CREATE, nullptr); |
|
|
|
return 0; |
|
} |
|
|
|
ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { |
|
int count; |
|
enif_get_int(env, argv[0], &count); |
|
|
|
void* resource = enif_alloc_resource(CounterType, sizeof(Counter)); |
|
new(resource) Counter(count); |
|
|
|
ERL_NIF_TERM handle = enif_make_resource(env, resource); |
|
enif_release_resource(resource); |
|
|
|
return enif_make_tuple2( |
|
env, |
|
enif_make_atom(env, "ok"), |
|
handle |
|
); |
|
} |
|
|
|
ERL_NIF_TERM up(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { |
|
Counter* counter; |
|
enif_get_resource(env, argv[0], CounterType, reinterpret_cast<void**>(&counter)); |
|
|
|
int result = counter->up(); |
|
|
|
return enif_make_tuple2( |
|
env, |
|
enif_make_atom(env, "ok"), |
|
enif_make_int(env, result) |
|
); |
|
} |
|
|
|
ERL_NIF_TERM down(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { |
|
void* resource; |
|
enif_get_resource(env, argv[0], CounterType, &resource); |
|
Counter* counter = static_cast<Counter*>(resource); |
|
|
|
int result = counter->down(); |
|
|
|
return enif_make_tuple2( |
|
env, |
|
enif_make_atom(env, "ok"), |
|
enif_make_int(env, result) |
|
); |
|
} |
|
|
|
ERL_NIF_TERM set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { |
|
void* resource; |
|
enif_get_resource(env, argv[0], CounterType, &resource); |
|
Counter* counter = static_cast<Counter*>(resource); |
|
|
|
int count; |
|
enif_get_int(env, argv[1], &count); |
|
|
|
counter->set(count); |
|
|
|
return enif_make_atom(env, "ok"); |
|
} |
|
|
|
ERL_NIF_TERM get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { |
|
void* resource; |
|
enif_get_resource(env, argv[0], CounterType, &resource); |
|
Counter* counter = static_cast<Counter*>(resource); |
|
|
|
int result = counter->get(); |
|
|
|
return enif_make_tuple2( |
|
env, |
|
enif_make_atom(env, "ok"), |
|
enif_make_int(env, result) |
|
); |
|
} |
|
|
|
static ErlNifFunc nif_funcs[] = { |
|
{"create", 1, create}, |
|
{"up", 1, up}, |
|
{"down", 1, down}, |
|
{"set", 2, set}, |
|
{"get", 1, get} |
|
}; |
|
|
|
ERL_NIF_INIT(Elixir.Counter, nif_funcs, load, nullptr, nullptr, nullptr); |