Fix bugs with powders and migrate constants to c++
This commit is contained in:
parent
3a5876ceba
commit
1c07cd0911
11 changed files with 103 additions and 86 deletions
|
@ -1,5 +1,6 @@
|
|||
CXX=emcc
|
||||
CXXFLAGS=-sENVIRONMENT=web -sSINGLE_FILE -sMODULARIZE -sWASM_ASYNC_COMPILATION=0 -sALLOW_MEMORY_GROWTH -lembind --closure 1
|
||||
#CXXFLAGS=-sENVIRONMENT=web -sSINGLE_FILE -sMODULARIZE -sWASM_ASYNC_COMPILATION=0 -sALLOW_MEMORY_GROWTH -lembind --closure 1
|
||||
CXXFLAGS=-sENVIRONMENT=web -sSINGLE_FILE -sMODULARIZE -sWASM_ASYNC_COMPILATION=0 -sALLOW_MEMORY_GROWTH -lembind -g
|
||||
|
||||
all: utils.js powders.js
|
||||
|
||||
|
|
36
js/c++/js_helpers.h
Normal file
36
js/c++/js_helpers.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/bind.h>
|
||||
using namespace emscripten;
|
||||
|
||||
#define MAP_TO_JS_FUNC(map_name) \
|
||||
auto make_ ## map_name () { \
|
||||
return map_to_js(map_name); \
|
||||
}
|
||||
|
||||
#define VEC_TO_JS_FUNC(vec_name) \
|
||||
auto make_ ## vec_name () { \
|
||||
return vector_to_js(vec_name); \
|
||||
}
|
||||
|
||||
// NOTE!!! For some stupid reason you can'd declare constants with these...
|
||||
template<class Container>
|
||||
val map_to_js(const Container& input_map) {
|
||||
static val Map = val::global("Map");
|
||||
val retval = Map.new_();
|
||||
for (const auto& [k, v] : input_map) {
|
||||
retval.call<val>("set", k, v);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template<class Container>
|
||||
val vector_to_js(const Container& input_vec) {
|
||||
val retval = val::array();
|
||||
for (const auto& x : input_vec) {
|
||||
retval.call<void>("push", x);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,31 +8,32 @@ using namespace emscripten;
|
|||
|
||||
#include <cstring>
|
||||
|
||||
const std::map<std::string, int> powderIDs = []{
|
||||
const std::map<std::string, int> powder_IDs = []{
|
||||
std::map<std::string, int> m;
|
||||
int powder_id = 0;
|
||||
for (const auto& x : skp_elements) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
m[x + std::to_string(i)] = i;
|
||||
m[(char)toupper(x[0]) + std::to_string(i)] = i;
|
||||
for (int i = 1; i <= 6; ++i) {
|
||||
m[x + std::to_string(i)] = powder_id;
|
||||
m[(char)toupper(x[0]) + std::to_string(i)] = powder_id;
|
||||
powder_id++;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}();
|
||||
|
||||
const std::map<int, std::string> powderNames = []{
|
||||
const std::map<int, std::string> powder_names = []{
|
||||
std::map<int, std::string> m;
|
||||
for (const auto& kv : powderIDs) {
|
||||
for (const auto& kv : powder_IDs) {
|
||||
m[kv.second] = kv.first;
|
||||
}
|
||||
return m;
|
||||
}();
|
||||
|
||||
Powder::Powder() {}
|
||||
Powder::Powder(int min, int max, int conv, int defPlus, int defMinus) :
|
||||
min(min), max(max), convert(conv), defPlus(defPlus), defMinus(defMinus) {}
|
||||
|
||||
const std::vector<Powder> powderStats = []{
|
||||
const std::vector<Powder> powder_stats = []{
|
||||
auto p = [](int a, int b, int c, int d, int e){ return Powder(a,b,c,d,e); };
|
||||
return std::vector<Powder> {
|
||||
p(3,6,17,2,1), p(5,8,21,4,2), p(6,10,25,8,3), p(7,10,31,14,5), p(9,11,38,22,9), p(11,13,46,30,13),
|
||||
|
@ -44,6 +45,24 @@ const std::vector<Powder> powderStats = []{
|
|||
}();
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "js_helpers.h"
|
||||
#include <iostream>
|
||||
|
||||
MAP_TO_JS_FUNC(powder_IDs);
|
||||
MAP_TO_JS_FUNC(powder_names);
|
||||
VEC_TO_JS_FUNC(powder_stats);
|
||||
|
||||
EMSCRIPTEN_BINDINGS(powders) {
|
||||
function("powderIDs", &make_powder_IDs);
|
||||
function("powderNames", &make_powder_names);
|
||||
value_object<Powder>("Powder")
|
||||
.field("min", &Powder::min)
|
||||
.field("max", &Powder::max)
|
||||
.field("convert", &Powder::convert)
|
||||
.field("defPlus", &Powder::defPlus)
|
||||
.field("defMinus", &Powder::defMinus)
|
||||
;
|
||||
function("powderStats", make_powder_stats);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern const std::map<std::string, int> powderIDs;
|
||||
extern const std::map<int, std::string> powderNames;
|
||||
extern const std::map<std::string, int> powder_IDs;
|
||||
extern const std::map<int, std::string> powder_names;
|
||||
|
||||
struct Powder {
|
||||
int min;
|
||||
|
@ -13,7 +13,8 @@ struct Powder {
|
|||
int defPlus;
|
||||
int defMinus;
|
||||
|
||||
Powder();
|
||||
Powder(int min, int max, int conv, int defPlus, int defMinus);
|
||||
};
|
||||
|
||||
extern const std::vector<Powder> powderStats;
|
||||
extern const std::vector<Powder> powder_stats;
|
||||
|
|
|
@ -1,38 +1,9 @@
|
|||
|
||||
const _module_powders = create_powders();
|
||||
|
||||
let powderIDs = new Map();
|
||||
let powderNames = new Map();
|
||||
let _powderID = 0;
|
||||
for (const x of skp_elements) {
|
||||
for (let i = 1; i <= 6; ++i) {
|
||||
// Support both upper and lowercase, I guess.
|
||||
powderIDs.set(x.toUpperCase()+i, _powderID);
|
||||
powderIDs.set(x+i, _powderID);
|
||||
powderNames.set(_powderID, x+i);
|
||||
_powderID++;
|
||||
}
|
||||
}
|
||||
|
||||
// Ordering: [dmgMin, dmgMax, convert, defPlus, defMinus (+6 mod 5)]
|
||||
class Powder {
|
||||
constructor(min, max, convert, defPlus, defMinus) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.convert = convert;
|
||||
this.defPlus = defPlus;
|
||||
this.defMinus = defMinus;
|
||||
}
|
||||
}
|
||||
function _p(a,b,c,d,e) { return new Powder(a,b,c,d,e); } //bruh moment
|
||||
|
||||
let powderStats = [
|
||||
_p(3,6,17,2,1), _p(5,8,21,4,2), _p(6,10,25,8,3), _p(7,10,31,14,5), _p(9,11,38,22,9), _p(11,13,46,30,13),
|
||||
_p(1,8,9,3,1), _p(1,12,11,5,1), _p(2,15,13,9,2), _p(3,15,17,14,4), _p(4,17,22,20,7), _p(5,20,28,28,10),
|
||||
_p(3,4,13,3,1), _p(4,6,15,6,1), _p(5,8,17,11,2), _p(6,8,21,18,4), _p(7,10,26,28,7), _p(9,11,32,40,10),
|
||||
_p(2,5,14,3,1), _p(4,8,16,5,2), _p(5,9,19,9,3), _p(6,9,24,16,5), _p(8,10,30,25,9), _p(10,12,37,36,13),
|
||||
_p(2,6,11,3,1), _p(3,10,14,6,2), _p(4,11,17,10,3), _p(5,11,22,16,5), _p(7,12,28,24,9), _p(8,14,35,34,13)
|
||||
];
|
||||
const powderIDs = _module_powders.powderIDs();
|
||||
const powderNames = _module_powders.powderNames();
|
||||
const powderStats = _module_powders.powderStats();
|
||||
|
||||
//Ordering: [weapon special name, weapon special effects, armor special name, armor special effects]
|
||||
class PowderSpecial{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/bind.h>
|
||||
using namespace emscripten;
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -45,7 +44,9 @@ std::vector<std::vector<T>> perm(std::vector<T> a) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
using namespace emscripten;
|
||||
val __perm_wrap(val a) {
|
||||
const size_t l = a["length"].as<size_t>();
|
||||
std::vector<val> things;
|
||||
|
@ -65,26 +66,6 @@ val __perm_wrap(val a) {
|
|||
return return_array;
|
||||
}
|
||||
|
||||
/** Appends data to the BitVector.
|
||||
*
|
||||
* @param {Number | String} data - The data to append.
|
||||
* @param {Number} length - The length, in bits, of the new data. This is ignored if data is a string.
|
||||
*/
|
||||
void __BitVector_append(BitVector& self, val data, val length) {
|
||||
if (data.typeOf().as<std::string>() == "string") {
|
||||
self.append(data.as<std::string>());
|
||||
return;
|
||||
}
|
||||
if (data.typeOf().as<std::string>() == "number") {
|
||||
size_t num = data.as<size_t>();
|
||||
//if (num >= 1<<bitvec_data_s) {
|
||||
// throw std::range_error("Numerical data has to fit within a 32-bit integer range to append to a BitVector.");
|
||||
//}
|
||||
self.append(num, length.as<size_t>());
|
||||
return;
|
||||
}
|
||||
throw std::invalid_argument("BitVector must be appended with a Number or a B64 String");
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(utils) {
|
||||
function("clamp", &clamp);
|
||||
|
@ -97,6 +78,7 @@ EMSCRIPTEN_BINDINGS(utils) {
|
|||
class_<BitVector>("BitVector")
|
||||
.constructor<std::string>()
|
||||
.constructor<size_t, size_t>()
|
||||
.property("length", &BitVector::length)
|
||||
.function("read_bit", &BitVector::read_bit)
|
||||
.function("slice", &BitVector::slice)
|
||||
.function("set_bit", &BitVector::set_bit)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Generate all permutations of a vector.
|
||||
*
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Base64 {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string fromIntN(unsigned int int32, int n) {
|
||||
std::string fromIntN(int int32, int n) {
|
||||
std::string result;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
result = digits[int32 & 0x3f] + result;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Base64 {
|
|||
|
||||
std::string fromIntV(unsigned int i);
|
||||
|
||||
std::string fromIntN(unsigned int i, int n);
|
||||
std::string fromIntN(int i, int n);
|
||||
|
||||
unsigned int toInt(std::string digitsStr);
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
#include <sstream>
|
||||
|
||||
BitVector::BitVector() {};
|
||||
BitVector::BitVector(const BitVector& other) : data(other.data), length(other.length) {};
|
||||
BitVector::BitVector(const BitVector& other) : data(other.data), _length(other.length()) {};
|
||||
|
||||
BitVector::BitVector(const std::string b64_data) {
|
||||
length = b64_data.length() * 6;
|
||||
data.reserve(length/bitvec_data_s + 1);
|
||||
_length = b64_data.length() * 6;
|
||||
data.reserve(_length/bitvec_data_s + 1);
|
||||
|
||||
bitvec_data_t scratch = 0;
|
||||
size_t bitvec_index = 0;
|
||||
|
@ -34,7 +34,7 @@ BitVector::BitVector(bitvec_data_t num, size_t length) {
|
|||
throw std::range_error("BitVector must have nonnegative length.");
|
||||
}
|
||||
data.push_back(num);
|
||||
this->length = length;
|
||||
this->_length = length;
|
||||
}
|
||||
|
||||
/** Return value of bit at index idx.
|
||||
|
@ -44,9 +44,9 @@ BitVector::BitVector(bitvec_data_t num, size_t length) {
|
|||
* @returns The bit value at position idx
|
||||
*/
|
||||
bool BitVector::read_bit(size_t idx) const {
|
||||
if (idx < 0 || idx >= length) {
|
||||
if (idx < 0 || idx >= length()) {
|
||||
std::stringstream ss;
|
||||
ss << "Cannot read bit outside the range of the BitVector. (" << idx << " > " << length << ")";
|
||||
ss << "Cannot read bit outside the range of the BitVector. (" << idx << " > " << length() << ")";
|
||||
throw std::range_error(ss.str());
|
||||
}
|
||||
return (data[idx / bitvec_data_s] & (1 << (idx % bitvec_data_s))) == 0 ? 0 : 1;
|
||||
|
@ -104,7 +104,7 @@ bitvec_data_t BitVector::slice(size_t start, size_t end) const {
|
|||
* @param {Number} idx - The index to set.
|
||||
*/
|
||||
void BitVector::set_bit(size_t idx) {
|
||||
if (idx < 0 || idx >= length) {
|
||||
if (idx < 0 || idx >= length()) {
|
||||
throw std::range_error("Cannot set bit outside the range of the BitVector.");
|
||||
}
|
||||
data[idx / bitvec_data_s] |= (1 << (idx % bitvec_data_s));
|
||||
|
@ -115,7 +115,7 @@ void BitVector::set_bit(size_t idx) {
|
|||
* @param {Number} idx - The index to clear.
|
||||
*/
|
||||
void BitVector::clear_bit(size_t idx) {
|
||||
if (idx < 0 || idx >= length) {
|
||||
if (idx < 0 || idx >= length()) {
|
||||
throw std::range_error("Cannot clear bit outside the range of the BitVector.");
|
||||
}
|
||||
data[idx / bitvec_data_s] &= ~(1 << (idx % bitvec_data_s));
|
||||
|
@ -126,12 +126,12 @@ void BitVector::clear_bit(size_t idx) {
|
|||
* @returns A b64 string representation of the BitVector.
|
||||
*/
|
||||
std::string BitVector::toB64() const {
|
||||
if (length == 0) {
|
||||
if (length() == 0) {
|
||||
return "";
|
||||
}
|
||||
std::stringstream b64_str;
|
||||
size_t i = 0;
|
||||
while (i < length) {
|
||||
while (i < length()) {
|
||||
b64_str << Base64::fromIntN(this->slice(i, i + 6), 1);
|
||||
i += 6;
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ std::string BitVector::toB64() const {
|
|||
*/
|
||||
std::string BitVector::toString() const {
|
||||
std::stringstream ret_str;
|
||||
for (size_t i = length; i != 0; --i) {
|
||||
for (size_t i = length(); i != 0; --i) {
|
||||
ret_str << (this->read_bit(i-1) ? "1": "0");
|
||||
}
|
||||
return ret_str.str();
|
||||
|
@ -157,7 +157,7 @@ std::string BitVector::toString() const {
|
|||
*/
|
||||
std::string BitVector::toStringR() const {
|
||||
std::stringstream ret_str;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
for (size_t i = 0; i < length(); ++i) {
|
||||
ret_str << (this->read_bit(i) ? "1": "0");
|
||||
}
|
||||
return ret_str.str();
|
||||
|
@ -167,22 +167,22 @@ void BitVector::append(const BitVector& other) {
|
|||
data.reserve(data.size() + other.data.size());
|
||||
|
||||
size_t other_index = 0;
|
||||
if (this->length % bitvec_data_s != 0) {
|
||||
if (this->length() % bitvec_data_s != 0) {
|
||||
// fill in the last block.
|
||||
bitvec_data_t scratch = data[data.size() - 1];
|
||||
size_t bits_remaining = bitvec_data_s - (this->length % bitvec_data_s);
|
||||
size_t bits_remaining = bitvec_data_s - (this->length() % bitvec_data_s);
|
||||
|
||||
size_t n = std::min(other.length, bits_remaining);
|
||||
scratch |= (other.slice(0, n) << (this->length % bitvec_data_s));
|
||||
size_t n = std::min(other.length(), bits_remaining);
|
||||
scratch |= (other.slice(0, n) << (this->length() % bitvec_data_s));
|
||||
data[data.size() - 1] = scratch;
|
||||
other_index += n;
|
||||
}
|
||||
while (other_index != other.length) {
|
||||
size_t n = std::min(other.length - other_index, (size_t)bitvec_data_s);
|
||||
while (other_index != other.length()) {
|
||||
size_t n = std::min(other.length() - other_index, (size_t)bitvec_data_s);
|
||||
data.push_back(other.slice(other_index, other_index + n));
|
||||
other_index += n;
|
||||
}
|
||||
this->length += other.length;
|
||||
this->_length += other.length();
|
||||
}
|
||||
|
||||
void BitVector::append(const std::string b64_data) {
|
||||
|
@ -194,3 +194,5 @@ void BitVector::append(bitvec_data_t num, size_t length) {
|
|||
BitVector tmp(num, length);
|
||||
this->append(tmp);
|
||||
}
|
||||
|
||||
size_t BitVector::length() const { return this->_length; }
|
||||
|
|
|
@ -84,7 +84,10 @@ public:
|
|||
void append(const std::string b64_data);
|
||||
void append(bitvec_data_t num, size_t length);
|
||||
|
||||
// length getter.
|
||||
size_t length() const;
|
||||
|
||||
private:
|
||||
std::vector<bitvec_data_t> data;
|
||||
size_t length;
|
||||
size_t _length;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue