Browse Source

新增cpp_server

master
hejl 2 months ago
parent
commit
cdbed3d535
  1. 1
      .gitignore
  2. 3
      .gitmodules
  3. 22
      cpp_server/.vscode/c_cpp_properties.json
  4. 9
      cpp_server/.vscode/settings.json
  5. 35
      cpp_server/CMakeLists.txt
  6. 1
      cpp_server/RuntimeCompiledCPlusPlus
  7. 7
      cpp_server/cmake/FindRCCPP.cmake
  8. 21
      cpp_server/src/controllers/UserController.cpp
  9. 22
      cpp_server/src/controllers/UserController.h
  10. 48
      cpp_server/src/main.cpp
  11. BIN
      documents/~$ UFT模块迁移方案.docx
  12. 35
      win_text_editor/lib/menus/app_menu.dart
  13. 5
      win_text_editor/lib/menus/menu_actions.dart
  14. 4
      win_text_editor/lib/menus/menu_constants.dart
  15. 1
      win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart
  16. 107
      win_text_editor/lib/modules/demo/widgets/demo_view.dart
  17. 5
      win_text_editor/lib/modules/module_router.dart
  18. 13
      win_text_editor/lib/modules/uft_file/controllers/uft_file_controller.dart
  19. 47
      win_text_editor/lib/modules/uft_file/widgets/uft_file_view.dart

1
.gitignore vendored

@ -6,3 +6,4 @@ @@ -6,3 +6,4 @@
/win_text_editor/macos
/win_text_editor/web
/win_text_editor/windows/runner
/cpp_server/swagger

3
.gitmodules vendored

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
[submodule "cpp_server/RuntimeCompiledCPlusPlus"]
path = cpp_server/RuntimeCompiledCPlusPlus
url = https://github.com/RuntimeCompiledCPlusPlus/RuntimeCompiledCPlusPlus.git

22
cpp_server/.vscode/c_cpp_properties.json vendored

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"D:/aigc/vcpkg/installed/x64-windows/include/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.18362.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}

9
cpp_server/.vscode/settings.json vendored

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
{
"cmake.configureOnOpen": true,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.generator": "Visual Studio 16 2019 Win64",
"C_Cpp.default.cppStandard": "c++11",
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "D:/aigc/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}

35
cpp_server/CMakeLists.txt

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.15)
project(MyDrogonProject)
# C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#
find_package(Drogon CONFIG REQUIRED)
# RCC++
add_subdirectory(RuntimeCompiledCPlusPlus)
#
set(RUNTIME_COMPILED_SOURCES
src/controllers/UserController.cpp
)
#
add_executable(${PROJECT_NAME}
src/main.cpp
${RUNTIME_COMPILED_SOURCES}
)
# RCC++
runtime_compile_setup(
TARGET ${PROJECT_NAME}
SOURCES ${RUNTIME_COMPILED_SOURCES}
)
#
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)
# Swagger UI
file(COPY swagger DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

1
cpp_server/RuntimeCompiledCPlusPlus

@ -0,0 +1 @@ @@ -0,0 +1 @@
Subproject commit a93b46d32052f16f2f0e647ef180ac92afa88764

7
cpp_server/cmake/FindRCCPP.cmake

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
# RCC++
find_path(RCCPP_INCLUDE_DIR RuntimeObjectSystem.h
PATHS ${CMAKE_SOURCE_DIR}/RuntimeCompiledCPlusPlus/RuntimeObjectSystem
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RCCPP DEFAULT_MSG RCCPP_INCLUDE_DIR)

21
cpp_server/src/controllers/UserController.cpp

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
#include "UserController.h"
RCCPP_RUNTIME_TYPE_REGISTRATION(UserController)
/**
* @brief
* @route GET /api/v1/users
* @response 200 JSON
*/
void UserController::asyncHandleHttpRequest(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback)
{
Json::Value ret;
ret["status"] = "ok";
ret["message"] = "Hello from RCC++!";
ret["data"] = Json::arrayValue;
auto resp = drogon::HttpResponse::newHttpJsonResponse(ret);
callback(resp);
}

22
cpp_server/src/controllers/UserController.h

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
#pragma once
#include "RuntimeCompiledCPlusPlus/RuntimeObjectSystem/RuntimeObjectSystem.h"
#include <drogon/HttpSimpleController.h>
class UserController : public RCCpp::IObject,
public drogon::HttpSimpleController<UserController>
{
public:
UserController() { RCCpp::Construct(); }
virtual ~UserController() { RCCpp::Destruct(); }
RCCPP_RUNTIME_TYPE_DECLARATION(UserController)
void asyncHandleHttpRequest(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
PATH_ADD("/api/v1/users", drogon::Get);
PATH_LIST_END
};

48
cpp_server/src/main.cpp

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
#include <drogon/drogon.h>
#include "RuntimeCompiledCPlusPlus/RuntimeObjectSystem/RuntimeObjectSystem.h"
#include "controllers/UserController.h"
class SystemTable : public RCCpp::ISystemTable
{
public:
virtual void Log(RCCpp::LogSystem::LogType type, const char *pText) override
{
if (type == RCCpp::LogSystem::ERROR)
LOG_ERROR << pText;
else
LOG_INFO << pText;
}
};
int main()
{
// 初始化RCC++
SystemTable systemTable;
RCCpp::RuntimeObjectSystem runtimeObjectSystem;
runtimeObjectSystem.Initialise(&systemTable, nullptr);
// 设置Swagger
drogon::app().registerController(std::make_shared<drogon::SwaggerController>());
// 加载热重载控制器
runtimeObjectSystem.GetObjectFactorySystem()->LoadObjectFactory(
"UserController", true);
// 设置文档路径
drogon::app().setDocumentRoot("./swagger");
drogon::app().setDocumentRoot("/api/v1/docs");
// 启动日志
LOG_INFO << "Server running on http://127.0.0.1:8848";
LOG_INFO << "Swagger UI: http://127.0.0.1:8848/api/v1/docs";
LOG_INFO << "Hot reload enabled - modify controller files to see changes";
// 主循环
drogon::app()
.addListener("0.0.0.0", 8848)
.setThreadNum(4)
.run();
runtimeObjectSystem.CleanObjectFiles();
return 0;
}

BIN
documents/~$ UFT模块迁移方案.docx

Binary file not shown.

35
win_text_editor/lib/menus/app_menu.dart

@ -15,6 +15,7 @@ class AppMenu extends StatelessWidget { @@ -15,6 +15,7 @@ class AppMenu extends StatelessWidget {
children: [
_buildMenuButton(context, '文件', _buildFileMenuItems()),
_buildMenuButton(context, '工具', _buildToolsMenuItems()),
_buildMenuButton(context, 'AIGC', _buildAigcMenuItems()),
_buildMenuButton(context, '编辑', _buildEditMenuItems()),
_buildMenuButton(context, '窗口', _buildWindowMenuItems()),
_buildMenuButton(context, '帮助', _buildHelpMenuItems()),
@ -25,12 +26,36 @@ class AppMenu extends StatelessWidget { @@ -25,12 +26,36 @@ class AppMenu extends StatelessWidget {
List<PopupMenuEntry<String>> _buildToolsMenuItems() {
return [
const PopupMenuItem<String>(value: MenuConstants.templateParser, child: Text('XML解析')),
const PopupMenuItem<String>(value: MenuConstants.contentSearch, child: Text('内容搜索')),
const PopupMenuItem<String>(value: MenuConstants.dataCompare, child: Text('数据对比')),
const PopupMenuItem<String>(value: MenuConstants.dataFormat, child: Text('数据格式化')),
const PopupMenuItem<String>(
value: MenuConstants.templateParser,
child: ListTile(leading: Icon(Icons.auto_awesome_mosaic), title: Text('XML解析')),
),
const PopupMenuItem<String>(
value: MenuConstants.contentSearch,
child: ListTile(leading: Icon(Icons.search), title: Text('内容搜索')),
),
const PopupMenuItem<String>(
value: MenuConstants.dataCompare,
child: ListTile(leading: Icon(Icons.compare), title: Text('数据对比')),
),
const PopupMenuItem<String>(
value: MenuConstants.dataFormat,
child: ListTile(leading: Icon(Icons.date_range), title: Text('数据格式化')),
),
const PopupMenuDivider(),
const PopupMenuItem<String>(value: MenuConstants.demo, child: Text('Demo')),
const PopupMenuItem<String>(
value: MenuConstants.demo,
child: ListTile(leading: Icon(Icons.code), title: Text('Demo')),
),
];
}
List<PopupMenuEntry<String>> _buildAigcMenuItems() {
return [
const PopupMenuItem<String>(
value: MenuConstants.uftFile,
child: ListTile(leading: Icon(Icons.drive_file_move), title: Text('UFT文件')),
),
];
}

5
win_text_editor/lib/menus/menu_actions.dart

@ -16,6 +16,7 @@ class MenuActions { @@ -16,6 +16,7 @@ class MenuActions {
MenuConstants.templateParser: _openTemplateParser,
MenuConstants.dataFormat: _dataFormat,
MenuConstants.dataCompare: _dataCompare,
MenuConstants.uftFile: _openUftFile,
MenuConstants.demo: _demo,
MenuConstants.exit: _exitApplication,
};
@ -47,6 +48,10 @@ class MenuActions { @@ -47,6 +48,10 @@ class MenuActions {
await _openOrActivateTab(context, "XML解析", RouterKey.templateParser, Icons.auto_awesome_mosaic);
}
static Future<void> _openUftFile(BuildContext context) async {
await _openOrActivateTab(context, "UFT文件", RouterKey.uftFile, Icons.drive_file_move);
}
static Future<void> _dataFormat(BuildContext context) async {
await _openOrActivateTab(context, "数据格式化", RouterKey.dataFormat, Icons.date_range);
}

4
win_text_editor/lib/menus/menu_constants.dart

@ -19,6 +19,10 @@ class MenuConstants { @@ -19,6 +19,10 @@ class MenuConstants {
static const String dataCompare = 'data_compare';
static const String demo = 'demo';
// AIGC菜单项
static const String aigc = 'aigc';
static const String uftFile = 'uftFile';
//
static const String undo = 'undo';
static const String redo = 'redo';

1
win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart

@ -3,7 +3,6 @@ import 'dart:io'; @@ -3,7 +3,6 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:win_text_editor/framework/controllers/logger.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import 'package:path/path.dart' as path;
class DataCompareController extends BaseContentController {
List<String> leftColumns = [];

107
win_text_editor/lib/modules/demo/widgets/demo_view.dart

@ -42,111 +42,6 @@ class _DemoViewState extends State<DemoView> { @@ -42,111 +42,6 @@ class _DemoViewState extends State<DemoView> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: _controller,
child: const Padding(padding: EdgeInsets.all(8.0), child: ButtonPositionExample()),
);
}
}
class ButtonPositionExample extends StatefulWidget {
const ButtonPositionExample({Key? key}) : super(key: key);
@override
_ButtonPositionExampleState createState() => _ButtonPositionExampleState();
}
class _ButtonPositionExampleState extends State<ButtonPositionExample> {
// GlobalKey
final GlobalKey _buttonKey = GlobalKey();
//
String _buttonPosition = '未获取';
//
String _clickPosition = '未点击';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('按钮位置和点击坐标示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//
Text('按钮位置: $_buttonPosition'),
const SizedBox(height: 10),
//
Text('点击位置: $_clickPosition'),
const SizedBox(height: 30),
//
ElevatedButton(
key: _buttonKey,
onPressed: () {
_getButtonPosition();
},
child: const Text('获取按钮位置'),
),
const SizedBox(height: 20),
//
GestureDetector(
onTapDown: (TapDownDetails details) {
_getClickPosition(details);
},
child: Container(
padding: const EdgeInsets.all(16.0),
color: Colors.blue,
child: const Text('点击此处获取点击坐标', style: TextStyle(color: Colors.white)),
),
),
const SizedBox(height: 20),
//
Builder(
builder: (BuildContext context) {
return ElevatedButton(
onPressed: () {
// 使context.findRenderObject()
final RenderBox renderBox = context.findRenderObject() as RenderBox;
final position = renderBox.localToGlobal(Offset.zero);
setState(() {
_buttonPosition =
'按钮位置: (${position.dx.toStringAsFixed(2)}, ${position.dy.toStringAsFixed(2)})';
});
},
child: const Text('使用Builder获取按钮位置'),
);
},
),
],
),
),
);
}
//
void _getButtonPosition() {
final RenderBox renderBox = _buttonKey.currentContext?.findRenderObject() as RenderBox;
final position = renderBox.localToGlobal(Offset.zero);
setState(() {
_buttonPosition =
'按钮位置: (${position.dx.toStringAsFixed(2)}, ${position.dy.toStringAsFixed(2)})';
});
}
//
void _getClickPosition(TapDownDetails details) {
final RenderBox renderBox = context.findRenderObject() as RenderBox;
final position = renderBox.globalToLocal(details.globalPosition);
setState(() {
_clickPosition =
'点击位置: (${position.dx.toStringAsFixed(2)}, ${position.dy.toStringAsFixed(2)})';
});
return const Center(child: Text('demo'));
}
}

5
win_text_editor/lib/modules/module_router.dart

@ -7,6 +7,8 @@ import 'package:win_text_editor/modules/data_format/controllers/data_format_cont @@ -7,6 +7,8 @@ import 'package:win_text_editor/modules/data_format/controllers/data_format_cont
import 'package:win_text_editor/modules/data_format/widgets/data_format_view.dart';
import 'package:win_text_editor/modules/demo/controllers/demo_controller.dart';
import 'package:win_text_editor/modules/demo/widgets/demo_view.dart';
import 'package:win_text_editor/modules/uft_file/controllers/uft_file_controller.dart';
import 'package:win_text_editor/modules/uft_file/widgets/uft_file_view.dart';
import 'package:win_text_editor/shared/base/base_content_controller.dart';
import 'package:win_text_editor/modules/content_search/controllers/content_search_controller.dart';
import 'package:win_text_editor/modules/template_parser/controllers/template_parser_controller.dart';
@ -19,6 +21,7 @@ class RouterKey { @@ -19,6 +21,7 @@ class RouterKey {
static const String dataFormat = 'data_format';
static const String textEditor = 'text_editor';
static const String dataCompare = 'data_compare';
static const String uftFile = 'uft_file';
static const String demo = 'demo';
}
@ -29,6 +32,7 @@ class ModuleRouter { @@ -29,6 +32,7 @@ class ModuleRouter {
RouterKey.templateParser: (tab) => TemplateParserController(),
RouterKey.dataFormat: (tab) => DataFormatController(),
RouterKey.dataCompare: (tab) => DataCompareController(),
RouterKey.uftFile: (tab) => UftFileController(),
RouterKey.demo: (tab) => DemoController(),
};
@ -38,6 +42,7 @@ class ModuleRouter { @@ -38,6 +42,7 @@ class ModuleRouter {
RouterKey.templateParser: (tab, controller) => TemplateParserView(tabId: tab.id),
RouterKey.dataFormat: (tab, controller) => DataFormatView(tabId: tab.id),
RouterKey.dataCompare: (tab, controller) => DataCompareView(tabId: tab.id),
RouterKey.uftFile: (tab, controller) => UftFileView(tabId: tab.id),
RouterKey.demo: (tab, controller) => DemoView(tabId: tab.id),
};

13
win_text_editor/lib/modules/uft_file/controllers/uft_file_controller.dart

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
import 'package:win_text_editor/shared/base/base_content_controller.dart';
class UftFileController extends BaseContentController {
@override
void onOpenFile(String filePath) {
// TODO: implement onOpenFile
}
@override
void onOpenFolder(String folderPath) {
// TODO: implement onOpenFolder
}
}

47
win_text_editor/lib/modules/uft_file/widgets/uft_file_view.dart

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:win_text_editor/framework/controllers/tab_items_controller.dart';
import 'package:win_text_editor/modules/uft_file/controllers/uft_file_controller.dart';
class UftFileView extends StatefulWidget {
final String tabId;
const UftFileView({super.key, required this.tabId});
@override
State<UftFileView> createState() => _UftFileViewState();
}
class _UftFileViewState extends State<UftFileView> {
late final UftFileController _controller;
bool _isControllerFromTabManager = false;
get tabManager => Provider.of<TabItemsController>(context, listen: false);
@override
void initState() {
super.initState();
final controllerFromManager = tabManager.getController(widget.tabId);
if (controllerFromManager != null) {
_controller = controllerFromManager;
_isControllerFromTabManager = true;
} else {
_controller = UftFileController();
_isControllerFromTabManager = false;
tabManager.registerController(widget.tabId, _controller);
}
}
@override
void dispose() {
if (!_isControllerFromTabManager) {
_controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return const Center(child: Text('demo'));
}
}
Loading…
Cancel
Save