Builds, runs, and tests succeed*
*Tests only succeed if you run them in a single-threaded instance. With cargo this means invoking them as `cargo run -- --test-threads=1`. There is an instance of global state in the Sword engine with the VersificationMgr class that can easily cause a race condition. Since VersificationMgr is intended to be a global singleton, when it is first being instantiated the pointer is null. Sometimes the tests get into that method at the same time and overwrite one another with the instance of the manager, thus causing some of the VerseKeys that get instantiated to be invalid. TODO: On the Rust side of the code, create an instance of the VersificationMgr before allowing any VerseKey objects to be created. Probably also necessary to run it before allowing SWMgr to be instantiated, as well, just to be safe.
This commit is contained in:
+61
-23
@@ -1,9 +1,8 @@
|
||||
#include "versekey.h"
|
||||
#include <memory>
|
||||
#include <sword/versekey.h>
|
||||
|
||||
namespace sword_rs {
|
||||
// Key methods
|
||||
// VerseKey methods - all include null pointer checks for safety
|
||||
uint8_t VerseKey::get_error() const {
|
||||
return ptr ? ptr->getError() : 0;
|
||||
}
|
||||
@@ -46,7 +45,6 @@ namespace sword_rs {
|
||||
}
|
||||
}
|
||||
|
||||
// VerseKey specific methods
|
||||
rust::String VerseKey::get_book_name() const {
|
||||
return ptr ? rust::String(ptr->getBookName()) : rust::String("");
|
||||
}
|
||||
@@ -153,35 +151,75 @@ namespace sword_rs {
|
||||
}
|
||||
}
|
||||
|
||||
// Explicit cleanup method
|
||||
void VerseKey::cleanup() {
|
||||
if (owned && ptr) {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
owned = false;
|
||||
bool VerseKey::is_valid() const {
|
||||
return ptr != nullptr;
|
||||
}
|
||||
|
||||
// Factory function for self-managing VerseKey
|
||||
VerseKey* new_verse_key() {
|
||||
try {
|
||||
auto sword_key = new sword::VerseKey();
|
||||
auto wrapper = new VerseKey();
|
||||
wrapper->ptr = sword_key;
|
||||
wrapper->managed = false; // self-managing
|
||||
return wrapper;
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Factory functions
|
||||
std::unique_ptr<VerseKey> new_verse_key() {
|
||||
auto verse_key = std::unique_ptr<VerseKey>(new VerseKey{new sword::VerseKey(), true});
|
||||
return verse_key;
|
||||
// Factory function for self-managing VerseKey from text
|
||||
VerseKey* new_verse_key_from_text(const rust::String text) {
|
||||
try {
|
||||
auto sword_key = new sword::VerseKey(std::string(text).c_str());
|
||||
auto wrapper = new VerseKey();
|
||||
wrapper->ptr = sword_key;
|
||||
wrapper->managed = false; // self-managing
|
||||
return wrapper;
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<VerseKey> new_verse_key_from_text(const rust::String& text) {
|
||||
auto verse_key = std::unique_ptr<VerseKey>(new VerseKey{new sword::VerseKey(std::string(text).c_str()), true});
|
||||
return verse_key;
|
||||
// Creates a managed VerseKey wrapper from module's sword::VerseKey
|
||||
VerseKey* get_verse_key_wrapper(SwordVerseKey* sword_key) {
|
||||
if (!sword_key) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
auto wrapper = new VerseKey();
|
||||
wrapper->ptr = sword_key;
|
||||
wrapper->managed = true; // managed by external code
|
||||
return wrapper;
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
VerseKey verse_key_from_borrowed(sword::VerseKey* key) {
|
||||
VerseKey verse_key{key, false};
|
||||
return verse_key;
|
||||
// Clone function - always returns self-managing copy using copy constructor
|
||||
VerseKey* clone_verse_key(const VerseKey& source) {
|
||||
if (!source.ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
// Create a new sword::VerseKey using copy constructor
|
||||
auto sword_key = new sword::VerseKey(*source.ptr);
|
||||
auto wrapper = new VerseKey();
|
||||
wrapper->ptr = sword_key;
|
||||
wrapper->managed = false; // clones are always self-managing
|
||||
return wrapper;
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void delete_verse_key(VerseKey* key) {
|
||||
if (key) {
|
||||
key->cleanup();
|
||||
delete key;
|
||||
// Delete function for VerseKey wrappers
|
||||
void delete_verse_key(VerseKey* verse_key) {
|
||||
if (verse_key) {
|
||||
verse_key->cleanup();
|
||||
delete verse_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user