BS版图形系统 - 整合C++到JS中
QQ: 282397369
几个月下来,JavaScript/TypeScript算是基本入门了,也能编一些自认为满意的效果。从正常预期来看,BS版能达到桌面应用的效果,这可作为一个方向。
图形的应用场合很多,画电路气路液路图只是其中一个。当然在做的过程中,也比较随意,突然发现可以先做思维导图,然后居然也实现了一个初版。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6a20a36127db26bd7d471167fe1d2307.png)
又有点心痒,准备把这个也做得专业一点,至少先达到百度脑图的效果,然后再加上一些实用功能。
顺便看了下百度脑图,觉得界面设计上比较好,其工具栏有初步的Ribbon风格。
那就先做一个Ribbon风格的工具栏先。
先还比较顺利,但慢慢却发现一个不大不小的问题,之前各按钮的排列对齐都是左对齐,居然出不了两行
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/003b30c182a1523cfbb91e2e3152cedd.png)
真是岂有此理。深究发现是计算位置时的逻辑要复杂一些,用TypeScripe进行内存操作、数组处理还比较麻烦(可能是还没有掌握相应知识点)。要是能用C++就好了。
感叹的时候,顺便在网上转了下,突然发现,用emscripten就可以把C++整合进来。
那就花两天时间把这个功能看看究竟。
C/C++面向WebAssembly编程
挑重点看了下这个教程,麻溜地实现了C++整合。中间也填了不少坑,但现在也忘了有哪些坑。
整合了结果,以后慢慢梳理。
基础东东就看上面的教程。以下内容就是一些知识点的调试汇总,两天时间就在折腾这个,中间过程给记不清了。
C++代码
#pragma region 调用JS函数
EMAPI(int) js_add(int a, int b);
EMAPI(void) js_console_log(int param);
#pragma end_region
#pragma region 一些通用功能函数
EMAPI(void) free_buf(void * buf) {
free(buf);
}
EMAPI(int) add(int a, int b) {
a = js_add(a, b) * a;
js_console_log(a);
return a * b * a + b;
}
EMAPI(const char *)get_string() {
const char * str = "Hello, wolrd! 你好,世界,归根结底是那帮孙子的!";
return str;
}
EMAPI(int *) fibonacci_M(int count) {
if (count <= 0) return NULL;
int* re = (int*)malloc(count * 4);
if (NULL == re) {
printf("Not enough memory.\n");
return NULL;
}
re[0] = 1;
int i0 = 0, i1 = 1;
for (int i = 1; i < count; i++){
re[i] = i0 + i1;
i0 = i1;
i1 = re[i];
}
return re;
}
#pragma end_region
#pragma region 测试函数
int globalValue_Int = 31;
double globalValue_Double = 3.1415926;
EMAPI(int *) get_int_ptr() {
return &globalValue_Int;
}
EMAPI(double *) get_double_ptr() {
return &globalValue_Double;
}
EMAPI(void) print_global_value() {
printf("C{globalValue_Int: %d}\n", globalValue_Int);
printf("C{globalValue_Double: %lf}\n", globalValue_Double);
}
#pragma end_region
EMAPI(int) main(int argc, char ** argv) { //
printf("Hello World from C++ by DrGraph!\n");
emscripten_run_script("console.log('你好,Emscripten! Printed from C++ via emscripten_run_script')");
// EASM(console.log(''));
return 0;
}
EMAPI(int) myFunction(int argc, char ** argv) { //
printf("从JS里调用C++函数\n");
return 1;
}
加上类的C++代码
enum NClassType {
ctBaseObject = 0
};
class TObject {
private:
std::atomic<int> refCount;
NClassType classType;
char * name;
public:
__fastcall TObject();
void __fastcall AddRef();
int __fastcall Release();
virtual const char * __fastcall GetHint();
virtual void __fastcall SetName(char * value) { name = value; }
virtual char * __fastcall GetName() { return name; }
};
#pragma region TObject
__fastcall TObject::TObject() {
refCount = 1;
classType = ctBaseObject;
name = (char *)("Default Object");
}
void __fastcall TObject::AddRef() {
++refCount;
}
int __fastcall TObject::Release() {
int t = --refCount;
if(t == 0) delete this;
return t;
}
const char * __fastcall TObject::GetHint() {
return "TObject";
}
#pragma end_region
#pragma region 输出供JS调用函数
EMAPI(TObject *) __fastcall New(int type) {
if(ctBaseObject == type)
return new TObject;
return NULL;
}
EMAPI(void) __fastcall Delete(TObject * object) {
delete object;
}
EMAPI(const char *) __fastcall GetProperty(TObject * object, char * propertyName) {
if(strcasecmp(propertyName, "Hint") == 0)
return object->GetHint();
if(strcasecmp(propertyName, "Name") == 0)
return object->GetName();
return "Undefined";
}
EMAPI(void) __fastcall SetProperty(TObject * object, char * propertyName, char * propertyValue) {
if(strcasecmp(propertyName, "Name") == 0)
object->SetName(propertyValue);
}
#pragma end_region
JS调用代码
estCPP() {
DrGraph.Debug(`_testFun(4, 6) = ${DrCPP.cpp._add(4, 6)}`);
let count = 20;
let fibo = new cPointer(DrCPP.cpp._fibonacci_M(count), NDataTypeC.int32, count);
if (fibo.ptr) {
console.log(fibo.toString());
fibo.Free();
}
let testI = new cPointer(DrCPP.cpp._get_int_ptr());
DrGraph.Debug(`global int value = ${testI.getValueAt(0)}`);
testI.setValueAt(0, 123);
let testD = new cPointer(DrCPP.cpp._get_double_ptr(), NDataTypeC.double);
DrGraph.Debug(`global double value = ${testD.getValueAt(0)}`);
testD.setValueAt(0, 123.456457);
this.cpp._print_global_value();
var ptr = DrCPP.cpp._get_string();
var str = DrCPP.cpp.UTF8ToString(ptr);
DrGraph.Debug(`${str} 长度为 ${DrCPP.cpp.lengthBytesUTF8(str)} [汉字长度为3!!!]`, "字符串");
var result = DrCPP.cpp.ccall('add', 'number', ['number', 'number'], [13, 42]);
console.log(result, "通过ccall调用");
str = 'The answer is:42';
DrCPP.cpp.ccall('print_string', 'null', ['string'], [str]);
var s = DrCPP.cpp._Sum_New();
console.log(DrCPP.cpp._Sum_Inc(s, 29));
DrCPP.cpp._Sum_Delete(s);
let object = DrCPP.cpp.New(0);
DrGraph.Debug(object);
DrGraph.Debug(DrCPP.cpp.GetProperty(object, "name"));
DrCPP.cpp.SetProperty(object, "name", "Name Changed by DrGraph");
DrGraph.Debug(DrCPP.cpp.GetProperty(object, "name"));
DrCPP.cpp.Delete(object);
}
运行结果
这C++的运行结果就整合进来了。明天尝试做Ribbon风格工具栏。