[c] More fixes to C wrapper generator, everything compiles, smoke test works

This commit is contained in:
Mario Zechner 2025-07-10 04:44:35 +02:00
parent dcc0e20361
commit 8f831bd245
151 changed files with 331 additions and 165 deletions

View File

@ -238,3 +238,6 @@ class CWriter {
## checks.ts (continued) ## checks.ts (continued)
- [x] Fix checkConstNonConstConflicts - it was checking for different return types instead of checking for const vs non-const methods - [x] Fix checkConstNonConstConflicts - it was checking for different return types instead of checking for const vs non-const methods
## Build fixes
- [x] Fixed RTTI linking errors by including flags.cmake in spine-c-new CMakeLists.txt to enable -fno-rtti flag

View File

@ -4,6 +4,9 @@ project(spine-c-new C CXX)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
# Include the common flags (including -fno-rtti)
include(${CMAKE_CURRENT_LIST_DIR}/../flags.cmake)
# Include spine-cpp # Include spine-cpp
add_subdirectory(../spine-cpp ${CMAKE_CURRENT_BINARY_DIR}/spine-cpp) add_subdirectory(../spine-cpp ${CMAKE_CURRENT_BINARY_DIR}/spine-cpp)

View File

@ -66,6 +66,7 @@ export class CWriter {
lines.push('#endif'); lines.push('#endif');
lines.push(''); lines.push('');
lines.push(`#endif /* ${guardName} */`); lines.push(`#endif /* ${guardName} */`);
lines.push('');
return lines.join('\n'); return lines.join('\n');
} }
@ -135,6 +136,7 @@ export class CWriter {
lines.push('#endif'); lines.push('#endif');
lines.push(''); lines.push('');
lines.push(`#endif /* ${guardName} */`); lines.push(`#endif /* ${guardName} */`);
lines.push('');
return lines.join('\n'); return lines.join('\n');
} }
@ -211,6 +213,7 @@ export class CWriter {
lines.push(''); lines.push('');
lines.push('#endif // SPINE_C_H'); lines.push('#endif // SPINE_C_H');
lines.push('');
fs.writeFileSync(mainHeaderPath, lines.join('\n')); fs.writeFileSync(mainHeaderPath, lines.join('\n'));
} }
@ -255,6 +258,7 @@ export class CWriter {
arrayHeaderLines.push('#endif'); arrayHeaderLines.push('#endif');
arrayHeaderLines.push(''); arrayHeaderLines.push('');
arrayHeaderLines.push('#endif /* SPINE_C_ARRAYS_H */'); arrayHeaderLines.push('#endif /* SPINE_C_ARRAYS_H */');
arrayHeaderLines.push('');
} }
// Generate source // Generate source
@ -325,6 +329,7 @@ export class CWriter {
lines.push('#endif'); lines.push('#endif');
lines.push(''); lines.push('');
lines.push('#endif // SPINE_C_TYPES_H'); lines.push('#endif // SPINE_C_TYPES_H');
lines.push('');
fs.writeFileSync(headerPath, lines.join('\n')); fs.writeFileSync(headerPath, lines.join('\n'));
} }

View File

@ -55,10 +55,10 @@ typedef void* (*spine_texture_loader_load_func)(const char *path);
typedef void (*spine_texture_loader_unload_func)(void *texture); typedef void (*spine_texture_loader_unload_func)(void *texture);
// Version functions // Version functions
SPINE_C_API int32_t spine_major_version(); SPINE_C_API int32_t spine_major_version(void);
SPINE_C_API int32_t spine_minor_version(); SPINE_C_API int32_t spine_minor_version(void);
SPINE_C_API void spine_enable_debug_extension(bool enable); SPINE_C_API void spine_enable_debug_extension(bool enable);
SPINE_C_API void spine_report_leaks(); SPINE_C_API void spine_report_leaks(void);
// Bounds functions // Bounds functions
SPINE_C_API float spine_bounds_get_x(spine_bounds bounds); SPINE_C_API float spine_bounds_get_x(spine_bounds bounds);
@ -98,7 +98,7 @@ SPINE_C_API spine_animation_state_data spine_skeleton_drawable_get_animation_sta
SPINE_C_API spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable); SPINE_C_API spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable);
// Skin entries functions // Skin entries functions
SPINE_C_API spine_skin_entries spine_skin_entries_create(); SPINE_C_API spine_skin_entries spine_skin_entries_create(void);
SPINE_C_API void spine_skin_entries_dispose(spine_skin_entries entries); SPINE_C_API void spine_skin_entries_dispose(spine_skin_entries entries);
SPINE_C_API int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries); SPINE_C_API int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries);
SPINE_C_API spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index); SPINE_C_API spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index);

View File

@ -2,7 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <spine-c.h> #include <spine-c.h>
int main() { int main(int argc, char *argv[]) {
printf("Testing spine-c-new...\n"); printf("Testing spine-c-new...\n");
// Test version functions // Test version functions

View File

@ -32,10 +32,165 @@
#include <spine/Extension.h> #include <spine/Extension.h>
#include <spine/Array.h> #include <spine/Array.h>
#include <spine/HashMap.h>
namespace spine { namespace spine {
// Need a copy as HashMap extends SpineObject, which would trigger
// infinite recursion when used in DebugExtension
template<typename K, typename V>
class DebugHashMap {
private:
class DebugEntry;
public:
class SP_API DebugPair {
public:
explicit DebugPair(K &k, V &v) : key(k), value(v) {}
K &key;
V &value;
};
class SP_API DebugEntries {
public:
friend class DebugHashMap;
explicit DebugEntries(DebugEntry *entry) : _hasChecked(false) {
_start.next = entry;
_entry = &_start;
}
DebugPair next() {
assert(_entry);
assert(_hasChecked);
_entry = _entry->next;
DebugPair pair(_entry->_key, _entry->_value);
_hasChecked = false;
return pair;
}
bool hasNext() {
_hasChecked = true;
return _entry->next;
}
private:
bool _hasChecked;
DebugEntry _start;
DebugEntry *_entry;
};
DebugHashMap() :
_head(NULL),
_size(0) {
}
~DebugHashMap() {
clear();
}
void clear() {
for (DebugEntry *entry = _head; entry != NULL;) {
DebugEntry *next = entry->next;
delete entry;
entry = next;
}
_head = NULL;
_size = 0;
}
size_t size() {
return _size;
}
void put(const K &key, const V &value) {
DebugEntry *entry = find(key);
if (entry) {
entry->_key = key;
entry->_value = value;
} else {
entry = new DebugEntry();
entry->_key = key;
entry->_value = value;
DebugEntry *oldHead = _head;
if (oldHead) {
_head = entry;
oldHead->prev = entry;
entry->next = oldHead;
} else {
_head = entry;
}
_size++;
}
}
bool addAll(Array <K> &keys, const V &value) {
size_t oldSize = _size;
for (size_t i = 0; i < keys.size(); i++) {
put(keys[i], value);
}
return _size != oldSize;
}
bool containsKey(const K &key) {
return find(key) != NULL;
}
bool remove(const K &key) {
DebugEntry *entry = find(key);
if (!entry) return false;
DebugEntry *prev = entry->prev;
DebugEntry *next = entry->next;
if (prev) prev->next = next;
else _head = next;
if (next) next->prev = entry->prev;
delete entry;
_size--;
return true;
}
V operator[](const K &key) {
DebugEntry *entry = find(key);
if (entry) return entry->_value;
else {
assert(false);
return 0;
}
}
DebugEntries getEntries() const {
return DebugEntries(_head);
}
private:
DebugEntry *find(const K &key) {
for (DebugEntry *entry = _head; entry != NULL; entry = entry->next) {
if (entry->_key == key)
return entry;
}
return NULL;
}
class SP_API DebugEntry {
public:
K _key;
V _value;
DebugEntry *next;
DebugEntry *prev;
DebugEntry() : next(NULL), prev(NULL) {}
};
DebugEntry *_head;
size_t _size;
};
class SP_API DebugExtension : public SpineExtension { class SP_API DebugExtension : public SpineExtension {
struct Allocation { struct Allocation {
void *address; void *address;
@ -56,9 +211,9 @@ namespace spine {
} }
void reportLeaks() { void reportLeaks() {
HashMap<void *, Allocation>::Entries entries = _allocated.getEntries(); DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<void *, Allocation>::Pair pair = entries.next(); DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
printf("\"%s:%i (%zu bytes at %p)\n", pair.value.fileName, pair.value.line, pair.value.size, printf("\"%s:%i (%zu bytes at %p)\n", pair.value.fileName, pair.value.line, pair.value.size,
pair.value.address); pair.value.address);
} }
@ -90,9 +245,9 @@ namespace spine {
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) { virtual void *_realloc(void *ptr, size_t size, const char *file, int line) {
if (_allocated.containsKey(ptr)) { if (_allocated.containsKey(ptr)) {
// Find and store the size before removing // Find and store the size before removing
HashMap<void *, Allocation>::Entries entries = _allocated.getEntries(); DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<void *, Allocation>::Pair pair = entries.next(); DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
if (pair.key == ptr) { if (pair.key == ptr) {
_usedMemory -= pair.value.size; _usedMemory -= pair.value.size;
break; break;
@ -112,9 +267,9 @@ namespace spine {
_extension->_free(mem, file, line); _extension->_free(mem, file, line);
_frees++; _frees++;
// Find and store the size before removing // Find and store the size before removing
HashMap<void *, Allocation>::Entries entries = _allocated.getEntries(); DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) { while (entries.hasNext()) {
HashMap<void *, Allocation>::Pair pair = entries.next(); DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
if (pair.key == mem) { if (pair.key == mem) {
_usedMemory -= pair.value.size; _usedMemory -= pair.value.size;
break; break;
@ -146,7 +301,7 @@ namespace spine {
private: private:
SpineExtension *_extension; SpineExtension *_extension;
HashMap<void *, Allocation> _allocated; DebugHashMap<void *, Allocation> _allocated;
size_t _allocations; size_t _allocations;
size_t _reallocations; size_t _reallocations;
size_t _frees; size_t _frees;

View File

@ -60,7 +60,7 @@ namespace spine {
public: public:
friend class HashMap; friend class HashMap;
explicit Entries(Entry *entry) : _entry(NULL), _hasChecked(false) { explicit Entries(Entry *entry) : _hasChecked(false) {
_start.next = entry; _start.next = entry;
_entry = &_start; _entry = &_start;
} }