Skip to content

Instantly share code, notes, and snippets.

@shoz-f
Last active September 5, 2018 13:30
Show Gist options
  • Select an option

  • Save shoz-f/e3e6660587c29de8caa9000bd34fcda0 to your computer and use it in GitHub Desktop.

Select an option

Save shoz-f/e3e6660587c29de8caa9000bd34fcda0 to your computer and use it in GitHub Desktop.
NIFsのリソースオブジェクトでSFMLのインスタンスを管理する
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include "erl_nif.h"
// sf::Drawable以下のクラス・オブジェクトを表すリソース型
ErlNifResourceType *SFML_DRAWABLE;
// リーダビリティUPのためのヘルパー
typedef sf::Drawable* DrawablePtr;
// リソース解放処理(SFML::Drawable以下で共有)
// リソースが持つ参照カウンタが 0になると呼ばれる
// sf::Drawableのインスタンスを解体する
void smart_ptr_destructor(ErlNifEnv *env, void *res)
{
DrawablePtr* drawable_res = reinterpret_cast<DrawablePtr*>(res);
sf::Drawable* drawable = *drawable_res;
delete drawable;
}
// リソース型を定義
int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info)
{
ErlNifResourceFlags flags = ERL_NIF_RT_CREATE;
SFML_DRAWABLE = enif_open_resource_type(env, NULL, "smart_ptr", smart_ptr_destructor, flags, NULL);
return 0;
}
/*** ここからsf::Drawable以下のクラス毎のルーチン ***/
// リーダビリティUPのためのヘルパー
typedef sf::CircleShape* CircleShapePtr;
// sf::CircleShapeのインスタンスを生成し、リソース型SFML_DRAWABLEに預ける
ERL_NIF_TERM sfCircleShapeCreate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
CircleShapePtr* circle_res = reinterpret_cast<CircleShapePtr*>(enif_alloc_resource(SFML_DRAWABLE, sizeof(CircleShapePtr)));
*circle_res = new sf::CircleShape();
ERL_NIF_TERM term = enif_make_resource(env, circle_res);
enif_release_resource(circle_res);
return term;
}
// 明示的にsf::CircleShapeインスタンスの参照カウントを減らす
// 明示的な操作をしない場合は、ガーベージコレクタが後片づけをする
ERL_NIF_TERM sfCircleShapeDestroy(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
CircleShapePtr* circle_res;
if (!enif_get_resource(env, argv[0], SFML_DRAWABLE, (void**)&circle_res)) {
return enif_make_badarg(env);
}
enif_release_resource(circle_res);
return enif_make_int(env, 0);
}
// sf::CircleShapeのメソッド呼び出し
ERL_NIF_TERM sfCircleShapeSetRadius(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
CircleShapePtr* circle_res;
if (!enif_get_resource(env, argv[0], SFML_DRAWABLE, (void**)&circle_res)) {
return enif_make_badarg(env);
}
sf::CircleShape* circle = *circle_res;
double radius;
if (!enif_get_double(env, argv[1], &radius)) {
return enif_make_badarg(env);
}
circle->setRadius((float)radius);
return argv[0];
}
// 以下省略
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment