@ 260528.1 · fetching

231103.1 · 7f4a9ed91bbecb84e39f4bc8030247ce5116ddf8

Reorganize examples into categorized folders (#341)

* refactor: create directory structure to organize exmaples
* test: update test_all to work with new directory structure
* fix: bug in test_all if no package.json scripts
* test: cleanup output of test_all
* fix: remove default test script that throws from thread_safe_function_with_object_wrap
* fix: remove build_with_cmake from .gitignore
* fix: swith to ' from " and remove subdir from getAllTests call
* test: add extra test cases for npm start and just running the pkgJson.main with node
* refactor: move all examples to src directory
* refactor: add numbers to categories so they are ordered in the src folder
* refactor: simplify getAllExamples in test_all.js
* docs: add directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure to README.md
* docs: update directory structure example in readme
* add back build_with_cmake --------- Co-authored-by: legendecas <legendecas@gmail.com>

reading declarations

Changes to src/2-js-to-native-conversion/object-template-demo/napi/node-api-common.h. All files

src/2-js-to-native-conversion/object-template-demo/napi/node-api-common.h

new file mode 100644@@ -0,0 +1,141 @@+#include <node_api.h>+#include <initializer_list>+#include <utility>++// Empty value so that macros here are able to return NULL or void+#define NODE_API_RETVAL_NOTHING  // Intentionally blank #define++#define GET_AND_THROW_LAST_ERROR(env)                                          \+  do {                                                                         \+    const napi_extended_error_info* error_info;                                \+    napi_get_last_error_info((env), &error_info);                              \+    bool is_pending;                                                           \+    const char* err_message = error_info->error_message;                       \+    napi_is_exception_pending((env), &is_pending);                             \+    /* If an exception is already pending, don't rethrow it */                 \+    if (!is_pending) {                                                         \+      const char* error_message =                                              \+          err_message != NULL ? err_message : "empty error message";           \+      napi_throw_error((env), NULL, error_message);                            \+    }                                                                          \+  } while (0)++#define NODE_API_ASSERT_BASE(env, assertion, message, ret_val)                 \+  do {                                                                         \+    if (!(assertion)) {                                                        \+      napi_throw_error(                                                        \+          (env), NULL, "assertion (" #assertion ") failed: " message);         \+      return ret_val;                                                          \+    }                                                                          \+  } while (0)++// Returns NULL on failed assertion.+// This is meant to be used inside napi_callback methods.+#define NODE_API_ASSERT(env, assertion, message)                               \+  NODE_API_ASSERT_BASE(env, assertion, message, NULL)++#define NODE_API_CALL_BASE(env, the_call, ret_val)                             \+  do {                                                                         \+    if ((the_call) != napi_ok) {                                               \+      GET_AND_THROW_LAST_ERROR((env));                                         \+      return ret_val;                                                          \+    }                                                                          \+  } while (0)++// Returns NULL if the_call doesn't return napi_ok.+#define NODE_API_CALL(env, the_call) NODE_API_CALL_BASE(env, the_call, NULL)++// Returns empty if the_call doesn't return napi_ok.+#define NODE_API_CALL_RETURN_VOID(env, the_call)                               \+  NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING)++#define CHECK_NAPI(...)                                                        \+  do {                                                                         \+    napi_status res__ = (__VA_ARGS__);                                         \+    if (res__ != napi_ok) {                                                    \+      return res__;                                                            \+    }                                                                          \+  } while (0)++#define NAPI_CALL(expr) NODE_API_CALL(env, expr);++#ifdef __cpp_lib_span+#include <span>+using std::span;+#else+/**+ * @brief A span of values that can be used to pass arguments to function.+ *+ * For C++20 we should consider to replace it with std::span.+ */+template <typename T>+struct span {+  constexpr span(std::initializer_list<T> il) noexcept+      : data_{const_cast<T*>(il.begin())}, size_{il.size()} {}+  constexpr span(T* data, size_t size) noexcept : data_{data}, size_{size} {}+  [[nodiscard]] constexpr T* data() const noexcept { return data_; }+  [[nodiscard]] constexpr size_t size() const noexcept { return size_; }+  [[nodiscard]] constexpr T* begin() const noexcept { return data_; }+  [[nodiscard]] constexpr T* end() const noexcept { return data_ + size_; }+  const T& operator[](size_t index) const noexcept { return *(data_ + index); }++ private:+  T* data_;+  size_t size_;+};+#endif  // __cpp_lib_span++struct RefHolder {+  RefHolder(std::nullptr_t = nullptr) noexcept {}+  explicit RefHolder(napi_env env, napi_value value) : env_(env) {+    // Start with 2 to avoid ever going to 0 that creates a weak ref.+    napi_create_reference(env, value, 2, &ref_);+  }++  // The class is movable.+  RefHolder(RefHolder&& other) noexcept+      : env_(std::exchange(other.env_, nullptr)),+        ref_(std::exchange(other.ref_, nullptr)) {}++  RefHolder& operator=(RefHolder&& other) noexcept {+    if (this != &other) {+      swap(*this, other);+      RefHolder temp(std::move(other));+    }+    return *this;+  }++  // The class is not copyable.+  RefHolder(const RefHolder& other) = delete;+  RefHolder& operator=(const RefHolder& other) = delete;++  ~RefHolder() noexcept {+    if (env_ != nullptr && ref_ != nullptr) {+      uint32_t refCount{};+      napi_reference_unref(env_, ref_, &refCount);+      if (refCount == 1) {+        napi_delete_reference(env_, ref_);+      }+    }+  }++  operator napi_value() const {+    napi_value result{};+    if (ref_ != nullptr) {+      napi_get_reference_value(env_, ref_, &result);+    }+    return result;+  }++  explicit operator bool() const noexcept { return ref_ != nullptr; }++  friend void swap(RefHolder& left, RefHolder& right) noexcept {+    using std::swap;+    swap(left.env_, right.env_);+    swap(left.ref_, right.ref_);+  }++ private:+  napi_env env_{};+  napi_ref ref_{};+};