refactor: cleanup project. ready for refactor.
- remove all old code - build directory hierarchy, add basic cmake scripts.
76
.gitignore
vendored
@@ -1,18 +1,30 @@
|
||||
# ============== My Options ==============
|
||||
|
||||
# ignore generated Virtools.props
|
||||
Virtools.props
|
||||
SuperScriptMaterializer/Virtools.props
|
||||
GPVirtoolsStatic/Virtools.props
|
||||
|
||||
# ignore generated database
|
||||
# -------------------- Personal Disabled --------------------
|
||||
# Ignore test used SQLite database
|
||||
*.db
|
||||
*.db-journal
|
||||
|
||||
# -------------------- Output --------------------
|
||||
out/
|
||||
CMakeSettings.json
|
||||
|
||||
# -------------------- CMake --------------------
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# -------------------- Visual Studio --------------------
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
@@ -42,7 +54,6 @@ bld/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
Temp/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
@@ -102,6 +113,7 @@ StyleCopReport.xml
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
@@ -154,7 +166,9 @@ _TeamCity*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*[.json, .xml, .info]
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
@@ -303,6 +317,17 @@ node_modules/
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
@@ -359,6 +384,9 @@ ASALocalRun/
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
@@ -368,6 +396,26 @@ MigrationBackup/
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# ============== My Options ==============
|
||||
# force adding debug profile for SuperScriptMaterializer
|
||||
!SuperScriptMaterializer/SuperScriptMaterializer.vcxproj.user
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
30
CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(VirtoolsSchematicWeaver
|
||||
VERSION 2.0.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
# Provide options
|
||||
option(VSW_BUILD_MATERIALIZER "Build Materializer part of Virtools Schematic Weaver." ON)
|
||||
option(VSW_BUILD_DECORATOR "Build Decorator part of Virtools Schematic Weaver" ON)
|
||||
|
||||
# Setup install path
|
||||
include(GNUInstallDirs)
|
||||
set(VSW_INSTALL_BIN_PATH ${CMAKE_INSTALL_BINDIR} CACHE PATH
|
||||
"Binary install path relative to CMAKE_INSTALL_PREFIX unless set to an absolute path.")
|
||||
|
||||
# Import shared library and essential library
|
||||
if (VSW_BUILD_MATERIALIZER OR VSW_BUILD_DECORATOR)
|
||||
# Import YYCC and sqlite because all project use them
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/custom_import_yycc.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/custom_import_sqlite.cmake)
|
||||
# Import shared library
|
||||
add_subdirectory(shared)
|
||||
endif ()
|
||||
# Import build targets
|
||||
if (VSW_BUILD_MATERIALIZER)
|
||||
add_subdirectory(materializer)
|
||||
endif ()
|
||||
if (VSW_BUILD_DECORATOR)
|
||||
add_subdirectory(decorator)
|
||||
endif ()
|
||||
99
README.md
@@ -1,98 +1,5 @@
|
||||
# Super Script Materializer
|
||||
# Virtools Schematic Weaver
|
||||
|
||||
[中文文档](./README_ZH.md)
|
||||
Virtools Schematic Weaver (former name Super Script Materializer)
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
The project consist of two parts:
|
||||
|
||||
1. SuperScriptMaterializer - Custom Virtools Interface Plugin that allows you to export all scripts/schematics into a SQLite database file
|
||||
2. SuperScriptViewer - a python parser that creates a web page based on the exported databases to view the schematic in Behavior Graph mode similar to how Virtools Dev displays.
|
||||
|
||||
The purpose of the project is to allow users to have a backup graph of their scripts from Virtools while providing support for analyzing `--Script Hidden--` scripts by generating relation among each script component.
|
||||
|
||||
The inspiration came from:
|
||||
- [BearKidsTeam/Script-Materializer](https://github.com/BearKidsTeam/Script-Materializer) - Allows exporting specific scripts into a JSON file
|
||||
- [BearKidsTeam/VirtoolsScriptDeobfuscation](https://github.com/BearKidsTeam/VirtoolsScriptDeobfuscation) - A custom interface plugin that loads Virtools files with hidden scripts and makes them visible and editable.
|
||||
|
||||
**NOTE:**
|
||||
|
||||
* This project does not give ability to edit hidden scripts within the file. It simply exports and views.
|
||||
* The latest commit may not be stable to use, please visit the Release page to get a stable version.
|
||||
* If you change the version (including the version before the first stable version), then you need to rebuild all the data, because the data between the various versions may not be compatible with each other.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Use
|
||||
|
||||
- Virtools Dev 5.0
|
||||
- Python 3.0 with Flask module
|
||||
- Common browsers (except Safari)
|
||||
|
||||
### Compile
|
||||
|
||||
For compile or debug this project, follwing tools also are necessary.
|
||||
|
||||
- Virtools Dev 5.0 SDK (May work for others, Virtools 4 has been tested and can be compiled and run without any modification)
|
||||
- Visual Studio 2015 with at least v140 toolset
|
||||
|
||||
## Usage
|
||||
|
||||
### Exporting Scripts from Virtools
|
||||
|
||||
1. Make Sure Virtools Dev is closed.
|
||||
2. Copy compiled SuperScriptMaterializer.dll into Virtools's InterfacePlugins folder. Copy `sqlite3.dll` you downloaded into Virtool's base folder (where `devr.exe` exist). If you use the packaged file on the Release page, just decompress it directly in the root directory of Virtools and allow folder merging and file overwriting.
|
||||
3. Open Virtools and load a Virtools document of your choice.
|
||||
4. Go to the menu bar and click `Super Script Materializer` and `Export all script`. Name it `export.db` and save it into `SuperScriptViewer` folder
|
||||
5. Go to the menu bar and click `Super Script Materializer` and `Export environment`. Name it `env.db` and save it into `SuperScriptViewer` folder
|
||||
|
||||
### Viewing Exported Databases
|
||||
|
||||
1. Run the viewer by `python3 SuperScriptViewer.py`
|
||||
2. It will generate a unique decorated database (`decorated.db`) used for viewing based on `export.db` and `env.db`
|
||||
3. Once generated, a webpage will be hosted (default 127.0.0.1:5000) to view all graphs.
|
||||
|
||||
There is advanced command line switches if needed for the SuperScriptViewer
|
||||
- `-i filename.db` specify an input file to be used as `export.db`
|
||||
- `-e filename.db` specify an input file to be used as `env.db`
|
||||
- `-o filename.db` specify an output file to generate `decorated.db`. If it already exists, it will used that instead of generating a new one.
|
||||
- `-c encoding_name` specify database encoding. The list of supported encodings can be viewed [here](https://docs.python.org/3/library/codecs.html#standard-encodings)
|
||||
- `-f` forces the output database to be regenerated (useful if you are unsure if decorated.db matches what export.db and env.db used)
|
||||
- `-d` enable debugging mode. Directly raise exceptions instead of outputting to the console after capture, which is convenient for debugging
|
||||
|
||||
A document instructing you how to use the SuperScriptViewer is built into the SuperScriptViewer and can be viewed from the Help page.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- If `SuperScriptViewer.py` displays `TEXT` type decoding error, you will need to use switch `-c` to whatever encoding system your OS uses since Virtools uses multi-byte encoding and depends on your system's locale. It should be noted that the specified encoding is not the current code page of your computer, but the code page of the author who made this Virtools document.
|
||||
- If Virtools or SuperScriptViewer show an error window or message, please create an issues page noting what Virtools version you have, a link to your file you used to export and the error message.
|
||||
|
||||
## Build
|
||||
|
||||
1. Download repository.
|
||||
2. Get SQLite SDK (amalgamation) and binaries (sqlite-dll-win32-x86) from [sqlite.org](http://www.sqlite.org/)
|
||||
3. Extract both SQLite SDK and binaries to the same folder.
|
||||
4. Open Developer Command Prompt for VS 2015 by typing Developer Command in Windows Search
|
||||
5. Go to directory where you've extracted SDK and binaries and type `lib /DEF:sqlite3.def /OUT:sqlite3.lib /MACHINE:x86` which will build a lib file for SQLite.
|
||||
6. Open SuperScriptMaterializer solution.
|
||||
7. Edit SuperScriptMaterializer Properties page as necessary:
|
||||
- General -> Target Platform Version
|
||||
- General -> Output Directory
|
||||
- General -> Platform Toolset
|
||||
- C/C++ -> General -> Additional Include Directories (Add your SQLite path and Virtools Includes Path)
|
||||
- Linker -> General -> Output File
|
||||
- Linker -> General -> Additional Library Dependencies (Add your SQLite path and Virtools Lib/Win32/Release Path)
|
||||
- Linker -> Debugging -> Generate Program Database File
|
||||
8. Clean and Build as Release
|
||||
|
||||
## Development plan
|
||||
|
||||
In subsequent versions, the following features will be gradually added:
|
||||
|
||||
* Current page search and global search
|
||||
* Shortcut tracking
|
||||
* Move Block and BB in Viewer
|
||||
Work in Progress. Do not use this branch now!
|
||||
|
||||
155
README_ZH.md
@@ -1,155 +0,0 @@
|
||||
# Super Script Materializer
|
||||
|
||||
[English document](./README.md)
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 简介
|
||||
|
||||
超级Virtools脚本物化器(机翻(确信))
|
||||
|
||||
本项目分为3个部分:
|
||||
|
||||
* `SuperScriptMaterializer`:一个C++工程,将生成一个Virtools界面插件或独立播放器用于导出初步数据。
|
||||
* `SuperScriptDecorator`:一个Python工程,将解析导出的数据,并将其组合成易于浏览的格式。
|
||||
* `SuperScriptViewer`:一个Python工程,使用Flask提供一个本地Web界面进行脚本以供快速查看。
|
||||
|
||||
整个工程所作的事情就是,将Virtools文档中的所有脚本导出成一个SQLite数据库文件(`Materializer`所做的任务),然后经过Python进行排布处理(`Decorator`所做的任务),最后提供一个本地Web前端查看脚本(`Viewer`所做的任务)。整个的查看流程比较复杂,涉及到多个软件的操作。希望您能继续阅读下面比较概要操作说明,以获得良好的使用体验。
|
||||
|
||||
物化器同样适用于`Script Hidden`的Virtools脚本,也适用于其中含有不可展开的`Behavior Graph`的脚本。物化器不能完全恢复脚本的原有排布,无论原有排布是否存在,物化器都将重新自动生成脚本中的各个元素的位置。某些结构的关系可能会改变(例如Export parameter),亦或者是与Virtools中的呈现不同,但是逻辑思路将不会改变。同时物化器不能将已经生成的结构回写成Virtools可接受的格式,因此物化器只能提供无视脚本隐藏的分析功能。
|
||||
|
||||
**注意事项**
|
||||
|
||||
* 当前最新的commit并不一定可以稳定使用,请访问Release界面获取可以稳定使用的版本。
|
||||
* 如果您更换了使用的版本(包括第一个稳定版本之前的版本),则需要重新构建所有数据,因为各个版本之间的数据可能彼此不兼容。
|
||||
|
||||
## SuperScriptMaterializer
|
||||
|
||||
SuperScriptMaterializer分为两种类型,一种是*插件*模式,在Virtools内部,作为界面插件,由人手动点击菜单进行导出,一般用于本地快速查看。另一种是*独立*模式,使用独立的Virtools编译器加载文件并导出,通过命令行参数的方式获得需要解析的文件和解析后数据库的路径,一般用于编写Shell脚本批量进行脚本导出。目前,我们支持的Virtools版本和模式如下:
|
||||
|
||||
|已知的Virtools版本|插件模式|独立模式|
|
||||
|:---|:---|:---|
|
||||
|Virtools 2.1|× (0)|√ (1)|
|
||||
|Virtools 2.5|× (2)|√ (4)|
|
||||
|Virtools 3.0|× (3)|× (3)|
|
||||
|Virtools 3.5|√|√|
|
||||
|Virtools 4.0|√|√ (4)|
|
||||
|Virtools 5.0|√|√|
|
||||
|
||||
0. 没有可用的Virtools Dev 2.1,因此没有插件模式
|
||||
0. 使用Ballance Mod Loader提供的逆向Virtools SDK进行编译
|
||||
0. Virtools SDK不支持在界面上添加菜单
|
||||
0. 缺少Virtools SDK,无法编译
|
||||
0. 有不影响输出的错误
|
||||
|
||||
### 运行环境
|
||||
|
||||
* 至少一个可以使用的Virtools环境
|
||||
|
||||
### 使用
|
||||
|
||||
无论您现在要使用何种版本,您都必须先下载一份可用的,匹配的`sqlite.dll`。通常来说,我们在每一次版本发布的时候都会附带对应的`sqlite.dll`,您只需要下载即可。
|
||||
|
||||
如果您将Virtools 2.1作为目标,则由于其只有独立模式,您需要准备一份Virtools 2.1的运行环境(通常而言是`CK2.dll`,`VxMath.dll`等一系列文件)。由于Virtools 2.1并没有创作环境,因此您只能从其他分发版本中获取到这个运行环境,通常来说,是一种游戏,在您的游戏文件夹内搜索相关dll即可找到,将下载好的独立模式的exe和`sqlite.dll`一起放在那里即可。
|
||||
|
||||
如果您选择其他Virtools版本,那么很幸运,它们的创作环境还能被下载到。因此,如果你选择独立模式,可以将下载到的exe和`sqlite.dll`一起放在Virtools创作环境的根目录下(通常有一个名为`Dev.exe`的可执行程序在那里)。当然,如果你是要解析某个游戏的内容,则可以和游戏所使用的Virtools环境放在一起。如果你选择插件模式,那么请仍然将`sqlite.dll`放在Virtools创作环境的根目录下,但是将下载到的dll插件文件放在名为`InterfacePlugins`的目录下。
|
||||
|
||||
#### 插件版本
|
||||
|
||||
启动Virtools,打开需要解析的文档,点击菜单栏的`Super Script Materializer`-`Export all script`,保存为`export.db`,然后等待Virtools提示你已经导出完成。这一步将导出所有脚本。然后同样的操作执行`Super Script Materializer`-`Export environment`,并将其保存为`env.db`。这一步将保存所有环境变量。环境变量很重要,尤其是分析脚本中的一些数据的时候。
|
||||
|
||||
#### 独立版本
|
||||
|
||||
在独立版本所在文件夹内启动命令行,按以下格式输入命令:`SuperScriptMaterializer.exe [virtools composition] [script db path] [env db path]`
|
||||
|
||||
* `virtools composition`:要导出的Virtools文档的地址
|
||||
* `script db path`:导出所有脚本所用数据库的地址
|
||||
* `env db path`:保存所有环境变量所用数据库的地址
|
||||
|
||||
## SuperScriptDecorator
|
||||
|
||||
上一步导出的数据库文件并不能直接被使用,需要通过`SuperScriptDecorator`辅助生成各个Building Graph的位置以及各种连线,之后才能进入下一步查看。同时,为了支持一次性在一个工程内浏览所有的脚本内容,`Decorator`还负责将多个上游导出的数据库合并成一个数据库,以供`Viewer`进行查看。
|
||||
|
||||
### 运行环境
|
||||
|
||||
* Python 3.x
|
||||
|
||||
### 使用
|
||||
|
||||
将上一步得到的`export.db`和`env.db`与`SuperScriptDecorator.py`放在一起。然后新建一个文件名为`import.txt`(使用UTF-8编码),在里面输入如下内容(三个部分之间的空白是`Tab`而不是空格):
|
||||
|
||||
```
|
||||
example.cmo export.db env.db
|
||||
```
|
||||
|
||||
然后在此目录中运行`python3 ./SuperScriptDecorator.py`,等待Python交互界面提示完成操作即可。
|
||||
|
||||
`SuperScriptDecorator.py`具有一些命令行开关:
|
||||
|
||||
- `-i`:指定输入的`import.txt`
|
||||
- `-o`:指定输出的`decorated.db`,如果已经存在将覆盖
|
||||
- `-c`:指定数据库编码,可用的编码表可以在[这里](https://docs.python.org/3/library/codecs.html#standard-encodings)查看
|
||||
- `-d`:无参数,启用调试模式,直接抛出异常,而不是捕获后在控制台输出,方便调试
|
||||
|
||||
### import.txt
|
||||
|
||||
`import.txt`是一个提供输入文件的集和的文本文件。由于`Decorator`还负责将多个上游导出的数据库合并成一个数据库,这些多个由上游导出的数据库需要由`import.txt`来指示。`import.txt`的基本格式就是:
|
||||
|
||||
* 每一行代表一组输入
|
||||
* 每一行共有3个输入,从左至右分别为:文档的名字(会被显示在脚本层次图中),`export.db`,和`env.db`
|
||||
* 每一行3个部分中间由`Tab`分割
|
||||
* 空行会被忽略
|
||||
|
||||
### 提示
|
||||
|
||||
以上某些选项在基本使用中应该不会用到,因此按最开始所述的方式直接放置好文件直接运行即可。
|
||||
|
||||
如果Python交互界面提示数据库`TEXT`类型解码失败,或者解析的字符出现乱码,那么可能您需要手动使用`-c`开关指定数据库文本解码方式。因为Virtools使用多字节编码,依赖于当前操作系统的代码页,`SuperScriptDecorator`做了特殊获取以保证大多数计算机可以直接运行,但仍然不能排除一些特殊情况。需要注意的是,指定的编码不是你计算机当前的代码页,而是制作这个Virtools文档的作者的计算机的代码页。
|
||||
|
||||
## SuperScriptViewer
|
||||
|
||||
`SuperScriptViewer`旨在提供一个网页前端查看已经生成好的数据文件。至于`Viewer`的使用,一份指导你如何使用`Viewer`的文档已内置在`Viewer`中,可以从Help页面进行查看。
|
||||
|
||||
### 运行环境
|
||||
|
||||
* 装有Flask的Python 3.x
|
||||
* 常见浏览器(Safari除外)
|
||||
|
||||
### 使用
|
||||
|
||||
如果您只是为了简单查看一下导出的文件,我们建议以调试模式运行`Viewer`,即将上一步得到的`decorated.db`和`SuperScriptViewer.py`放在一起,然后运行`python3 ./SuperScriptDecorator.py`,即可以运行调试模式的`Viewer`。如果您是要将生成的结果部署到服务器,我们更建议您使用生产模式进行部署,详情请参见[部署](./Documents/DEPLOY_ZH.md)。
|
||||
|
||||
## 问题反馈
|
||||
|
||||
以下情况可能是程序陷入了错误,请附带您引起bug的文件(如果可以)以及错误窗口的内容提交bug
|
||||
|
||||
* `SuperScriptMaterializer`插件模式在选择完文件后弹出错误或长时间没有反应
|
||||
* `SuperScriptMaterializer`独立模式输出了`[ERROR]`等类似内容
|
||||
* Python交互界面弹出错误
|
||||
|
||||
## 部署
|
||||
|
||||
参见[部署](./Documents/DEPLOY_ZH.md)
|
||||
|
||||
## 编译
|
||||
|
||||
参见[编译](./Documents/COMPILE_ZH.md)
|
||||
|
||||
## 开发计划
|
||||
|
||||
在之后的版本中,以下功能将逐步加入:
|
||||
|
||||
* 当前页面搜索和全局搜索
|
||||
* Shortcut追踪
|
||||
|
||||
## 特别感谢
|
||||
|
||||
* Dassault System:提供了Virtools 2.5及其可用的SDK
|
||||
* [BearKidsTeam/Script-Materializer](https://github.com/BearKidsTeam/Script-Materializer):该工程用于将指定脚本导出为JSON文档
|
||||
* [BearKidsTeam/VirtoolsScriptDeobfuscation](https://github.com/BearKidsTeam/VirtoolsScriptDeobfuscation):该工程能够在Virtools 3.5中提供内置的隐藏脚本解析功能,将解析结果解析为可以被Virtools识别的格式
|
||||
* [Gamepiaynmo/BallanceModLoader](https://github.com/Gamepiaynmo/BallanceModLoader):该工程提供了可以用于Virtools 2.1目标编译的,由逆向得到的Virtools SDK
|
||||
* [phaicm](https://github.com/phaicm): 提供了许多测试文件用于修复程序Bug。以及说明文档翻译上的帮助。
|
||||
14
SuperScriptDecorator/.vscode/launch.json
vendored
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "SSDecorator",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "SuperScriptDecorator.py",
|
||||
"console": "integratedTerminal",
|
||||
"args": ["-d", "-i", "../example.txt", "-o", "decorate.db"],
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import locale, sys, os, shlex
|
||||
|
||||
class InputEntry(object):
|
||||
def __init__(self, data: tuple[str]):
|
||||
if len(data) != 4:
|
||||
raise Exception(f"Input syntax error. Require 4 items but got {len(data)}")
|
||||
self.m_Name: str = data[0]
|
||||
self.m_VtFile: str = data[1]
|
||||
self.m_ExportDb: str = data[2]
|
||||
self.m_EnvDb: str = data[3]
|
||||
|
||||
class CustomConfig(object):
|
||||
def __init__(self):
|
||||
# encoding list
|
||||
# https://docs.python.org/3/library/codecs.html#standard-encodings
|
||||
self.m_DatabaseEncoding: str = locale.getpreferredencoding()
|
||||
self.m_DebugMode = False
|
||||
|
||||
self.m_ImportTxt: str = None
|
||||
self.m_DecoratedDb: str = None
|
||||
|
||||
self.m_InputEntries: list[InputEntry] = []
|
||||
|
||||
def Regulate(self) -> bool:
|
||||
# check input and output
|
||||
if self.m_ImportTxt is None:
|
||||
print("No input. Decorator exit.")
|
||||
return False
|
||||
if not os.path.isfile(self.m_ImportTxt):
|
||||
print(f'No such input: "{self.m_ImportTxt}"')
|
||||
return False
|
||||
|
||||
if self.m_DecoratedDb is None:
|
||||
print("No output. Decorator exit.")
|
||||
return False
|
||||
if os.path.isdir(self.m_DecoratedDb):
|
||||
print("Output must be a file.")
|
||||
return False
|
||||
|
||||
# remove result database in debug mode
|
||||
if self.m_DebugMode and os.path.isfile(self.m_DecoratedDb):
|
||||
os.remove(self.m_DecoratedDb)
|
||||
|
||||
# process input file
|
||||
try:
|
||||
with open(self.m_ImportTxt, 'r', encoding='utf-8') as f:
|
||||
while True:
|
||||
ln = f.readline()
|
||||
if ln == '': break
|
||||
ln.strip()
|
||||
if ln == '': continue
|
||||
|
||||
self.m_InputEntries.append(InputEntry(shlex.split(ln)))
|
||||
except Exception as ex:
|
||||
print("Errro when processing input file.")
|
||||
print(ex)
|
||||
|
||||
return True
|
||||
@@ -1,270 +0,0 @@
|
||||
import sqlite3, collections
|
||||
import DecoratorData, DecoratorConst
|
||||
|
||||
class BuildBBEnvironment(object):
|
||||
def __init__(self,
|
||||
cursor: sqlite3.Cursor, tree: DecoratorData.TreeLayout[DecoratorData.BBTreeNodeWrapper],
|
||||
depth: int, query_bb: int):
|
||||
|
||||
self.m_Cursor: sqlite3.Cursor = cursor
|
||||
self.m_Tree: DecoratorData.TreeLayout[DecoratorData.BBTreeNodeWrapper] = tree
|
||||
self.m_Depth: int = depth
|
||||
self.m_QueryBB: int = query_bb
|
||||
|
||||
class BuildOperEnvironment(object):
|
||||
def __init__(self,
|
||||
cursor: sqlite3.Cursor, tree: DecoratorData.TreeLayout[DecoratorData.OperTreeNodeWrapper],
|
||||
depth: int, query_oper: int):
|
||||
|
||||
self.m_Cursor: sqlite3.Cursor = cursor
|
||||
self.m_Tree: DecoratorData.TreeLayout[DecoratorData.OperTreeNodeWrapper] = tree
|
||||
self.m_Depth: int = depth
|
||||
self.m_QueryOper: int = query_oper
|
||||
|
||||
class FindOperRootEnvironment(object):
|
||||
def __init__(self,
|
||||
cursor: sqlite3.Cursor, walked_oper: set[int],
|
||||
depth: int, query_oper: int):
|
||||
|
||||
self.m_Cursor: sqlite3.Cursor = cursor
|
||||
self.m_WalkedOper: set[int] = walked_oper
|
||||
self.m_Depth: int = depth
|
||||
self.m_QueryOper: int = query_oper
|
||||
|
||||
class BlocksFactory(object):
|
||||
def __init__(self, db: sqlite3.Connection, graph: DecoratorData.GraphResult):
|
||||
# assign members
|
||||
self.m_Graph: DecoratorData.GraphResult = DecoratorData.GraphResult()
|
||||
self.m_Graph.m_GraphCKID = graph
|
||||
self.m_Db: sqlite3.Connection = db
|
||||
|
||||
self.__AllBB: set[int] = set()
|
||||
self.__AllOper: set[int] = set()
|
||||
|
||||
# fill data first
|
||||
self.__FillDataFromDb()
|
||||
|
||||
# proc each data
|
||||
self.__ProcActiveBB()
|
||||
self.__ProcPassiveBB()
|
||||
self.__ProcPassiveOper()
|
||||
|
||||
|
||||
def __GetOneFromSet(self, vals: set[int]) -> int:
|
||||
return next(iter(vals))
|
||||
|
||||
def __FillDataFromDb(self):
|
||||
cursor: sqlite3.Cursor = self.m_Db.cursor()
|
||||
cursor.execute('SELECT * FROM [script_behavior] WHERE parent == ?;', (self.m_Graph.m_GraphCKID, ))
|
||||
for sqldata in cursor.fetchall():
|
||||
payload: DecoratorData.BBDataPayload = DecoratorData.BBDataPayload(sqldata)
|
||||
self.m_Graph.m_BBDict[payload.m_CKID] = DecoratorData.BBTreeNodeWrapper(payload)
|
||||
self.__AllBB.add(payload.m_CKID)
|
||||
|
||||
cursor.execute('SELECT * FROM [script_pOper] WHERE parent == ?;', (self.m_Graph.m_GraphCKID, ))
|
||||
for sqldata in cursor.fetchall():
|
||||
payload: DecoratorData.OperDataPayload = DecoratorData.OperDataPayload(sqldata)
|
||||
self.m_Graph.m_OperDict[payload.m_CKID] = DecoratorData.BBTreeNodeWrapper(payload)
|
||||
self.__AllOper.add(payload.m_CKID)
|
||||
|
||||
cursor.close()
|
||||
|
||||
def __RecursiveFindOperRoot(self, envir: FindOperRootEnvironment) -> tuple[int]:
|
||||
envir.m_Cursor.execute('SELECT [output_obj], [output_type], [output_is_bb] FROM [script_pLink] WHERE ([input_obj] == ? AND [input_is_bb] == ? AND NOT (([output_type] == ? OR [output_type] == ?) AND [output_is_bb] == ?) AND [parent] == ?);',
|
||||
(envir.m_QueryOper, (DecoratorConst.Export_Boolean.TRUE if envir.m_Depth == 0 else DecoratorConst.Export_Boolean.FALSE),
|
||||
DecoratorConst.Export_pLink_InputOutputType.PIN, DecoratorConst.Export_pLink_InputOutputType.PTARGET, DecoratorConst.Export_Boolean.TRUE, # filter all BB's pIn
|
||||
self.m_Graph.m_GraphCKID)
|
||||
)
|
||||
|
||||
opers: set[int] = set()
|
||||
results: set[int] = set()
|
||||
|
||||
# read datas
|
||||
for (output_obj, output_type, output_is_bb, ) in envir.m_Cursor.fetchall():
|
||||
# check dup
|
||||
if output_obj in envir.m_WalkedOper or output_obj not in self.__AllOper:
|
||||
continue
|
||||
envir.m_WalkedOper.add(output_obj)
|
||||
|
||||
if output_type == DecoratorConst.Export_pLink_InputOutputType.PIN:
|
||||
# this is a oper. find its pOut and add into stack
|
||||
opers.add(output_obj)
|
||||
else:
|
||||
# this oper point to non-pIn, should be add into result
|
||||
if envir.m_Depth != 0: # omit BB
|
||||
results.add(envir.m_QueryOper)
|
||||
|
||||
# recursive calling opers to get root
|
||||
for oper in opers:
|
||||
results.update(self.__RecursiveFindOperRoot(FindOperRootEnvironment(
|
||||
envir.m_Cursor, envir.m_WalkedOper, envir.m_Depth + 1, oper
|
||||
)))
|
||||
|
||||
return tuple(i for i in results)
|
||||
|
||||
def __RecursiveBuildOper(self, envir: BuildOperEnvironment):
|
||||
envir.m_Cursor.execute("SELECT [input_obj] FROM [script_pLink] WHERE ([output_obj] == ? AND [output_type] == ? AND [input_type] == ? AND [input_is_bb] == ? AND [parent] = ?);",
|
||||
(envir.m_QueryOper, DecoratorConst.Export_pLink_InputOutputType.PIN, # order pOper's pIn
|
||||
DecoratorConst.Export_pLink_InputOutputType.POUT, DecoratorConst.Export_Boolean.FALSE, # order pOper's pOut
|
||||
self.m_Graph.m_GraphCKID, )
|
||||
)
|
||||
|
||||
gottenOper: list[int] = []
|
||||
for (input_obj, ) in envir.m_Cursor.fetchall():
|
||||
if input_obj in self.__AllOper:
|
||||
self.__AllOper.remove(input_obj)
|
||||
gottenOper.append(input_obj)
|
||||
|
||||
if len(gottenOper) == 0:
|
||||
return
|
||||
|
||||
if envir.m_Depth == 0:
|
||||
# if depth == 0, all item should start from a new layer
|
||||
for item in gottenOper:
|
||||
envir.m_Tree.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_OperDict[item])
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, item
|
||||
))
|
||||
else:
|
||||
# otherwise, only non-first node need new layer
|
||||
# proc first node
|
||||
first: int = gottenOper[0]
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_OperDict[first])
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, first
|
||||
))
|
||||
|
||||
# get layer and pos
|
||||
cur_layer = envir.m_Tree.GetCurrentLayerIndex()
|
||||
cur_idx = envir.m_Tree.GetCurrentItemIndex()
|
||||
|
||||
# proc other node
|
||||
for other in gottenOper[1:]:
|
||||
envir.m_Tree.NewLayer(cur_layer, cur_idx)
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_OperDict[other])
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, other
|
||||
))
|
||||
|
||||
def __RecursiveBuildBB(self, envir: BuildBBEnvironment):
|
||||
# query all link for next bb
|
||||
envir.m_Cursor.execute('SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [parent] = ?) ORDER BY [input_index] ASC;',
|
||||
(envir.m_QueryBB,
|
||||
(DecoratorConst.Export_bLink_InputOutputType.INPUT if envir.m_Depth == 0 else DecoratorConst.Export_bLink_InputOutputType.OUTPUT),
|
||||
self.m_Graph.m_GraphCKID)
|
||||
)
|
||||
|
||||
# filter useless bb
|
||||
gottenBB: list[int] = []
|
||||
for (output_obj, ) in envir.m_Cursor.fetchall():
|
||||
if output_obj in self.__AllBB:
|
||||
self.__AllBB.remove(output_obj)
|
||||
gottenBB.append(output_obj)
|
||||
|
||||
if len(gottenBB) == 0:
|
||||
return
|
||||
|
||||
# we need process this BB related opers now
|
||||
# for every item
|
||||
for bbid in gottenBB:
|
||||
bb: DecoratorData.BBTreeNodeWrapper = self.m_Graph.m_BBDict[bbid]
|
||||
# upper opers
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
envir.m_Cursor, bb.m_UpperOper, 0, bbid
|
||||
))
|
||||
# lower opers
|
||||
lower_root: tuple[int] = self.__RecursiveFindOperRoot(FindOperRootEnvironment(
|
||||
envir.m_Cursor, set(), 0, bbid
|
||||
))
|
||||
for operid in lower_root:
|
||||
# we need add it manually
|
||||
self.__AllOper.remove(operid)
|
||||
bb.m_LowerOper.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
|
||||
bb.m_LowerOper.NewItem(self.m_Graph.m_OperDict[operid])
|
||||
|
||||
# gotten "root" is oper's CKID, so use depth 1 to cheat this function
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
envir.m_Cursor, bb.m_LowerOper, 1, operid
|
||||
))
|
||||
|
||||
# now we place BB in tree layout
|
||||
if envir.m_Depth == 0:
|
||||
# if depth == 0, all item should start from a new layer
|
||||
for item in gottenBB:
|
||||
envir.m_Tree.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_BBDict[item])
|
||||
self.__RecursiveBuildBB(BuildBBEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, item
|
||||
))
|
||||
else:
|
||||
# otherwise, only non-first node need new layer
|
||||
# proc first node
|
||||
first: int = gottenBB[0]
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_BBDict[first])
|
||||
self.__RecursiveBuildBB(BuildBBEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, first
|
||||
))
|
||||
|
||||
# get layer and pos
|
||||
cur_layer = envir.m_Tree.GetCurrentLayerIndex()
|
||||
cur_idx = envir.m_Tree.GetCurrentItemIndex()
|
||||
|
||||
# proc other node
|
||||
for other in gottenBB[1:]:
|
||||
envir.m_Tree.NewLayer(cur_layer, cur_idx)
|
||||
envir.m_Tree.NewItem(self.m_Graph.m_BBDict[other])
|
||||
self.__RecursiveBuildBB(BuildBBEnvironment(
|
||||
envir.m_Cursor, envir.m_Tree, envir.m_Depth + 1, other
|
||||
))
|
||||
|
||||
|
||||
def __ProcActiveBB(self):
|
||||
cursor: sqlite3.Cursor = self.m_Db.cursor()
|
||||
self.__RecursiveBuildBB(BuildBBEnvironment(
|
||||
cursor, self.m_Graph.m_ActivePassiveBB, 0, self.m_Graph.m_GraphCKID
|
||||
))
|
||||
cursor.close()
|
||||
|
||||
def __ProcPassiveBB(self):
|
||||
cursor: sqlite3.Cursor = self.m_Db.cursor()
|
||||
while len(self.__AllBB) != 0:
|
||||
# we manually add first
|
||||
bbid = self.__GetOneFromSet(self.__AllBB)
|
||||
|
||||
self.__AllBB.remove(bbid)
|
||||
self.m_Graph.m_ActivePassiveBB.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
|
||||
self.m_Graph.m_ActivePassiveBB.NewItem(self.m_Graph.m_BBDict[bbid])
|
||||
|
||||
# use depth = 1 to cheat this function for avoiding error bIO type
|
||||
self.__RecursiveBuildBB(BuildBBEnvironment(
|
||||
cursor, self.m_Graph.m_ActivePassiveBB, 1, bbid
|
||||
))
|
||||
cursor.close()
|
||||
|
||||
def __ProcPassiveOper(self):
|
||||
cursor: sqlite3.Cursor = self.m_Db.cursor()
|
||||
while len(self.__AllOper) != 0:
|
||||
# peek one randomly and try finding root
|
||||
peek: int = self.__GetOneFromSet(self.__AllOper)
|
||||
roots: tuple[int] = self.__RecursiveFindOperRoot(FindOperRootEnvironment(
|
||||
cursor, set(), 1, peek # use 1 to cheat this function
|
||||
))
|
||||
|
||||
# if no root found, add self
|
||||
roots = (peek, )
|
||||
|
||||
# generate tree
|
||||
for operid in roots:
|
||||
# we need add it manually
|
||||
self.__AllOper.remove(operid)
|
||||
self.m_Graph.m_PassiveOper.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
|
||||
self.m_Graph.m_PassiveOper.NewItem(self.m_Graph.m_OperDict[operid])
|
||||
|
||||
# gotten "roots" is oper's CKID, so use depth 1 to cheat this function
|
||||
self.__RecursiveBuildOper(BuildOperEnvironment(
|
||||
cursor, self.m_Graph.m_PassiveOper, 1, operid
|
||||
))
|
||||
|
||||
cursor.close()
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
class Export_Boolean(object):
|
||||
TRUE = 1
|
||||
FALSE = 0
|
||||
|
||||
class Export_Behavior_Type(object):
|
||||
FUNCTION = 0
|
||||
GRAPH = 1
|
||||
SCRIPT = 4
|
||||
|
||||
class Export_bLink_InputOutputType(object):
|
||||
INPUT = 0
|
||||
OUTPUT = 1
|
||||
|
||||
class Export_pLink_InputOutputType(object):
|
||||
PIN = 0
|
||||
POUT = 1
|
||||
PLOCAL = 2
|
||||
PTARGET = 3
|
||||
PATTR = 4
|
||||
@@ -1,129 +0,0 @@
|
||||
import json
|
||||
|
||||
FONT_SIZE = 12
|
||||
|
||||
GRAPH_POFFSET = 40 # 主体bb的p距离左边框距离
|
||||
GRAPH_BOFFSET = 40 # 主体bb的b距离上边框距离
|
||||
GRAPH_PSPAN = 20 # 主体bb的每个p之间的水平间距
|
||||
GRAPH_BSPAN = 20 # 主体bb的每个b之间的垂直间距
|
||||
GRAPH_LAYER_SPAN = 50 # 绘图中各个bb层之间的间距
|
||||
GRAPH_BB_SPAN = 25 # 绘图中每个bb之间的距离(扩展到Oper和不可插入的local之间的距离)
|
||||
GRAPH_SPAN_BB_POPER = 60 # 每个bb上面挂载的oper和被挂载bb之间的垂直距离 和 每个bb上面挂载的oper的各层之间的垂直距离
|
||||
GRAPH_SPAN_BB_PLOCAL = 10 # 每个bb上面挂载的plocal和被挂载bb之间的垂直距离
|
||||
GRAPH_CONTENTOFFSET_X = 40 # 绘图内容原点到左边框的距离
|
||||
GRAPH_CONTENTOFFSET_Y = 40 # 绘图内容原点到顶边框的距离
|
||||
BB_POFFSET = 20 # bb框中的p距离左边框距离
|
||||
BB_BOFFSET = 10 # bb框中的b距离上边框距离
|
||||
BB_PSPAN = 20 # bb框每个p之间的水平间距
|
||||
BB_BSPAN = 20 # bb框每个b之间的垂直间距
|
||||
BB_PBSIZE = 6 # bb框中o和b的正方形符号的边长(扩展到graph中的p/b大小)
|
||||
CELL_WIDTH = 15
|
||||
CELL_HEIGHT = 5
|
||||
|
||||
class dbPLinkInputOutputType(object):
|
||||
PIN = 0
|
||||
POUT = 1
|
||||
PLOCAL = 2
|
||||
PTARGET = 3
|
||||
PATTR = 4
|
||||
|
||||
class dbBLinkInputOutputType(object):
|
||||
INPUT = 0
|
||||
OUTPUT = 1
|
||||
|
||||
class CellType(object):
|
||||
PLOCAL = 0
|
||||
SHORTCUT = 1
|
||||
PIO = 2
|
||||
BIO = 3
|
||||
PTARGET = 4
|
||||
|
||||
class LocalUsageType(object):
|
||||
PIN = 0
|
||||
POUT = 1
|
||||
PLOCAL = 2
|
||||
PATTR = 3
|
||||
|
||||
class JsonCustomEncoder(json.JSONEncoder):
|
||||
def default(self, field):
|
||||
if isinstance(field, PinInformation):
|
||||
return {'id': field.id, 'name': field.name, 'type': field.type}
|
||||
else:
|
||||
return json.JSONEncoder.default(self, field)
|
||||
|
||||
class BlockCellItem(object):
|
||||
def __init__(self, x, y, w, h):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = w
|
||||
self.h = h
|
||||
|
||||
class BBTreeNode(object):
|
||||
def __init__(self, ckid, layer):
|
||||
self.bb = ckid
|
||||
self.layer = layer
|
||||
self.nodes = []
|
||||
|
||||
class BBResult(object):
|
||||
def __init__(self, name, assistName, pin, pout, bin, bout, expandable):
|
||||
self.name = name
|
||||
self.assistName = assistName
|
||||
self.ptargetData = None
|
||||
self.pin = int(pin)
|
||||
self.pinData = None
|
||||
self.pout = int(pout)
|
||||
self.poutData = None
|
||||
self.bin = int(bin)
|
||||
self.binData = None
|
||||
self.bout = int(bout)
|
||||
self.boutData = None
|
||||
self.x = 0.0
|
||||
self.y = 0.0
|
||||
self.width = 0.0
|
||||
self.height = 0.0
|
||||
self.expandable = expandable
|
||||
|
||||
def computSize(self):
|
||||
wText = max(len(self.name), len(self.assistName)) * FONT_SIZE / 3 * 2
|
||||
hText = FONT_SIZE * 3
|
||||
|
||||
wp = max(self.pin, self.pout) * (BB_PBSIZE + BB_PSPAN)
|
||||
hb = max(self.bin, self.bout) * (BB_PBSIZE + BB_BSPAN)
|
||||
|
||||
self.width = 2 * BB_POFFSET + max(wp, wText)
|
||||
self.height = 2 * BB_BOFFSET + max(hb, hText)
|
||||
|
||||
class OperResult(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.x = 0.0
|
||||
self.y = 0.0
|
||||
self.pinData = None
|
||||
self.poutData = None
|
||||
self.height = 0.0
|
||||
self.width = 0.0
|
||||
|
||||
def computSize(self):
|
||||
wText = len(self.name) * FONT_SIZE / 3 * 2
|
||||
hText = FONT_SIZE * 3
|
||||
|
||||
wp = 2 * BB_POFFSET + 2 * (BB_PBSIZE + BB_PSPAN)
|
||||
hb = 2 * BB_BOFFSET + 0 * (BB_PBSIZE + BB_BSPAN)
|
||||
|
||||
self.width = max(wp, wText)
|
||||
self.height = max(hb, hText)
|
||||
|
||||
class PinInformation(object):
|
||||
def __init__(self, id, name, type):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.type = type
|
||||
|
||||
class LocalUsageItem(object):
|
||||
def __init__(self, count, isshortcut, internal_type):
|
||||
self.count = count
|
||||
self.lastUse = -1
|
||||
self.lastDirection = 0 # 0 for pIn, 1 for pOut
|
||||
self.lastIndex = -1 # -1 for pTarget, otherwise the real index
|
||||
self.isshortcut = isshortcut
|
||||
self.internal_type = internal_type # 0 pIn, 1 pOut, 2 pLocal. for convenient query match data
|
||||
@@ -1,710 +0,0 @@
|
||||
import sqlite3
|
||||
import DecoratorConstValue as dcv
|
||||
import json
|
||||
import CustomConfig
|
||||
import Progressbar
|
||||
|
||||
def run():
|
||||
exportDb = sqlite3.connect(CustomConfig.export_db)
|
||||
exportDb.text_factory = lambda x: x.decode(CustomConfig.database_encoding, errors="ignore")
|
||||
decorateDb = sqlite3.connect(CustomConfig.decorated_db)
|
||||
|
||||
# init table
|
||||
print('Init decorate database...')
|
||||
initDecorateDb(decorateDb)
|
||||
decorateDb.commit()
|
||||
|
||||
# decorate graph
|
||||
print('Generating gragh list...')
|
||||
graphList = []
|
||||
decorateGraph(exportDb, decorateDb, graphList)
|
||||
|
||||
# decorate each graph
|
||||
print('Generating graph...')
|
||||
currentGraphBlockCell = {}
|
||||
Progressbar.initProgressbar(len(graphList))
|
||||
for i in graphList:
|
||||
currentGraphBlockCell.clear()
|
||||
buildBlock(exportDb, decorateDb, i, currentGraphBlockCell)
|
||||
graphPIO = buildCell(exportDb, decorateDb, i, currentGraphBlockCell)
|
||||
buildLink(exportDb, decorateDb, i, currentGraphBlockCell, graphPIO)
|
||||
|
||||
Progressbar.stepProgressbar()
|
||||
Progressbar.finProgressbar()
|
||||
|
||||
# export information
|
||||
print('Generating info...')
|
||||
buildInfo(exportDb, decorateDb)
|
||||
|
||||
# give up all change of eexport.db (because no change)
|
||||
exportDb.close()
|
||||
decorateDb.commit()
|
||||
decorateDb.close()
|
||||
|
||||
def initDecorateDb(db):
|
||||
cur = db.cursor()
|
||||
cur.execute("CREATE TABLE graph([graph] INTEGER, [graph_name] TEXT, [width] INTEGER, [height] INTEGER, [index] INTEGER, [belong_to] TEXT);")
|
||||
cur.execute("CREATE TABLE info([target] INTEGER, [attach_bb] INTEGER, [is_setting] INTEGER, [name] TEXT, [field] TEXT, [data] TEXT);")
|
||||
|
||||
cur.execute("CREATE TABLE block([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [pin-ptarget] TEXT, [pin-pin] TEXT, [pin-pout] TEXT, [pin-bin] TEXT, [pin-bout] TEXT, [x] REAL, [y] REAL, [width] REAL, [height] REAL, [expandable] INTEGER);")
|
||||
cur.execute("CREATE TABLE cell([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [type] INTEGER);")
|
||||
cur.execute("CREATE TABLE link([belong_to_graph] INETGER, [delay] INTEGER, [start_interface] INTEGER, [end_interface] INTEGER, [startobj] INTEGER, [endobj] INTEGER, [start_type] INTEGER, [end_type] INTEGER, [start_index] INTEGER, [end_index] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);")
|
||||
|
||||
def decorateGraph(exDb, deDb, graph):
|
||||
exCur = exDb.cursor()
|
||||
deCur = deDb.cursor()
|
||||
scriptMap = {}
|
||||
|
||||
exCur.execute("SELECT [behavior], [index], [name] FROM script;")
|
||||
while True:
|
||||
lines = exCur.fetchone()
|
||||
if lines == None:
|
||||
break
|
||||
scriptMap[lines[0]] = (lines[1], lines[2])
|
||||
|
||||
exCur.execute("SELECT [thisobj], [type], [name] FROM behavior WHERE [type] != 0;")
|
||||
while True:
|
||||
lines = exCur.fetchone()
|
||||
if lines == None:
|
||||
break
|
||||
|
||||
# add into global graph list
|
||||
graph.append(lines[0])
|
||||
|
||||
# width and height will be computed by following method and use update
|
||||
# statement to change it
|
||||
if lines[1] == 1:
|
||||
# script
|
||||
deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, ?, ?)", (lines[0], lines[2], scriptMap[lines[0]][0], scriptMap[lines[0]][1]))
|
||||
else:
|
||||
# sub bb
|
||||
deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, -1, '')", (lines[0], lines[2]))
|
||||
|
||||
def buildBlock(exDb, deDb, target, currentGraphBlockCell):
|
||||
exCur = exDb.cursor()
|
||||
deCur = deDb.cursor()
|
||||
|
||||
# sort inner bb
|
||||
# use current graph input as the start point
|
||||
treeRoot = dcv.BBTreeNode(target, -1)
|
||||
processedBB = set()
|
||||
# layer start from 2, 0 is occupied for pLocal, 1 is occupied for pOper
|
||||
arrangedLayer = recursiveBuildBBTree(treeRoot, exCur, processedBB, 2, 0, target)
|
||||
|
||||
# get no linked bb and place them. linked bb position will be computed
|
||||
# following
|
||||
# calc each bb's x postion, as for y, calc later
|
||||
# flat bb tree
|
||||
arrangedLayer+=1
|
||||
singleBB = set()
|
||||
bbResult = {}
|
||||
bb_layer_map = {}
|
||||
baseX = dcv.GRAPH_CONTENTOFFSET_X
|
||||
exCur.execute('SELECT [thisobj], [name], [type], [proto_name], [pin_count] FROM behavior WHERE parent == ?', (target,))
|
||||
for i in exCur.fetchall():
|
||||
pinSplit = i[4].split(',')
|
||||
bbCache = dcv.BBResult(i[1], i[3], pinSplit[1], pinSplit[2], pinSplit[3], pinSplit[4], (i[0] if i[2] != 0 else -1))
|
||||
bbCache.computSize()
|
||||
if i[0] not in processedBB:
|
||||
# single bb, process it
|
||||
singleBB.add(i[0])
|
||||
bbCache.x = baseX
|
||||
baseX += bbCache.width + dcv.GRAPH_BB_SPAN
|
||||
bb_layer_map[i[0]] = arrangedLayer
|
||||
|
||||
bbResult[i[0]] = bbCache
|
||||
|
||||
recursiveCalcBBX(treeRoot, dcv.GRAPH_CONTENTOFFSET_X, bbResult, bb_layer_map)
|
||||
|
||||
# calc poper
|
||||
allBB = processedBB | singleBB
|
||||
processedOper = set()
|
||||
pluggedOper = {}
|
||||
occupiedLayerCountForSpecificBB = {}
|
||||
exCur.execute('SELECT [thisobj] FROM pOper WHERE [belong_to] == ?', (target,))
|
||||
newCur = exDb.cursor()
|
||||
newCur2 = exDb.cursor()
|
||||
for i in exCur.fetchall():
|
||||
if i[0] in processedOper:
|
||||
continue
|
||||
|
||||
# check current bout, plugin into the first bb
|
||||
newCur.execute("SELECT [output_obj] FROM pLink WHERE ([input_obj] == ? AND [output_type] == ? AND [output_is_bb] == 1)", (i[0], dcv.dbPLinkInputOutputType.PIN))
|
||||
for j in newCur.fetchall():
|
||||
if j[0] in allBB:
|
||||
# can be plugin
|
||||
# try get tree
|
||||
if j[0] not in pluggedOper.keys():
|
||||
pluggedOper[j[0]] = {}
|
||||
recursiveBuildOperTree(i[0], bb_layer_map, processedOper, occupiedLayerCountForSpecificBB, newCur2, 1, j[0], target, pluggedOper[j[0]])
|
||||
# exit for due to have found a proper host bb
|
||||
break
|
||||
|
||||
|
||||
# calc layer position
|
||||
layer_height = {}
|
||||
layer_y = {}
|
||||
layer_height[0] = 25
|
||||
layer_height[1] = 50
|
||||
for i in bb_layer_map.keys():
|
||||
curLayer = bb_layer_map[i]
|
||||
if curLayer not in layer_height.keys():
|
||||
layer_height[curLayer] = bbResult[i].height
|
||||
else:
|
||||
layer_height[curLayer] = max(layer_height.get(curLayer, 0), bbResult[i].height)
|
||||
layer_height[arrangedLayer] = layer_height.get(arrangedLayer, 0) # make sure misc bb height exist
|
||||
layer_height[2] = layer_height.get(2, 0) # make sure at least have a bb layer (when there are no bb in a map)
|
||||
|
||||
# calc bb Y
|
||||
baseY = dcv.GRAPH_CONTENTOFFSET_Y
|
||||
for i in range(arrangedLayer + 1):
|
||||
baseY += layer_height[i] + dcv.GRAPH_LAYER_SPAN
|
||||
baseY += occupiedLayerCountForSpecificBB.get(i, 0) * dcv.GRAPH_SPAN_BB_POPER # add oper occipation
|
||||
layer_y[i] = baseY
|
||||
for i in bbResult.keys():
|
||||
cache = bbResult[i]
|
||||
layer = bb_layer_map[i]
|
||||
cache.y = layer_y[layer] - layer_height[layer]
|
||||
|
||||
# calc oper position
|
||||
# flat oper tree
|
||||
operResult = {}
|
||||
exCur.execute('SELECT [thisobj], [op] FROM pOper WHERE [belong_to] == ?', (target,))
|
||||
homelessOperCurrentX = dcv.GRAPH_CONTENTOFFSET_X
|
||||
for i in exCur.fetchall():
|
||||
if i[0] not in processedOper:
|
||||
# homeless oper
|
||||
cache2 = dcv.OperResult(i[1])
|
||||
cache2.computSize()
|
||||
cache2.x = homelessOperCurrentX
|
||||
cache2.y = layer_y[1] - cache2.height
|
||||
homelessOperCurrentX += cache2.width + dcv.GRAPH_BB_SPAN
|
||||
operResult[i[0]] = cache2
|
||||
|
||||
for i in pluggedOper.keys(): # plugged oper
|
||||
cache = bbResult[i]
|
||||
for j in pluggedOper[i]:
|
||||
jCache = pluggedOper[i][j]
|
||||
baseX = cache.x
|
||||
for q in jCache:
|
||||
exCur.execute("SELECT [op] FROM pOper WHERE [thisobj] == ?", (q,))
|
||||
cache2 = dcv.OperResult(exCur.fetchone()[0])
|
||||
cache2.computSize()
|
||||
cache2.x = baseX
|
||||
baseX += cache2.width + dcv.GRAPH_BB_SPAN
|
||||
cache2.y = cache.y - j * dcv.GRAPH_SPAN_BB_POPER
|
||||
operResult[q] = cache2
|
||||
|
||||
# query bb pin's data
|
||||
listCache = []
|
||||
listItemCache = None
|
||||
for i in allBB:
|
||||
cache = bbResult[i]
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?;", (i,))
|
||||
temp = exCur.fetchone()
|
||||
if temp == None:
|
||||
cache.ptargetData = '{}'
|
||||
else:
|
||||
cache.ptargetData = json.dumps(dcv.PinInformation(temp[0], temp[1], temp[2]), cls = dcv.JsonCustomEncoder)
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name] FROM bIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], '')
|
||||
listCache.append(listItemCache)
|
||||
cache.binData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name] FROM bOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], '')
|
||||
listCache.append(listItemCache)
|
||||
cache.boutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], j[2])
|
||||
listCache.append(listItemCache)
|
||||
cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], j[2])
|
||||
listCache.append(listItemCache)
|
||||
cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
# query oper pin's data
|
||||
for i in operResult.keys():
|
||||
cache = operResult[i]
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], j[2])
|
||||
listCache.append(listItemCache)
|
||||
cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
listCache.clear()
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
|
||||
for j in exCur.fetchall():
|
||||
listItemCache = dcv.PinInformation(j[0], j[1], j[2])
|
||||
listCache.append(listItemCache)
|
||||
cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
|
||||
|
||||
# write to database and return
|
||||
for i in bbResult.keys():
|
||||
cache = bbResult[i]
|
||||
currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
|
||||
deCur.execute('INSERT INTO block VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
(target, i, cache.name, cache.assistName, cache.ptargetData, cache.pinData, cache.poutData, cache.binData, cache.boutData, cache.x, cache.y, cache.width, cache.height, cache.expandable))
|
||||
for i in operResult.keys():
|
||||
cache = operResult[i]
|
||||
currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
|
||||
deCur.execute("INSERT INTO block VALUES (?, ?, ?, '', '{}', ?, ?, '[]', '[]', ?, ?, ?, ?, -1)",
|
||||
(target, i, cache.name, cache.pinData, cache.poutData, cache.x, cache.y, cache.width, cache.height))
|
||||
|
||||
def recursiveBuildBBTree(node, exCur, processedBB, layer, depth, graphId):
|
||||
realLinkedBB = set()
|
||||
# find links
|
||||
exCur.execute("SELECT [output_obj] FROM bLink WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;",
|
||||
(node.bb, (dcv.dbBLinkInputOutputType.INPUT if depth == 0 else dcv.dbBLinkInputOutputType.OUTPUT), graphId))
|
||||
for i in exCur.fetchall():
|
||||
if i[0] != graphId: # omit self
|
||||
realLinkedBB.add(i[0])
|
||||
|
||||
if (len(realLinkedBB) == 0):
|
||||
return layer
|
||||
|
||||
# ignore duplicated bb
|
||||
# calc need processed bb first
|
||||
# and register all gotten bb. for preventing infinity resursive func and
|
||||
# keep bb tree structure
|
||||
realLinkedBB = realLinkedBB - processedBB
|
||||
processedBB.update(realLinkedBB)
|
||||
|
||||
# iterate each bb
|
||||
for i in realLinkedBB:
|
||||
# recursive execute this method
|
||||
newNode = dcv.BBTreeNode(i, layer)
|
||||
layer = recursiveBuildBBTree(newNode, exCur, processedBB, layer, depth + 1, graphId)
|
||||
# add new node into list and ++layer
|
||||
layer+=1
|
||||
node.nodes.append(newNode)
|
||||
|
||||
# minus extra ++ due to for
|
||||
if (len(realLinkedBB) != 0):
|
||||
layer-=1
|
||||
|
||||
return layer
|
||||
|
||||
def recursiveCalcBBX(node, baseX, resultList, layerMap):
|
||||
maxExpand = 0
|
||||
for i in node.nodes:
|
||||
layerMap[i.bb] = i.layer
|
||||
resultList[i.bb].x = baseX
|
||||
maxExpand = max(maxExpand, resultList[i.bb].width)
|
||||
|
||||
for i in node.nodes:
|
||||
recursiveCalcBBX(i, baseX + maxExpand + dcv.GRAPH_BB_SPAN, resultList, layerMap)
|
||||
|
||||
def recursiveBuildOperTree(oper, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer, bb, graphId, subLayerColumnMap):
|
||||
if oper in processedOper:
|
||||
return
|
||||
|
||||
# for avoid fucking export parameter feature. check whether self is
|
||||
# current graph's memeber
|
||||
exCur.execute("SELECT [belong_to] FROM pOper WHERE [thisobj] == ?;", (oper,))
|
||||
if (exCur.fetchone()[0] != graphId):
|
||||
# fuck export param, exit
|
||||
return
|
||||
|
||||
# make sure sub layer column map is ok
|
||||
if sublayer not in subLayerColumnMap.keys():
|
||||
subLayerColumnMap[sublayer] = []
|
||||
|
||||
# register self
|
||||
# mark processed
|
||||
processedOper.add(oper)
|
||||
subLayerColumnMap[sublayer].append(oper)
|
||||
|
||||
# record layer occupation
|
||||
layer = bb_layer_map[bb]
|
||||
occupiedLayerMap[layer] = max(occupiedLayerMap.get(layer, -1), sublayer)
|
||||
|
||||
# iterate sub item
|
||||
exCur.execute("SELECT [input_obj] FROM pLink WHERE ([output_obj] == ? AND [input_type] == ? AND [input_is_bb] == 0) ORDER BY [output_index];", (oper, dcv.dbPLinkInputOutputType.POUT))
|
||||
res = []
|
||||
for i in exCur.fetchall():
|
||||
res.append(i[0])
|
||||
|
||||
for i in res:
|
||||
recursiveBuildOperTree(i, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer + 1, bb, graphId, subLayerColumnMap)
|
||||
|
||||
def buildCell(exDb, deDb, target, currentGraphBlockCell):
|
||||
exCur = exDb.cursor()
|
||||
deCur = deDb.cursor()
|
||||
# prepare block set
|
||||
blockSet = set()
|
||||
for i in currentGraphBlockCell.keys():
|
||||
blockSet.add(i)
|
||||
|
||||
# find current graph's pio bio
|
||||
boutx = set()
|
||||
pouty = set()
|
||||
graphPIO = set()
|
||||
|
||||
# bOut.x and pOut.y data is not confirmed, when graph size was confirmed,
|
||||
# update it
|
||||
exCur.execute("SELECT [thisobj], [name], [index] FROM bIn WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
x = 0
|
||||
y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
|
||||
currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
|
||||
exCur.execute("SELECT [thisobj], [name], [index] FROM bOut WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
x = 0
|
||||
y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
|
||||
currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
|
||||
boutx.add(i[0])
|
||||
|
||||
exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pIn WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
|
||||
y = 0
|
||||
currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
|
||||
graphPIO.add(i[0])
|
||||
exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pOut WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
|
||||
y = 0
|
||||
currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
|
||||
graphPIO.add(i[0])
|
||||
pouty.add(i[0])
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?", (target,))
|
||||
cache = exCur.fetchone()
|
||||
if cache != None:
|
||||
currentGraphBlockCell[cache[0]] = dcv.BlockCellItem(0, 0, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, 0, 0, ?)", (target, i[0], i[1], i[2], dcv.CellType.PTARGET))
|
||||
graphPIO.add(cache[0])
|
||||
|
||||
# query all plocal
|
||||
allLocal = set()
|
||||
localUsageCounter = {}
|
||||
exCur.execute("SELECT [thisobj], [name], [type] FROM pLocal WHERE [belong_to] == ?;", (target,))
|
||||
for i in exCur.fetchall():
|
||||
allLocal.add(i[0])
|
||||
localUsageCounter[i[0]] = dcv.LocalUsageItem(0, False, dcv.LocalUsageType.PLOCAL)
|
||||
|
||||
# query all links(don't need to consider export pIO, due to it will not add
|
||||
# any shortcut)
|
||||
# !! the same if framework in pLink generator function !! SHARED
|
||||
createdShortcut = set()
|
||||
exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
|
||||
# analyse 5 chancee one by one
|
||||
if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
|
||||
if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
|
||||
if i[2] in allLocal or i[2] in createdShortcut:
|
||||
cache = localUsageCounter[i[2]]
|
||||
else:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
|
||||
localUsageCounter[i[2]] = cache
|
||||
createdShortcut.add(i[2])
|
||||
|
||||
cache.count += 1
|
||||
cache.lastUse = i[6]
|
||||
cache.lastDirection = 0
|
||||
cache.lastIndex = i[9]
|
||||
|
||||
elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
|
||||
if i[2] == target:
|
||||
continue # ignore self pIn/pOut. it doesn't need any shortcut
|
||||
if i[2] not in blockSet:
|
||||
if i[0] not in createdShortcut:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PIN)
|
||||
localUsageCounter[i[0]] = cache
|
||||
createdShortcut.add(i[0])
|
||||
else:
|
||||
cache = localUsageCounter[i[0]]
|
||||
|
||||
cache.count+=1
|
||||
cache.lastUse = i[6]
|
||||
cache.lastDirection = 0
|
||||
cache.lastIndex = i[9]
|
||||
elif (i[3] == dcv.dbPLinkInputOutputType.PATTR): # for attribute using
|
||||
if i[2] not in createdShortcut:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PATTR)
|
||||
localUsageCounter[i[2]] = cache
|
||||
createdShortcut.add(i[2])
|
||||
else:
|
||||
cache = localUsageCounter[i[2]]
|
||||
|
||||
cache.count+=1
|
||||
cache.lastUse = i[6]
|
||||
cache.lastDirection = 0
|
||||
cache.lastIndex = i[9]
|
||||
else:
|
||||
if i[2] not in blockSet:
|
||||
if i[0] not in createdShortcut:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
|
||||
localUsageCounter[i[0]] = cache
|
||||
createdShortcut.add(i[0])
|
||||
else:
|
||||
cache = localUsageCounter[i[0]]
|
||||
|
||||
cache.count+=1
|
||||
cache.lastUse = i[6]
|
||||
cache.lastDirection = 1
|
||||
cache.lastIndex = i[9]
|
||||
else:
|
||||
if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
|
||||
if i[6] in allLocal or i[6] in createdShortcut:
|
||||
cache = localUsageCounter[i[6]]
|
||||
else:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
|
||||
localUsageCounter[i[6]] = cache
|
||||
createdShortcut.add(i[6])
|
||||
|
||||
cache.count += 1
|
||||
cache.lastUse = i[2]
|
||||
cache.lastDirection = 1
|
||||
cache.lastIndex = i[5]
|
||||
else:
|
||||
if i[6] == target:
|
||||
continue # ignore self pIn/pOut. it doesn't need any shortcut
|
||||
if i[6] not in blockSet:
|
||||
if i[1] not in createdShortcut:
|
||||
cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
|
||||
localUsageCounter[i[1]] = cache
|
||||
createdShortcut.add(i[1])
|
||||
else:
|
||||
cache = localUsageCounter[i[1]]
|
||||
|
||||
cache.count += 1
|
||||
cache.lastUse = i[2]
|
||||
cache.lastDirection = 1
|
||||
cache.lastIndex = i[5]
|
||||
|
||||
# apply all cells
|
||||
defaultCellIndex = 0
|
||||
for i in localUsageCounter.keys():
|
||||
cache = localUsageCounter[i]
|
||||
# comput x,y
|
||||
if (cache.count == 1):
|
||||
# attachable
|
||||
attachTarget = currentGraphBlockCell[cache.lastUse]
|
||||
(x, y) = computCellPosition(attachTarget.x, attachTarget.y, attachTarget.h, cache.lastDirection, cache.lastIndex)
|
||||
|
||||
else:
|
||||
# place it in default area
|
||||
y = dcv.GRAPH_CONTENTOFFSET_Y
|
||||
x = dcv.GRAPH_CONTENTOFFSET_X + defaultCellIndex * (dcv.CELL_WIDTH + dcv.GRAPH_BB_SPAN)
|
||||
defaultCellIndex += 1
|
||||
# get information
|
||||
if (cache.internal_type == dcv.LocalUsageType.PIN):
|
||||
tableName = 'pIn'
|
||||
elif (cache.internal_type == dcv.LocalUsageType.POUT):
|
||||
tableName = 'pOut'
|
||||
elif (cache.internal_type == dcv.LocalUsageType.PATTR):
|
||||
tableName = 'pAttr'
|
||||
else:
|
||||
tableName = 'pLocal'
|
||||
exCur.execute("SELECT [name], [type] FROM {} WHERE [thisobj] == ?".format(tableName), (i,))
|
||||
temp = exCur.fetchone()
|
||||
|
||||
# submit to database and map
|
||||
currentGraphBlockCell[i] = dcv.BlockCellItem(x, y, dcv.CELL_WIDTH, dcv.CELL_HEIGHT)
|
||||
deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
(target, i, temp[0], temp[1], x, y, (dcv.CellType.SHORTCUT if cache.isshortcut else dcv.CellType.PLOCAL)))
|
||||
|
||||
# comput size and update database and currentGraphBlockCell
|
||||
graphX = 0
|
||||
graphY = 0
|
||||
for key, values in currentGraphBlockCell.items():
|
||||
graphX = max(graphX, values.x + values.w)
|
||||
graphY = max(graphY, values.y + values.h)
|
||||
graphX += dcv.GRAPH_POFFSET
|
||||
graphY += dcv.GRAPH_BOFFSET
|
||||
|
||||
deCur.execute("UPDATE graph SET [width] = ?, [height] = ? WHERE [graph] == ?", (graphX, graphY, target))
|
||||
|
||||
# update bOut.x and pOut.y data
|
||||
for i in boutx:
|
||||
deCur.execute("UPDATE cell SET [x] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphX - dcv.BB_PBSIZE, i, target))
|
||||
currentGraphBlockCell[i].x = graphX - dcv.BB_PBSIZE
|
||||
for i in pouty:
|
||||
deCur.execute("UPDATE cell SET [y] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphY - dcv.BB_PBSIZE, i, target))
|
||||
currentGraphBlockCell[i].y = graphY - dcv.BB_PBSIZE
|
||||
|
||||
return graphPIO
|
||||
|
||||
def computCellPosition(baseX, baseY, height, direction, index):
|
||||
if (index == -1):
|
||||
return (baseX, baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
|
||||
|
||||
if (direction == 0):
|
||||
return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
|
||||
else:
|
||||
return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY + height + dcv.GRAPH_SPAN_BB_PLOCAL)
|
||||
|
||||
def buildLink(exDb, deDb, target, currentGraphBlockCell, graphPIO):
|
||||
exCur = exDb.cursor()
|
||||
deCur = deDb.cursor()
|
||||
|
||||
# prepare block set
|
||||
blockSet = set()
|
||||
for i in currentGraphBlockCell.keys():
|
||||
blockSet.add(i)
|
||||
|
||||
# bLink
|
||||
exCur.execute("SELECT * FROM bLink WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
if i[3] == target:
|
||||
(x1, y1) = computLinkBTerminal(i[0], 0, -1 ,currentGraphBlockCell)
|
||||
bStartObj = i[0]
|
||||
bStartType = 0
|
||||
bStartIndex = -1
|
||||
else:
|
||||
(x1, y1) = computLinkBTerminal(i[3], i[4], i[5], currentGraphBlockCell)
|
||||
bStartObj = i[3]
|
||||
bStartType = i[4]
|
||||
bStartIndex = i[5]
|
||||
if i[6] == target:
|
||||
(x2, y2) = computLinkBTerminal(i[1], 0, -1,currentGraphBlockCell)
|
||||
bEndObj = i[1]
|
||||
bEndType = 0
|
||||
bEndIndex = -1
|
||||
else:
|
||||
(x2, y2) = computLinkBTerminal(i[6], i[7], i[8],currentGraphBlockCell)
|
||||
bEndObj = i[6]
|
||||
bEndType = i[7]
|
||||
bEndIndex = i[8]
|
||||
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, i[2], i[0], i[1], bStartObj, bEndObj, bStartType, bEndType, bStartIndex, bEndIndex, x1, y1, x2, y2))
|
||||
|
||||
# pLink
|
||||
# !! the same if framework in cell generator function !! SHARED
|
||||
exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
# analyse 5 chancee one by one
|
||||
if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
|
||||
if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
|
||||
(x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
|
||||
(x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
|
||||
|
||||
elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
|
||||
(x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
|
||||
if i[2] == target:
|
||||
(x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[0], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
|
||||
else:
|
||||
(x1, y1) = computLinkPTerminal(i[2], 0, i[5], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 0, 0, i[5], i[9], x1, y1, x2, y2))
|
||||
elif (i[3] == dcv.dbPLinkInputOutputType.PATTR):
|
||||
(x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
|
||||
(x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
|
||||
else:
|
||||
if i[2] in blockSet: # process protencial pOut(shortcut) (because plocal input/input_obj
|
||||
# output/output_obj is same, so don't need add for them)
|
||||
(x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
|
||||
else:
|
||||
(x1, y1) = computLinkPTerminal(i[0], 1, i[5], currentGraphBlockCell)
|
||||
(x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], i[9], x1, y1, x2, y2))
|
||||
|
||||
else:
|
||||
if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
|
||||
(x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
|
||||
(x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], -1, x1, y1, x2, y2))
|
||||
else:
|
||||
(x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
|
||||
if i[6] == target:
|
||||
(x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[1], 1, 0, i[5], -1, x1, y1, x2, y2))
|
||||
else:
|
||||
(x2, y2) = computLinkPTerminal(i[6], 1, i[9], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -1, i[0], i[1], i[2], i[6], 1, 1, i[5], i[9], x1, y1, x2, y2))
|
||||
|
||||
# eLink
|
||||
exCur.execute("SELECT * FROM eLink WHERE [belong_to] == ?", (target,))
|
||||
for i in exCur.fetchall():
|
||||
(x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
|
||||
(x2, y2) = computLinkPTerminal(i[1], 0 if i[2] == 1 else 1, i[3], currentGraphBlockCell)
|
||||
deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
|
||||
(target, -2, i[0], i[0], target, i[1], 0, 0 if i[2] == 1 else 1, -1, i[3], x1, y1, x2, y2))
|
||||
|
||||
def computLinkBTerminal(obj, xtype, index, currentGraphBlockCell):
|
||||
# index = -1 mean no offset, it will connect to graph io
|
||||
cache = currentGraphBlockCell[obj]
|
||||
return (cache.x if xtype == 0 else cache.x + cache.w - dcv.BB_PBSIZE,
|
||||
cache.y if index == -1 else (cache.y + dcv.BB_BOFFSET + index * (dcv.BB_PBSIZE + dcv.BB_BSPAN)))
|
||||
|
||||
def computLinkPTerminal(obj, ytype, index, currentGraphBlockCell):
|
||||
# ytype is not database type. it have the same meaning of LinkBTerminal,
|
||||
# indicating the position. 0 is keep origin position(for pIn and pTarget),
|
||||
# 1 is consider height(for pOut)
|
||||
cache = currentGraphBlockCell[obj]
|
||||
return (cache.x if index == -1 else (cache.x + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN)),
|
||||
cache.y if ytype == 0 else (cache.y + cache.h - dcv.BB_PBSIZE))
|
||||
|
||||
def buildInfo(exDb, deDb):
|
||||
exInfoCur = exDb.cursor()
|
||||
exQueryCur = exDb.cursor()
|
||||
deCur = deDb.cursor()
|
||||
|
||||
# declare tiny storage for convenient query
|
||||
tinyStorageKey = 0
|
||||
tinyStorageBB = -1
|
||||
tinyStorageSetting = 0
|
||||
tinyStorageName = ""
|
||||
|
||||
# export local data (including proto bb internal data)
|
||||
exInfoCur.execute("SELECT * FROM pData;")
|
||||
for i in exInfoCur.fetchall():
|
||||
attachBB = -1
|
||||
isSetting = 0
|
||||
infoName = ""
|
||||
|
||||
if i[2] == tinyStorageKey:
|
||||
attachBB = tinyStorageBB
|
||||
isSetting = tinyStorageSetting
|
||||
infotName = tinyStorageName
|
||||
else:
|
||||
# clear storage first
|
||||
tinyStorageBB = -1
|
||||
tinyStorageSetting = 0
|
||||
tinyStorageName = ""
|
||||
|
||||
# query correspond pLocal
|
||||
exQueryCur.execute("SELECT [belong_to], [is_setting], [name] FROM pLocal WHERE [thisobj] = ?", (i[2], ))
|
||||
plocalCache = exQueryCur.fetchone()
|
||||
if plocalCache is not None:
|
||||
# add setting config
|
||||
tinyStorageSetting = isSetting = plocalCache[1]
|
||||
tinyStorageName = infoName = plocalCache[2]
|
||||
# query bb again
|
||||
exQueryCur.execute("SELECT [thisobj] FROM behavior WHERE ([thisobj] = ? AND [type] = 0)", (plocalCache[0], ))
|
||||
behaviorCache = exQueryCur.fetchone()
|
||||
if behaviorCache is not None:
|
||||
tinyStorageBB = attachBB = behaviorCache[0]
|
||||
|
||||
deCur.execute("INSERT INTO info VALUES (?, ?, ?, ?, ?, ?)", (i[2], attachBB, isSetting, infoName, i[0], i[1]))
|
||||
@@ -1,118 +0,0 @@
|
||||
import sqlite3, json, collections
|
||||
import CustomConfig, Progressbar
|
||||
import DecoratorBB, DecoratorConst
|
||||
|
||||
class CompositionIngredients(object):
|
||||
def __init__(self, name: str, export_id: int, env_id: int):
|
||||
self.m_CompositionName: str = name
|
||||
self.m_ExportIndex = export_id
|
||||
self.m_EnvIndex = env_id
|
||||
|
||||
def __InitDecoratedDb(db: sqlite3.Connection):
|
||||
cur = db.cursor()
|
||||
cur.execute("CREATE TABLE [compositions] ([id] INTEGER, [name] TEXT, [export_id] INTEGER, [env_id] INTEGER);")
|
||||
|
||||
cur.execute("CREATE TABLE [graph_graph] ([parent_export] INTEGER, [thisobj] INTEGER, [name] TEXT, [hierarchy] TEXT, [height] REAL, [width] REAL, [bind_behavior] TEXT, [bind_beh_ord] INTEGER);")
|
||||
#cur.execute("CREATE TABLE info([target] INTEGER, [attach_bb] INTEGER, [is_setting] INTEGER, [name] TEXT, [field] TEXT, [data] TEXT);")
|
||||
|
||||
cur.execute("CREATE TABLE [graph_block] ([parent_graph] INETGER, [parent_export] INTEGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [width] REAL, [height] REAL, [expand_id] INTEGER);")
|
||||
cur.execute("CREATE TABLE [graph_cell] ([parent_graph] INETGER, [parent_export] INTEGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [type] INTEGER);")
|
||||
cur.execute("CREATE TABLE [graph_particle] ([parent_graph] INETGER, [parent_export] INTEGER, [thisobj] INTEGER, [name] TEXT, [x] REAL, [y] REAL, [type] INTEGER, [relation_block] INTEGER);")
|
||||
cur.execute("CREATE TABLE [graph_link] ([parent_graph] INETGER, [parent_export] INTEGER, [delay] INTEGER, [start_particle] INTEGER, [end_particle] INTEGER, [start_block] INTEGER, [end_block] INTEGER, [line_type] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);")
|
||||
|
||||
db.commit()
|
||||
cur.close()
|
||||
|
||||
def __GenerateCompositions(cfg: CustomConfig.CustomConfig) -> tuple[tuple[CompositionIngredients], tuple[str], tuple[str]]:
|
||||
compositions: list[CompositionIngredients] = []
|
||||
exportdb: collections.OrderedDict = collections.OrderedDict()
|
||||
envdb: collections.OrderedDict = collections.OrderedDict()
|
||||
|
||||
for entry in cfg.m_InputEntries:
|
||||
# check 2 database
|
||||
export_id = exportdb.get(entry.m_ExportDb, None)
|
||||
if export_id is None:
|
||||
export_id = len(exportdb)
|
||||
exportdb[entry.m_ExportDb] = export_id
|
||||
|
||||
env_id = envdb.get(entry.m_EnvDb, None)
|
||||
if env_id is None:
|
||||
env_id = len(envdb)
|
||||
envdb[entry.m_EnvDb] = env_id
|
||||
|
||||
# create record
|
||||
compositions.append(CompositionIngredients(entry.m_Name, export_id, env_id))
|
||||
|
||||
return (
|
||||
tuple(compositions),
|
||||
tuple(exportdb.keys()),
|
||||
tuple(envdb.keys())
|
||||
)
|
||||
|
||||
def __UploadComposition(db: sqlite3.Connection, compositions: list[CompositionIngredients]):
|
||||
cur = db.cursor()
|
||||
cur.executemany('INSERT INTO [compositions] VALUES(?, ?, ?, ?);',
|
||||
((idx, ingredient.m_CompositionName, ingredient.m_ExportIndex, ingredient.m_EnvIndex) for idx, ingredient in enumerate(compositions))
|
||||
)
|
||||
|
||||
db.commit()
|
||||
cur.close()
|
||||
|
||||
def __ProcessGraph(cfg: CustomConfig.CustomConfig, export_id: int, export_filename: str):
|
||||
# create database and apply encoding
|
||||
db: sqlite3.Connection = sqlite3.connect(export_filename)
|
||||
db.text_factory = lambda x: x.decode(cfg.m_DatabaseEncoding, errors="ignore")
|
||||
|
||||
# create a cursor to get graph
|
||||
cur: sqlite3.Cursor = db.cursor()
|
||||
cur.execute('SELECT [thisobj] FROM [script_behavior] WHERE [type] != ?;',
|
||||
(DecoratorConst.Export_Behavior_Type.FUNCTION, )
|
||||
)
|
||||
|
||||
# proc each graph
|
||||
for (thisobj, ) in cur.fetchall():
|
||||
# todo: add more proc step
|
||||
blocks: DecoratorBB.BlocksFactory = DecoratorBB.BlocksFactory(db, thisobj)
|
||||
del blocks
|
||||
|
||||
# todo: recursively build [graph_graph]
|
||||
|
||||
# close db
|
||||
cur.close()
|
||||
db.close()
|
||||
|
||||
|
||||
def Run(cfg: CustomConfig.CustomConfig):
|
||||
# establish target database
|
||||
print('Opening decorated database...')
|
||||
decorateDb: sqlite3.Connection = sqlite3.connect(cfg.m_DecoratedDb)
|
||||
|
||||
# init table
|
||||
print('Initializing decorated database...')
|
||||
__InitDecoratedDb(decorateDb)
|
||||
decorateDb.commit()
|
||||
|
||||
# we need know which database we need analyse first
|
||||
print('Generating compositions...')
|
||||
(compositions, exportdb, envdb) = __GenerateCompositions(cfg)
|
||||
__UploadComposition(decorateDb, compositions)
|
||||
print(f'Analysation done. {len(exportdb)} Export DB and {len(envdb)} Env DB.')
|
||||
|
||||
# process export
|
||||
print('Generating graphs...')
|
||||
progressbar: Progressbar.Prograssbar = Progressbar.Prograssbar(len(exportdb))
|
||||
for expid, exp in enumerate(exportdb):
|
||||
__ProcessGraph(cfg, expid, exp)
|
||||
progressbar.Finish()
|
||||
|
||||
# process env
|
||||
print('Generating infos...')
|
||||
progressbar = Progressbar.Prograssbar(len(envdb))
|
||||
for envid, env in enumerate(envdb):
|
||||
pass
|
||||
progressbar.Finish()
|
||||
|
||||
# close database
|
||||
print('Closing decorated database...')
|
||||
decorateDb.commit()
|
||||
decorateDb.close()
|
||||
@@ -1,192 +0,0 @@
|
||||
'''
|
||||
NOTE:
|
||||
|
||||
There are 3 different styles shape in generated graph.
|
||||
"Block" is stands for the large block, including BB and pOper.
|
||||
"Cell" is stands for the medium block, including pLocal, pAttr, Shortcut.
|
||||
"Particle" is stands for the small block, including bIO, pIO, pTarget.
|
||||
|
||||
Besides these shapes, the generated graph also include various links.
|
||||
There are 2 types link. bLink and pLink.
|
||||
'''
|
||||
import typing, collections, sqlite3
|
||||
|
||||
class Vector(object):
|
||||
def __init__(self):
|
||||
self.X: float = 0.0
|
||||
self.Y: float = 0.0
|
||||
def __init__(self, x: float, y: float):
|
||||
self.X: float = x
|
||||
self.Y: float = y
|
||||
|
||||
@property
|
||||
def LenLeavesDir(self):
|
||||
return self.X
|
||||
@LenLeavesDir.setter
|
||||
def LenLeavesDir(self, v):
|
||||
self.X = v
|
||||
@property
|
||||
def LenRootsDir(self):
|
||||
return self.Y
|
||||
@LenRootsDir.setter
|
||||
def LenRootsDir(self, v):
|
||||
self.Y = v
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return Vector(self.X + other.X, self.Y + other.Y)
|
||||
def __sub__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return Vector(self.X - other.X, self.Y - other.Y)
|
||||
|
||||
def __radd__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return Vector(self.X + other.X, self.Y + other.Y)
|
||||
def __rsub__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return Vector(self.X - other.X, self.Y - other.Y)
|
||||
|
||||
def __iadd__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
self.X += other.X
|
||||
self.Y += other.Y
|
||||
return self
|
||||
def __isub__(self, other):
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
self.X -= other.X
|
||||
self.Y -= other.Y
|
||||
return self
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return (self.X == other.X and self.Y == other.Y)
|
||||
def __ne__(self, other) -> bool:
|
||||
if not isinstance(other, Vector): return NotImplemented
|
||||
return (self.X != other.X or self.Y != other.Y)
|
||||
|
||||
class Margin(object):
|
||||
def __init__(self):
|
||||
self.m_TopSize: Vector = Vector()
|
||||
self.m_BodySize: Vector = Vector()
|
||||
self.m_BottomSize: Vector = Vector()
|
||||
|
||||
class ICanManipulate(object):
|
||||
'''
|
||||
This class is served for TreeLayout class.
|
||||
|
||||
All classes inherit this class will have ability to calculate the size of self,
|
||||
and report to TreeLayout. TreeLayout will use these data to distribute position.
|
||||
|
||||
The functions declared in this class have unique name meaning.
|
||||
The reason is that the vertical and horizonal direction between BB and Oper is opposited.
|
||||
So we use Leaves and Root to give theme an uniformed concept.
|
||||
'''
|
||||
def SetOrigin():
|
||||
pass
|
||||
def ComputeSize() -> Vector:
|
||||
'''
|
||||
Get current node's start position
|
||||
'''
|
||||
raise NotImplementedError()
|
||||
|
||||
TNode = typing.TypeVar('TNode', bound=ICanManipulate)
|
||||
|
||||
class TreeLayoutLayer(typing.Generic[TNode]):
|
||||
def __init__(self, ref_layer: int, start_pos_of_ref_layer: int):
|
||||
self.m_Container: collections.deque[TNode] = collections.deque()
|
||||
self.m_RefLayer: int = ref_layer
|
||||
self.m_RefLayerIndex: int = start_pos_of_ref_layer
|
||||
|
||||
class TreeLayout(typing.Generic[TNode]):
|
||||
NO_REFERENCE_LAYER: int = -1
|
||||
NO_START_POS_OF_REF_LAYER: int = -1
|
||||
|
||||
def __init__(self):
|
||||
self.m_Layers: collections.deque[TreeLayoutLayer[TNode]] = collections.deque()
|
||||
self.__CurrentLayer: TreeLayoutLayer[TNode] = None
|
||||
|
||||
def GetCurrentLayerIndex(self) -> int:
|
||||
if self.__CurrentLayer is None: raise Exception("No layer!")
|
||||
return len(self.m_Layers) - 1
|
||||
|
||||
def GetCurrentItemIndex(self) -> int:
|
||||
if self.__CurrentLayer is None: raise Exception("No layer!")
|
||||
result = len(self.__CurrentLayer.m_Container)
|
||||
if result == 0: raise Exception("No item!")
|
||||
return result - 1
|
||||
|
||||
def NewLayer(self, ref_layer: int, start_pos_of_ref_layer: int):
|
||||
self.__CurrentLayer = TreeLayoutLayer(ref_layer, start_pos_of_ref_layer)
|
||||
self.m_Layers.append(self.__CurrentLayer)
|
||||
|
||||
def NewItem(self, node: TNode):
|
||||
if self.__CurrentLayer is None: raise Exception("No layer to append data!")
|
||||
self.__CurrentLayer.m_Container.append(node)
|
||||
|
||||
|
||||
class BBDataPayload(object):
|
||||
SqlTableProto = collections.namedtuple('Behavior', 'thisobj, name, type, proto_name, proto_guid, flags, priority, version, pin_count, parent')
|
||||
|
||||
def __init__(self, sql_data: tuple):
|
||||
v = BBDataPayload.SqlTableProto._make(sql_data)
|
||||
|
||||
self.m_CKID: int = v.thisobj
|
||||
self.m_Name: str = v.name
|
||||
self.m_Type: int = v.type
|
||||
self.m_ProtoName: str = v.proto_name
|
||||
self.m_ProtoGUID: str = v.proto_guid
|
||||
self.m_Flags: int = v.flags
|
||||
self.m_Priority: int = v.priority
|
||||
self.m_Version: int = v.version
|
||||
self.m_Parent: int = v.parent
|
||||
|
||||
div_pin_count = v.pin_count.split(',')
|
||||
self.m_pTargetExisting: bool = int(div_pin_count[0] == 1)
|
||||
self.m_pInCount: int = int(div_pin_count[1])
|
||||
self.m_pOutCount: int = int(div_pin_count[2])
|
||||
self.m_bInCount: int = int(div_pin_count[3])
|
||||
self.m_bOutCount: int = int(div_pin_count[4])
|
||||
|
||||
class OperDataPayload(object):
|
||||
SqlTableProto = collections.namedtuple('Oper', 'thisobj, name, op_guid, parent')
|
||||
|
||||
def __init__(self, sql_data: tuple):
|
||||
v = OperDataPayload.SqlTableProto._make(sql_data)
|
||||
self.m_CKID: int = v.thisobj
|
||||
self.m_Name: str = v.name
|
||||
self.m_OpGuid: str = v.op_guid
|
||||
self.m_Parent: int = v.parent
|
||||
|
||||
class OperTreeNodeWrapper(ICanManipulate):
|
||||
def __init__(self, payload: OperDataPayload):
|
||||
self.m_Payload: OperDataPayload = payload
|
||||
|
||||
class BBTreeNodeWrapper(ICanManipulate):
|
||||
def __init__(self, payload: BBDataPayload):
|
||||
self.m_UpperOper: TreeLayout[OperTreeNodeWrapper] = TreeLayout()
|
||||
self.m_LowerOper: TreeLayout[OperTreeNodeWrapper] = TreeLayout()
|
||||
self.m_Upperval: collections.deque = collections.deque()
|
||||
self.m_LowerVal: collections.deque = collections.deque()
|
||||
|
||||
self.m_Payload: BBDataPayload = payload
|
||||
|
||||
|
||||
class GraphResult(ICanManipulate):
|
||||
def __init__(self):
|
||||
self.m_GraphCKID: int = 0
|
||||
|
||||
self.m_BBDict: dict[int, BBTreeNodeWrapper] = {}
|
||||
self.m_OperDict: dict[int, OperTreeNodeWrapper] = {}
|
||||
self.m_CellDict: dict[int, ICanManipulate] = {}
|
||||
self.m_ParticleDict: dict[int, ICanManipulate] = {}
|
||||
|
||||
self.m_bIn: collections.deque = collections.deque()
|
||||
self.m_bOut: collections.deque = collections.deque()
|
||||
self.m_pIn: collections.deque = collections.deque()
|
||||
self.m_pOut: collections.deque = collections.deque()
|
||||
|
||||
self.m_PassiveVal: collections.deque = collections.deque()
|
||||
self.m_PassiveOper: TreeLayout[OperTreeNodeWrapper] = TreeLayout()
|
||||
self.m_ActivePassiveBB: TreeLayout[BBTreeNodeWrapper] = TreeLayout()
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import sys
|
||||
|
||||
class Prograssbar(object):
|
||||
def __init__(self, filecount: int):
|
||||
if (filecount < 0): raise Exception("Progressbar can not hold minus length!")
|
||||
|
||||
self.__FileCount: int = filecount
|
||||
self.__FileNow: int = 0
|
||||
self.__ContentCount: int = 0
|
||||
self.__ContentNow: int = 0
|
||||
|
||||
self.__PbarFullChar: int = 50
|
||||
self.__PercentPerFile: float = 1 / self.__FileCount
|
||||
self.__CurFileName: str = None
|
||||
|
||||
self.__Render()
|
||||
|
||||
def StepFile(self, newfile: str, content_len: int):
|
||||
if self.__CurFileName is not None:
|
||||
# not first call, INC FileNow
|
||||
# if first call, do not INC it
|
||||
self.__FileNow += 1
|
||||
# apply others
|
||||
self.__CurFileName = newfile
|
||||
self.__ContentNow = 0
|
||||
self.__ContentCount = content_len
|
||||
|
||||
self.__Render()
|
||||
|
||||
def StepContent(self):
|
||||
self.__ContentNow += 1
|
||||
|
||||
self.__Render()
|
||||
|
||||
def Finish(self):
|
||||
sys.stdout.write('\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
def __Render(self):
|
||||
percentage_content: float = 0 if self.__ContentCount == 0 else (self.__ContentNow / self.__ContentCount)
|
||||
percentage_full: float = (percentage_content + self.__FileNow) * self.__PercentPerFile
|
||||
|
||||
percentage_bar = int(percentage_full * self.__PbarFullChar)
|
||||
|
||||
sys.stdout.write('\r[{}{}] {:.2f}% - {}'.format(
|
||||
percentage_bar * '#',
|
||||
(self.__PbarFullChar - percentage_bar) * '=',
|
||||
percentage_full * 100,
|
||||
self.__CurFileName if self.__CurFileName else ''
|
||||
))
|
||||
sys.stdout.flush()
|
||||
@@ -1,51 +0,0 @@
|
||||
import CustomConfig, DecoratorCore, Progressbar
|
||||
import os, sys, getopt, logging, time
|
||||
|
||||
# print banner
|
||||
print('Super Script Decorator')
|
||||
print('Homepage: https://github.com/yyc12345/SuperScriptMaterializer')
|
||||
print('Report bug: https://github.com/yyc12345/SuperScriptMaterializer/issues')
|
||||
print('')
|
||||
|
||||
# try get args
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hi:o:e:c:fd")
|
||||
except getopt.GetoptError:
|
||||
print('Wrong arguments!')
|
||||
print('python SuperScriptViewer.py -i <import.txt> -o <decorated.db> -c <codec_name> -d')
|
||||
sys.exit(1)
|
||||
|
||||
# analyze args
|
||||
cfg: CustomConfig.CustomConfig = CustomConfig.CustomConfig()
|
||||
for opt, arg in opts:
|
||||
if opt == '-h':
|
||||
print('python SuperScriptViewer.py -i <import.txt> -o <decorated.db> -c <codec_name> -d')
|
||||
sys.exit(0)
|
||||
elif opt == '-i':
|
||||
cfg.m_ImportTxt = arg
|
||||
elif opt == '-o':
|
||||
cfg.m_DecoratedDb = arg
|
||||
elif opt == '-c':
|
||||
cfg.m_DatabaseEncoding = arg
|
||||
elif opt == '-d':
|
||||
cfg.m_DebugMode = True
|
||||
|
||||
# regulate data
|
||||
if not cfg.Regulate():
|
||||
# failed. exit program
|
||||
sys.exit(1)
|
||||
|
||||
# if in debug mode, run directly
|
||||
# otherwise, run with a try wrapper.
|
||||
if cfg.m_DebugMode:
|
||||
DecoratorCore.Run(cfg)
|
||||
else:
|
||||
try:
|
||||
DecoratorCore.Run(cfg)
|
||||
except Exception as ex:
|
||||
print("!!! An error occurs. Please report follwoing error output and reproduce file to developer. !!!")
|
||||
logging.exception(ex)
|
||||
sys.exit(1)
|
||||
|
||||
print('Decorated database generation done.')
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29418.71
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SuperScriptMaterializer", "SuperScriptMaterializer\SuperScriptMaterializer.vcxproj", "{4D941003-020F-47FD-9FA2-FFC989E306B8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4D941003-020F-47FD-9FA2-FFC989E306B8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4D941003-020F-47FD-9FA2-FFC989E306B8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4D941003-020F-47FD-9FA2-FFC989E306B8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4D941003-020F-47FD-9FA2-FFC989E306B8}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {291FA855-812F-4C42-819E-6E463AEB219E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,135 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{4D941003-020F-47FD-9FA2-FFC989E306B8}</ProjectGuid>
|
||||
<RootNamespace>SuperScriptMaterializer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<UseOfMfc>Dynamic</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType></PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<UseOfMfc>Dynamic</UseOfMfc>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType></PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="Virtools.props"/>
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="Virtools.props"/>
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros"/>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(VIRTOOLS_OUTPUT_PATH)</OutDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>Temp\$(Configuration)\</IntDir>
|
||||
<TargetExt>.$(VIRTOOLS_BUILD_SUFFIX)</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(VIRTOOLS_OUTPUT_PATH)</OutDir>
|
||||
<IntDir>Temp\$(Configuration)\</IntDir>
|
||||
<TargetExt>.$(VIRTOOLS_BUILD_SUFFIX)</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(VIRTOOLS_HEADER_PATH);$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;$(VIRTOOLS_VER);$(VIRTOOLS_STD_MACRO);$(VIRTOOLS_EXTRA_MACRO);VX_MEM_RELEASE;$(VIRTOOLS_BUILD_TYPE);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableSpecificWarnings>4819;4996</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(VIRTOOLS_OUTPUT_PATH)SuperScriptMaterializer.$(VIRTOOLS_BUILD_SUFFIX)</OutputFile>
|
||||
</Link>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SQLITE_LIB_PATH);$(VIRTOOLS_LIB_PATH);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(SQLITE_LIB_FILENAME);$(VIRTOOLS_LIB_FILENAME);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(VIRTOOLS_OUTPUT_PATH)SuperScriptMaterializer.pdb</ProgramDatabaseFile>
|
||||
<ModuleDefinitionFile>$(VIRTOOLS_MODULE_DEFINE)</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FunctionLevelLinking>
|
||||
</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(VIRTOOLS_HEADER_PATH);$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;$(VIRTOOLS_VER);$(VIRTOOLS_STD_MACRO);$(VIRTOOLS_EXTRA_MACRO);VX_MEM_RELEASE;_RELEASE;$(VIRTOOLS_BUILD_TYPE);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<DisableSpecificWarnings>4819;4996</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>$(VIRTOOLS_MODULE_DEFINE)</ModuleDefinitionFile>
|
||||
<OutputFile>$(VIRTOOLS_OUTPUT_PATH)SuperScriptMaterializer.$(VIRTOOLS_BUILD_SUFFIX)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(VIRTOOLS_LIB_PATH);$(SQLITE_LIB_PATH);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(SQLITE_LIB_FILENAME);$(VIRTOOLS_LIB_FILENAME);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ProgramDatabaseFile>$(VIRTOOLS_OUTPUT_PATH)SuperScriptMaterializer.pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="database.hpp"/>
|
||||
<ClInclude Include="env_export.hpp"/>
|
||||
<ClInclude Include="resource.h"/>
|
||||
<ClInclude Include="doc_export.hpp"/>
|
||||
<ClInclude Include="string_helper.hpp"/>
|
||||
<ClInclude Include="virtools_compatible.hpp"/>
|
||||
<ClInclude Include="vt_menu.hpp"/>
|
||||
<ClInclude Include="stdafx.h"/>
|
||||
<ClInclude Include="vt_player.hpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="database.cpp"/>
|
||||
<ClCompile Include="env_export.cpp"/>
|
||||
<ClCompile Include="main.cpp"/>
|
||||
<ClCompile Include="doc_export.cpp"/>
|
||||
<ClCompile Include="string_helper.cpp"/>
|
||||
<ClCompile Include="virtools_compatible.cpp"/>
|
||||
<ClCompile Include="vt_menu.cpp"/>
|
||||
<ClCompile Include="vt_player.cpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SuperScriptMaterializer.def"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Sources">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Headers">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="database.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="env_export.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="doc_export.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vt_menu.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="virtools_compatible.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="string_helper.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vt_player.hpp">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="database.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="env_export.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="doc_export.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vt_menu.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="vt_player.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="virtools_compatible.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="string_helper.cpp">
|
||||
<Filter>Sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SuperScriptMaterializer.def">
|
||||
<Filter>Sources</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>$(VIRTOOLS_DEBUG_TARGET)</LocalDebuggerCommand>
|
||||
<LocalDebuggerCommandArguments>$(VIRTOOLS_DEBUG_COMMANDLINE)</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerWorkingDirectory>$(VIRTOOLS_DEBUG_ROOT)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerCommand>$(VIRTOOLS_DEBUG_TARGET)</LocalDebuggerCommand>
|
||||
<LocalDebuggerCommandArguments>$(VIRTOOLS_DEBUG_COMMANDLINE)</LocalDebuggerCommandArguments>
|
||||
<LocalDebuggerWorkingDirectory>$(VIRTOOLS_DEBUG_ROOT)</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,612 +0,0 @@
|
||||
#include "database.hpp"
|
||||
|
||||
namespace SSMaterializer {
|
||||
|
||||
namespace DataStruct {
|
||||
namespace Helper {
|
||||
|
||||
DocumentHelper::DocumentHelper(CKParameterManager* paramManager) :
|
||||
script(), script_behavior(), script_pOper(),
|
||||
script_bIn(), script_bOut(), script_bLink(),
|
||||
script_pIn(), script_pOut(), script_pLink(), script_eLink(),
|
||||
script_pLocal(), script_pTarget(), script_pAttr(),
|
||||
msg(), obj(),
|
||||
data() {
|
||||
param_manager = paramManager;
|
||||
}
|
||||
|
||||
DocumentHelper::~DocumentHelper() {
|
||||
;
|
||||
}
|
||||
|
||||
EnvironmentHelper::EnvironmentHelper() :
|
||||
op(), param(), attr(), plugin(), variable() {
|
||||
;
|
||||
}
|
||||
|
||||
EnvironmentHelper::~EnvironmentHelper() {
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Database {
|
||||
|
||||
#pragma region universal sqlite database init and free
|
||||
|
||||
SSMaterializerDatabase::SSMaterializerDatabase() :
|
||||
mStmtCache(), mDb(NULL) {
|
||||
;
|
||||
}
|
||||
|
||||
SSMaterializerDatabase::~SSMaterializerDatabase() {
|
||||
;
|
||||
}
|
||||
|
||||
sqlite3_stmt* SSMaterializerDatabase::GetStmt(const char* str_stmt) {
|
||||
// try find first
|
||||
auto probe = mStmtCache.find(reinterpret_cast<const uintptr_t>(str_stmt));
|
||||
if (probe != mStmtCache.end()) {
|
||||
return probe->second;
|
||||
}
|
||||
|
||||
// no found. create one
|
||||
int result;
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
result = sqlite3_prepare_v2(mDb, str_stmt, -1, &stmt, NULL);
|
||||
if (result != SQLITE_OK) return NULL;
|
||||
|
||||
// append new one
|
||||
mStmtCache.emplace(reinterpret_cast<const uintptr_t>(str_stmt), stmt);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
void SSMaterializerDatabase::FakeConstructor(const char* file) {
|
||||
// open mDb
|
||||
int result;
|
||||
result = sqlite3_open(file, &mDb);
|
||||
if (result != SQLITE_OK) goto open_fail;
|
||||
|
||||
// disable synchronous
|
||||
result = sqlite3_exec(mDb, "PRAGMA synchronous = OFF;", NULL, NULL, NULL);
|
||||
if (result != SQLITE_OK) goto fail;
|
||||
|
||||
// run init
|
||||
if (!Init()) goto fail;
|
||||
|
||||
//start job
|
||||
result = sqlite3_exec(mDb, "begin;", NULL, NULL, NULL);
|
||||
if (result != SQLITE_OK) goto fail;
|
||||
|
||||
return;
|
||||
fail:
|
||||
sqlite3_close(mDb);
|
||||
open_fail:
|
||||
mDb = NULL;
|
||||
}
|
||||
|
||||
void SSMaterializerDatabase::FakeDeconstructor() {
|
||||
if (mDb == NULL) return;
|
||||
int result;
|
||||
|
||||
//commit job
|
||||
result = sqlite3_exec(mDb, "commit;", NULL, NULL, NULL);
|
||||
if (result != SQLITE_OK) goto fail;
|
||||
|
||||
// run extra stuff
|
||||
if (!Finalize()) goto fail;
|
||||
|
||||
//free all cached stmts and commit job
|
||||
for (auto it = mStmtCache.begin(); it != mStmtCache.end(); it++) {
|
||||
if (it->second != NULL) {
|
||||
result = sqlite3_finalize(it->second);
|
||||
if (result != SQLITE_OK) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
//release res
|
||||
sqlite3_close(mDb);
|
||||
mDb = NULL;
|
||||
}
|
||||
|
||||
BOOL SSMaterializerDatabase::Init() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SSMaterializerDatabase::Finalize() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region sub-database constructor, deconstructor and help functions
|
||||
|
||||
DocumentDatabase::DocumentDatabase(const char* file, CKParameterManager* paramManager) :
|
||||
SSMaterializerDatabase(), mUniqueAttr(), /*mUniqueObj(), */mDbHelper(paramManager) {
|
||||
FakeConstructor(file);
|
||||
}
|
||||
|
||||
DocumentDatabase::~DocumentDatabase() {
|
||||
FakeDeconstructor();
|
||||
}
|
||||
|
||||
EnvironmentDatabase::EnvironmentDatabase(const char* file) :
|
||||
SSMaterializerDatabase(), mDbHelper() {
|
||||
FakeConstructor(file);
|
||||
}
|
||||
|
||||
EnvironmentDatabase::~EnvironmentDatabase() {
|
||||
FakeDeconstructor();
|
||||
}
|
||||
|
||||
BOOL DocumentDatabase::is_attr_duplicated(DataStruct::EXPAND_CK_ID parents) {
|
||||
// check duplication
|
||||
if (mUniqueAttr.find(parents) != mUniqueAttr.end()) {
|
||||
//existing item. skip it to make sure unique
|
||||
return TRUE;
|
||||
} else {
|
||||
//add this item
|
||||
mUniqueAttr.insert(parents);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//BOOL DocumentDatabase::is_obj_duplicated(DataStruct::EXPAND_CK_ID parents) {
|
||||
// // check duplication
|
||||
// if (mUniqueObj.find(parents) != mUniqueObj.end()) {
|
||||
// //existing item. skip it to make sure unique
|
||||
// return TRUE;
|
||||
// } else {
|
||||
// //add this item
|
||||
// mUniqueObj.insert(parents);
|
||||
// return FALSE;
|
||||
// }
|
||||
//}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region table, index creation functions
|
||||
|
||||
#define SafeSqlExec(sql) result = sqlite3_exec(mDb, sql, NULL, NULL, NULL); \
|
||||
if (result != SQLITE_OK) { return FALSE; }
|
||||
|
||||
BOOL DocumentDatabase::Init() {
|
||||
// execute parent first
|
||||
if (!SSMaterializerDatabase::Init()) return FALSE;
|
||||
|
||||
int result;
|
||||
|
||||
//Init table
|
||||
SafeSqlExec("begin;");
|
||||
|
||||
SafeSqlExec("CREATE TABLE [script] ([thisobj] INTEGER, [name] TEXT, [index] INTEGER, [behavior] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_behavior] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [proto_name] TEXT, [proto_guid] TEXT, [flags] INTEGER, [priority] INTEGER, [version] INTEGER, [pin_count] TEXT, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pTarget] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER, [direct_source] INTEGER, [shard_source] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER, [direct_source] INTEGER, [shared_source] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_bIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_bOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_bLink] ([input] INTEGER, [output] INTEGER, [delay] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_index] INETEGR, [output_obj] INTEGER, [output_type] INTEGER, [output_index] INETEGR, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pLocal] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [is_setting] INTEGER, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pLink] ([input] INTEGER, [output] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_is_bb] INTEGER, [input_index] INETEGR, [output_obj] INTEGER, [output_type] INTEGER, [output_is_bb] INTEGER, [output_index] INETEGR, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pOper] ([thisobj] INTEGER, [op] TEXT, [op_guid] TEXT, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_eLink] ([export_obj] INTEGER, [internal_obj] INTEGER, [is_in] INTEGER, [index] INTEGER, [parent] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [script_pAttr] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT);");
|
||||
|
||||
SafeSqlExec("CREATE TABLE [msg] ([index] INTEGER, [name] TEXT);");
|
||||
SafeSqlExec("CREATE TABLE [obj] ([id] INTEGER, [name] TEXT, [classid] INTEGER, [classtype] TEXT);");
|
||||
|
||||
SafeSqlExec("CREATE TABLE [data] ([field] TEXT, [data] TEXT, [parent] INTEGER);");
|
||||
|
||||
SafeSqlExec("commit;");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DocumentDatabase::Finalize() {
|
||||
// execute parent first
|
||||
if (!SSMaterializerDatabase::Finalize()) return FALSE;
|
||||
|
||||
//create index for quick select in SuperScriptDecorator
|
||||
int result;
|
||||
|
||||
SafeSqlExec("begin;");
|
||||
SafeSqlExec("CREATE INDEX [quick_where1] ON [script_behavior] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where2] ON [script_pOper] ([parent], [thisobj])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where3] ON [script_pTarget] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where4] ON [script_bIn] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where5] ON [script_bOut] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where6] ON [script_pIn] ([parent], [thisobj])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where7] ON [script_pOut] ([parent], [thisobj])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where8] ON [script_pLocal] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where9] ON [script_pLink] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where10] ON [script_bLink] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where11] ON [script_elink] ([parent])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where12] ON [script_pAttr] ([thisobj])");
|
||||
SafeSqlExec("CREATE INDEX [quick_where13] ON [data] ([parent])");
|
||||
SafeSqlExec("commit;");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EnvironmentDatabase::Init() {
|
||||
// execute parent first
|
||||
if (!SSMaterializerDatabase::Init()) return FALSE;
|
||||
|
||||
int result;
|
||||
|
||||
//init table
|
||||
SafeSqlExec("begin;");
|
||||
|
||||
SafeSqlExec("CREATE TABLE [op] ([funcptr] INTEGER, [in1_guid] TEXT, [in2_guid] TEXT, [out_guid] TEXT, [op_guid] TEXT, [op_name] TEXT, [op_code] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [param] ([index] INTEGER, [guid] TEXT, [derived_from] TEXT, [type_name] TEXT, [default_size] INTEGER, [func_CreateDefault] INTEGER, [func_Delete] INTEGER, [func_SaveLoad] INTEGER, [func_Check] INTEGER, [func_Copy] INTEGER, [func_String] INTEGER, [func_UICreator] INTEGER, [creator_dll_index] INTEGER, [creator_plugin_index] INTEGER, [dw_param] INTEGER, [dw_flags] INTEGER, [cid] INTEGER, [saver_manager] TEXT);");
|
||||
SafeSqlExec("CREATE TABLE [attr] ([index] INTEGER, [name] TEXT, [category_index] INTEGER, [category_name] TEXT, [flags] INTEGER, [param_index] INTEGER, [compatible_classid] INTEGER, [default_value] TEXT);");
|
||||
SafeSqlExec("CREATE TABLE [plugin] ([dll_index] INTEGER, [dll_name] TEXT, [plugin_index] INTEGER, [category] TEXT, [active] INTEGER, [guid] TEXT, [desc] TEXT, [author] TEXT, [summary] TEXT, [version] INTEGER, [func_init] INTEGER, [func_exit] INTEGER);");
|
||||
SafeSqlExec("CREATE TABLE [variable] ([name] TEXT, [description] TEXT, [flags] INTEGER, [type] INTEGER, [representation] TEXT, [data] TEXT);");
|
||||
|
||||
SafeSqlExec("commit;");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EnvironmentDatabase::Finalize() {
|
||||
// execute parent first
|
||||
if (!SSMaterializerDatabase::Finalize()) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef SafeSqlExec
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region document database
|
||||
|
||||
void DocumentDatabase::write_script(DataStruct::dbdoc_script& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.host_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.index);
|
||||
sqlite3_bind_int(stmt, 4, data.behavior);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_behavior(DataStruct::dbdoc_script_behavior& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_behavior] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.type);
|
||||
sqlite3_bind_text(stmt, 4, data.proto_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, data.proto_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 6, data.flags);
|
||||
sqlite3_bind_int(stmt, 7, data.priority);
|
||||
sqlite3_bind_int(stmt, 8, data.version);
|
||||
sqlite3_bind_text(stmt, 9, data.pin_count.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 10, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
|
||||
void DocumentDatabase::write_script_pTarget(DataStruct::dbdoc_script_pTarget& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pTarget] VALUES (?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.type.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 5, data.parent);
|
||||
sqlite3_bind_int(stmt, 6, data.direct_source);
|
||||
sqlite3_bind_int(stmt, 7, data.shared_source);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pIn(DataStruct::dbdoc_script_pIn& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pIn] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_int(stmt, 2, data.index);
|
||||
sqlite3_bind_text(stmt, 3, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, data.type_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 6, data.parent);
|
||||
sqlite3_bind_int(stmt, 7, data.direct_source);
|
||||
sqlite3_bind_int(stmt, 8, data.shared_source);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pOut(DataStruct::dbdoc_script_pOut& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pOut] VALUES (?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_int(stmt, 2, data.index);
|
||||
sqlite3_bind_text(stmt, 3, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, data.type_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 6, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_bIn(DataStruct::dbdoc_script_bIn& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bIn] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_int(stmt, 2, data.index);
|
||||
sqlite3_bind_text(stmt, 3, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 4, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_bOut(DataStruct::dbdoc_script_bOut& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bOut] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_int(stmt, 2, data.index);
|
||||
sqlite3_bind_text(stmt, 3, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 4, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_bLink(DataStruct::dbdoc_script_bLink& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.input);
|
||||
sqlite3_bind_int(stmt, 2, data.output);
|
||||
sqlite3_bind_int(stmt, 3, data.delay);
|
||||
sqlite3_bind_int(stmt, 4, data.input_obj);
|
||||
sqlite3_bind_int(stmt, 5, data.input_type);
|
||||
sqlite3_bind_int(stmt, 6, data.input_index);
|
||||
sqlite3_bind_int(stmt, 7, data.output_obj);
|
||||
sqlite3_bind_int(stmt, 8, data.output_type);
|
||||
sqlite3_bind_int(stmt, 9, data.output_index);
|
||||
sqlite3_bind_int(stmt, 10, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pLocal(DataStruct::dbdoc_script_pLocal& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pLocal] VALUES (?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.type.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 5, data.is_setting);
|
||||
sqlite3_bind_int(stmt, 6, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pLink(DataStruct::dbdoc_script_pLink& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.input);
|
||||
sqlite3_bind_int(stmt, 2, data.output);
|
||||
sqlite3_bind_int(stmt, 3, data.input_obj);
|
||||
sqlite3_bind_int(stmt, 4, data.input_type);
|
||||
sqlite3_bind_int(stmt, 5, data.input_is_bb);
|
||||
sqlite3_bind_int(stmt, 6, data.input_index);
|
||||
sqlite3_bind_int(stmt, 7, data.output_obj);
|
||||
sqlite3_bind_int(stmt, 8, data.output_type);
|
||||
sqlite3_bind_int(stmt, 9, data.output_is_bb);
|
||||
sqlite3_bind_int(stmt, 10, data.output_index);
|
||||
sqlite3_bind_int(stmt, 11, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pOper(DataStruct::dbdoc_script_pOper& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pOper] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.op.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.op_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 4, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_eLink(DataStruct::dbdoc_script_eLink& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_eLink] VALUES (?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.export_obj);
|
||||
sqlite3_bind_int(stmt, 2, data.internal_obj);
|
||||
sqlite3_bind_int(stmt, 3, data.is_in);
|
||||
sqlite3_bind_int(stmt, 4, data.index);
|
||||
sqlite3_bind_int(stmt, 5, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_script_pAttr(DataStruct::dbdoc_script_pAttr& data) {
|
||||
// then check database validation
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pAttr] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.thisobj);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.type.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_msg(DataStruct::dbdoc_msg& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [msg] VALUES (?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.index);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_obj(DataStruct::dbdoc_obj& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [obj] VALUES (?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.id);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.classid);
|
||||
sqlite3_bind_text(stmt, 4, data.classtype.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void DocumentDatabase::write_data(DataStruct::dbdoc_data& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [data] VALUES (?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_text(stmt, 1, data.field.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, data.data.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.parent);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region environment database
|
||||
|
||||
void EnvironmentDatabase::write_op(DataStruct::dbenv_op& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [op] VALUES (?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, (int)data.funcPtr);
|
||||
sqlite3_bind_text(stmt, 2, data.in1_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.in2_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.out_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, data.op_guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 6, data.op_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 7, data.op_code);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void EnvironmentDatabase::write_param(DataStruct::dbenv_param& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [param] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.index);
|
||||
sqlite3_bind_text(stmt, 2, data.guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 3, data.derived_from.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 4, data.type_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 5, data.default_size);
|
||||
sqlite3_bind_int(stmt, 6, (int)data.func_CreateDefault);
|
||||
sqlite3_bind_int(stmt, 7, (int)data.func_Delete);
|
||||
sqlite3_bind_int(stmt, 8, (int)data.func_SaveLoad);
|
||||
sqlite3_bind_int(stmt, 9, (int)data.func_Check);
|
||||
sqlite3_bind_int(stmt, 10, (int)data.func_Copy);
|
||||
sqlite3_bind_int(stmt, 11, (int)data.func_String);
|
||||
sqlite3_bind_int(stmt, 12, (int)data.func_UICreator);
|
||||
sqlite3_bind_int(stmt, 13, data.creator_dll_index);
|
||||
sqlite3_bind_int(stmt, 14, data.creator_plugin_index);
|
||||
sqlite3_bind_int(stmt, 15, data.dw_param);
|
||||
sqlite3_bind_int(stmt, 16, data.dw_flags);
|
||||
sqlite3_bind_int(stmt, 17, data.cid);
|
||||
sqlite3_bind_text(stmt, 18, data.saver_manager.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void EnvironmentDatabase::write_attr(DataStruct::dbenv_attr& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [attr] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.index);
|
||||
sqlite3_bind_text(stmt, 2, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.category_index);
|
||||
sqlite3_bind_text(stmt, 4, data.category_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 5, data.flags);
|
||||
sqlite3_bind_int(stmt, 6, data.param_index);
|
||||
sqlite3_bind_int(stmt, 7, data.compatible_classid);
|
||||
sqlite3_bind_text(stmt, 8, data.default_value.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void EnvironmentDatabase::write_plugin(DataStruct::dbenv_plugin& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [plugin] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_int(stmt, 1, data.dll_index);
|
||||
sqlite3_bind_text(stmt, 2, data.dll_name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.plugin_index);
|
||||
sqlite3_bind_text(stmt, 4, data.category.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 5, data.active);
|
||||
sqlite3_bind_text(stmt, 6, data.guid.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 7, data.desc.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 8, data.author.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 9, data.summary.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 10, data.version);
|
||||
sqlite3_bind_int(stmt, 11, (int)data.func_init);
|
||||
sqlite3_bind_int(stmt, 12, (int)data.func_exit);
|
||||
sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
void EnvironmentDatabase::write_variable(DataStruct::dbenv_variable& data) {
|
||||
if (mDb == NULL) return;
|
||||
|
||||
#if !defined(VIRTOOLS_21)
|
||||
sqlite3_stmt* stmt = GetStmt("INSERT INTO [variable] VALUES (?, ?, ?, ?, ?, ?)");
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
sqlite3_bind_text(stmt, 1, data.name.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, data.desciption.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 3, data.flags);
|
||||
sqlite3_bind_int(stmt, 4, data.type);
|
||||
sqlite3_bind_text(stmt, 5, data.representation.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 6, data.data.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "stdafx.h"
|
||||
#include "virtools_compatible.hpp"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace DataStruct {
|
||||
|
||||
#pragma region data struct
|
||||
|
||||
typedef long EXPAND_CK_ID;
|
||||
enum bLinkInputOutputType {
|
||||
bLinkInputOutputType_INPUT,
|
||||
bLinkInputOutputType_OUTPUT
|
||||
};
|
||||
enum pLinkInputOutputType {
|
||||
pLinkInputOutputType_PIN,
|
||||
pLinkInputOutputType_POUT,
|
||||
pLinkInputOutputType_PLOCAL, //when using pLocal, omit [index] and [input_is_bb], [input_index] set -1
|
||||
pLinkInputOutputType_PTARGET, //when using pTarget, omit [index] and [input_is_bb], [input_index] set -1
|
||||
pLinkInputOutputType_PATTR //when using pAttr, omit [index], and [input_is_bb] will become [input_is_dataarray]
|
||||
};
|
||||
|
||||
// =================== doc mDb
|
||||
|
||||
struct dbdoc_script {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string host_name;
|
||||
int index;
|
||||
EXPAND_CK_ID behavior;
|
||||
};
|
||||
|
||||
struct dbdoc_script_behavior {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string name;
|
||||
CK_BEHAVIOR_TYPE type;
|
||||
std::string proto_name;
|
||||
std::string proto_guid;
|
||||
CK_BEHAVIOR_FLAGS flags;
|
||||
int priority;
|
||||
CKDWORD version;
|
||||
//pTarget, pIn, pOut, bIn, bOut
|
||||
std::string pin_count;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
struct dbdoc_script_bIO {
|
||||
EXPAND_CK_ID thisobj;
|
||||
int index;
|
||||
std::string name;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
typedef dbdoc_script_bIO dbdoc_script_bIn;
|
||||
typedef dbdoc_script_bIO dbdoc_script_bOut;
|
||||
|
||||
struct dbdoc_script_pTarget {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string type_guid;
|
||||
EXPAND_CK_ID parent;
|
||||
EXPAND_CK_ID direct_source;
|
||||
EXPAND_CK_ID shared_source;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pIn {
|
||||
EXPAND_CK_ID thisobj;
|
||||
int index;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string type_guid;
|
||||
EXPAND_CK_ID parent;
|
||||
EXPAND_CK_ID direct_source;
|
||||
EXPAND_CK_ID shared_source;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pOut {
|
||||
EXPAND_CK_ID thisobj;
|
||||
int index;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string type_guid;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
struct dbdoc_script_bLink {
|
||||
EXPAND_CK_ID input;
|
||||
EXPAND_CK_ID output;
|
||||
int delay;
|
||||
EXPAND_CK_ID parent;
|
||||
|
||||
//additional field
|
||||
EXPAND_CK_ID input_obj;
|
||||
bLinkInputOutputType input_type;
|
||||
int input_index;
|
||||
EXPAND_CK_ID output_obj;
|
||||
bLinkInputOutputType output_type;
|
||||
int output_index;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pLocal {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string type_guid;
|
||||
BOOL is_setting;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pAttr {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string type_guid;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pLink {
|
||||
EXPAND_CK_ID input;
|
||||
EXPAND_CK_ID output;
|
||||
EXPAND_CK_ID parent;
|
||||
|
||||
//additional field
|
||||
EXPAND_CK_ID input_obj;
|
||||
pLinkInputOutputType input_type;
|
||||
BOOL input_is_bb;
|
||||
int input_index;
|
||||
EXPAND_CK_ID output_obj;
|
||||
pLinkInputOutputType output_type;
|
||||
BOOL output_is_bb;
|
||||
int output_index;
|
||||
};
|
||||
|
||||
struct dbdoc_script_pOper {
|
||||
EXPAND_CK_ID thisobj;
|
||||
std::string op;
|
||||
std::string op_guid;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
struct dbdoc_script_eLink {
|
||||
EXPAND_CK_ID export_obj;
|
||||
EXPAND_CK_ID internal_obj;
|
||||
BOOL is_in;
|
||||
int index;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
struct dbdoc_msg {
|
||||
CKMessageType index;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct dbdoc_obj {
|
||||
EXPAND_CK_ID id;
|
||||
std::string name;
|
||||
CK_CLASSID classid;
|
||||
std::string classtype;
|
||||
};
|
||||
|
||||
struct dbdoc_data {
|
||||
std::string field;
|
||||
std::string data;
|
||||
EXPAND_CK_ID parent;
|
||||
};
|
||||
|
||||
// =================== env mDb
|
||||
|
||||
struct dbenv_op {
|
||||
CK_PARAMETEROPERATION funcPtr;
|
||||
std::string in1_guid;
|
||||
std::string in2_guid;
|
||||
std::string out_guid;
|
||||
std::string op_guid;
|
||||
std::string op_name;
|
||||
CKOperationType op_code;
|
||||
};
|
||||
|
||||
struct dbenv_param {
|
||||
CKParameterType index;
|
||||
std::string guid;
|
||||
std::string derived_from;
|
||||
std::string type_name;
|
||||
int default_size;
|
||||
CK_PARAMETERCREATEDEFAULTFUNCTION func_CreateDefault;
|
||||
CK_PARAMETERDELETEFUNCTION func_Delete;
|
||||
CK_PARAMETERSAVELOADFUNCTION func_SaveLoad;
|
||||
CK_PARAMETERCHECKFUNCTION func_Check;
|
||||
CK_PARAMETERCOPYFUNCTION func_Copy;
|
||||
CK_PARAMETERSTRINGFUNCTION func_String;
|
||||
CK_PARAMETERUICREATORFUNCTION func_UICreator;
|
||||
int creator_dll_index;
|
||||
int creator_plugin_index;
|
||||
CKDWORD dw_param;
|
||||
CKDWORD dw_flags;
|
||||
CKDWORD cid;
|
||||
std::string saver_manager;
|
||||
};
|
||||
|
||||
struct dbenv_attr {
|
||||
CKAttributeType index;
|
||||
std::string name;
|
||||
CKAttributeCategory category_index;
|
||||
std::string category_name;
|
||||
CK_ATTRIBUT_FLAGS flags;
|
||||
CKParameterType param_index;
|
||||
CK_CLASSID compatible_classid;
|
||||
std::string default_value;
|
||||
};
|
||||
|
||||
struct dbenv_plugin {
|
||||
int dll_index;
|
||||
std::string dll_name;
|
||||
int plugin_index;
|
||||
std::string category;
|
||||
CKBOOL active;
|
||||
std::string guid;
|
||||
std::string desc;
|
||||
std::string author;
|
||||
std::string summary;
|
||||
DWORD version;
|
||||
CK_INITINSTANCEFCT func_init;
|
||||
CK_EXITINSTANCEFCT func_exit;
|
||||
};
|
||||
|
||||
struct dbenv_variable {
|
||||
std::string name;
|
||||
std::string desciption;
|
||||
XWORD flags;
|
||||
UNIVERSAL_VAR_TYPE type;
|
||||
std::string representation;
|
||||
std::string data;
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
namespace Helper {
|
||||
|
||||
class DocumentHelper {
|
||||
public:
|
||||
DocumentHelper(CKParameterManager* paramManager);
|
||||
~DocumentHelper();
|
||||
|
||||
CKParameterManager* param_manager;
|
||||
|
||||
dbdoc_script script;
|
||||
dbdoc_script_behavior script_behavior;
|
||||
dbdoc_script_bIn script_bIn;
|
||||
dbdoc_script_bOut script_bOut;
|
||||
dbdoc_script_pIn script_pIn;
|
||||
dbdoc_script_pOut script_pOut;
|
||||
dbdoc_script_bLink script_bLink;
|
||||
dbdoc_script_pLocal script_pLocal;
|
||||
dbdoc_script_pAttr script_pAttr;
|
||||
dbdoc_script_pLink script_pLink;
|
||||
dbdoc_script_pOper script_pOper;
|
||||
dbdoc_script_eLink script_eLink;
|
||||
dbdoc_script_pTarget script_pTarget;
|
||||
|
||||
dbdoc_msg msg;
|
||||
dbdoc_obj obj;
|
||||
|
||||
dbdoc_data data;
|
||||
};
|
||||
|
||||
class EnvironmentHelper {
|
||||
public:
|
||||
EnvironmentHelper();
|
||||
~EnvironmentHelper();
|
||||
|
||||
dbenv_op op;
|
||||
dbenv_param param;
|
||||
dbenv_attr attr;
|
||||
dbenv_plugin plugin;
|
||||
dbenv_variable variable;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Database {
|
||||
|
||||
class SSMaterializerDatabase {
|
||||
public:
|
||||
SSMaterializerDatabase();
|
||||
virtual ~SSMaterializerDatabase();
|
||||
|
||||
protected:
|
||||
sqlite3_stmt* GetStmt(const char* stmt);
|
||||
void FakeConstructor(const char* file);
|
||||
void FakeDeconstructor();
|
||||
virtual BOOL Init();
|
||||
virtual BOOL Finalize();
|
||||
|
||||
sqlite3* mDb;
|
||||
std::unordered_map<uintptr_t, sqlite3_stmt*> mStmtCache;
|
||||
};
|
||||
|
||||
class DocumentDatabase : public SSMaterializerDatabase {
|
||||
public:
|
||||
DocumentDatabase(const char* file, CKParameterManager* paramManager);
|
||||
virtual ~DocumentDatabase();
|
||||
DataStruct::Helper::DocumentHelper mDbHelper;
|
||||
|
||||
void write_script(DataStruct::dbdoc_script& data);
|
||||
void write_script_behavior(DataStruct::dbdoc_script_behavior& data);
|
||||
void write_script_pTarget(DataStruct::dbdoc_script_pTarget& data);
|
||||
void write_script_pIn(DataStruct::dbdoc_script_pIn& data);
|
||||
void write_script_pOut(DataStruct::dbdoc_script_pOut& data);
|
||||
void write_script_bIn(DataStruct::dbdoc_script_bIn& data);
|
||||
void write_script_bOut(DataStruct::dbdoc_script_bOut& data);
|
||||
void write_script_bLink(DataStruct::dbdoc_script_bLink& data);
|
||||
void write_script_pLocal(DataStruct::dbdoc_script_pLocal& data);
|
||||
void write_script_pLink(DataStruct::dbdoc_script_pLink& data);
|
||||
void write_script_pOper(DataStruct::dbdoc_script_pOper& data);
|
||||
void write_script_eLink(DataStruct::dbdoc_script_eLink& data);
|
||||
void write_script_pAttr(DataStruct::dbdoc_script_pAttr& data);
|
||||
|
||||
void write_msg(DataStruct::dbdoc_msg& data);
|
||||
void write_obj(DataStruct::dbdoc_obj& data);
|
||||
|
||||
void write_data(DataStruct::dbdoc_data& data);
|
||||
|
||||
BOOL is_attr_duplicated(DataStruct::EXPAND_CK_ID parents);
|
||||
//BOOL is_obj_duplicated(DataStruct::EXPAND_CK_ID parents);
|
||||
|
||||
protected:
|
||||
virtual BOOL Init() override;
|
||||
virtual BOOL Finalize() override;
|
||||
|
||||
std::set<DataStruct::EXPAND_CK_ID> mUniqueAttr;
|
||||
//std::set<DataStruct::EXPAND_CK_ID> mUniqueObj;
|
||||
};
|
||||
|
||||
class EnvironmentDatabase : public SSMaterializerDatabase {
|
||||
public:
|
||||
EnvironmentDatabase(const char* file);
|
||||
virtual ~EnvironmentDatabase();
|
||||
DataStruct::Helper::EnvironmentHelper mDbHelper;
|
||||
|
||||
void write_op(DataStruct::dbenv_op& data);
|
||||
void write_param(DataStruct::dbenv_param& data);
|
||||
void write_attr(DataStruct::dbenv_attr& data);
|
||||
void write_plugin(DataStruct::dbenv_plugin& data);
|
||||
void write_variable(DataStruct::dbenv_variable& data);
|
||||
|
||||
protected:
|
||||
virtual BOOL Init() override;
|
||||
virtual BOOL Finalize() override;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,698 +0,0 @@
|
||||
#include "doc_export.hpp"
|
||||
#include "string_helper.hpp"
|
||||
|
||||
// some shitty features process
|
||||
//disable shit tip
|
||||
#pragma warning(disable:26812)
|
||||
// disable microsoft shitty macro to avoid build error
|
||||
#undef GetClassName
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace DocumentExporter {
|
||||
|
||||
#pragma region script
|
||||
|
||||
/*
|
||||
* `Generate` mean that this function will analyse something to generate some objects which are not existed in original Virtools document.
|
||||
* `Proc` meath that this function only just export something which is already existed in original Virtools document, or with slight modifications.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Generate pLink and eLink from pIn
|
||||
/// </summary>
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="analysed_pin"></param>
|
||||
/// <param name="mDb"></param>
|
||||
/// <param name="parents"></param>
|
||||
/// <param name="grandparents"></param>
|
||||
/// <param name="pin_index"></param>
|
||||
/// <param name="executedFromBB"></param>
|
||||
/// <param name="isTarget"></param>
|
||||
void Generate_pLink(CKContext* ctx, CKParameterIn* analysed_pin, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int pin_index, BOOL executedFromBB, BOOL isTarget) {
|
||||
CKParameter* directSource = NULL;
|
||||
CKObject* ds_Owner = NULL;
|
||||
CKParameterIn* sharedSource = NULL;
|
||||
CKObject* ss_Owner = NULL;
|
||||
|
||||
// first, we analyse eLink
|
||||
// check whether this is export parameter and write to database
|
||||
// if the behavior graph where this pIn locate, also include this pIn, we can simply
|
||||
// assume there is a eLink between them
|
||||
if (((CKBehavior*)ctx->GetObject(grandparents))->GetInputParameterPosition(analysed_pin) != -1) {
|
||||
mDb->mDbHelper.script_eLink.export_obj = analysed_pin->GetID();
|
||||
mDb->mDbHelper.script_eLink.internal_obj = parents;
|
||||
mDb->mDbHelper.script_eLink.is_in = TRUE;
|
||||
mDb->mDbHelper.script_eLink.index = pin_index;
|
||||
mDb->mDbHelper.script_eLink.parent = grandparents;
|
||||
|
||||
mDb->write_script_eLink(mDb->mDbHelper.script_eLink);
|
||||
// if a eLink has been detected successfully, we returned immediately
|
||||
// and do not analyse any pLink anymore.
|
||||
return;
|
||||
}
|
||||
|
||||
// start to analyse pLink
|
||||
// first, analyse direct_src
|
||||
if (directSource = analysed_pin->GetDirectSource()) {
|
||||
mDb->mDbHelper.script_pLink.input = directSource->GetID();
|
||||
// for almost pin, it is connected to a pLocal, so we use a if to test it first
|
||||
if (directSource->GetClassID() == CKCID_PARAMETERLOCAL || directSource->GetClassID() == CKCID_PARAMETERVARIABLE) {
|
||||
//pLocal
|
||||
mDb->mDbHelper.script_pLink.input_obj = directSource->GetID(); // the owner of pLocal is itself.
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PLOCAL;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE;
|
||||
mDb->mDbHelper.script_pLink.input_index = -1;
|
||||
} else {
|
||||
// according to Virtools SDK document, there are 4 possible value gotten by us:
|
||||
// bb pOut / pOper pOut / CKObject Attribute / CKDataArray
|
||||
// however, the last 2 returned values have NOT been tested perfectly.
|
||||
ds_Owner = directSource->GetOwner();
|
||||
switch (ds_Owner->GetClassID()) {
|
||||
case CKCID_BEHAVIOR:
|
||||
mDb->mDbHelper.script_pLink.input_obj = ds_Owner->GetID();
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_POUT;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = TRUE;
|
||||
mDb->mDbHelper.script_pLink.input_index = ((CKBehavior*)ds_Owner)->GetOutputParameterPosition((CKParameterOut*)directSource);
|
||||
break;
|
||||
case CKCID_PARAMETEROPERATION:
|
||||
mDb->mDbHelper.script_pLink.input_obj = ds_Owner->GetID();
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_POUT;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE;
|
||||
mDb->mDbHelper.script_pLink.input_index = 0; // pOper only have 1 pOut
|
||||
break;
|
||||
case CKCID_DATAARRAY:
|
||||
// CKDataArray, see as virtual bb pLocal shortcut
|
||||
mDb->mDbHelper.script_pLink.input_obj = directSource->GetID();
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PATTR;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE; // omit
|
||||
mDb->mDbHelper.script_pLink.input_index = -1; // omit
|
||||
Proc_pAttr(ctx, mDb, directSource);
|
||||
break;
|
||||
default:
|
||||
// CKObject, because CKDataArray also a CKObject, so we test it first.
|
||||
// see as virtual bb pLocal shortcut
|
||||
mDb->mDbHelper.script_pLink.input_obj = directSource->GetID();
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PATTR;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE; // omit
|
||||
mDb->mDbHelper.script_pLink.input_index = -1; // omit
|
||||
Proc_pAttr(ctx, mDb, directSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// direct_src reflect the real source of current analysed pIn,
|
||||
// however direct_src do not reflact export link
|
||||
// so we need to analyse shared_src now.
|
||||
//
|
||||
// if this pIn has established some export relation, its shared_src must be filled.
|
||||
// so we can detect it here. once its shared_src is not NULL
|
||||
// we should consider export link here.
|
||||
//
|
||||
// we do not need to analyse any export link here, we just need to export some info
|
||||
// to indicate this phenomeno.
|
||||
if (sharedSource = analysed_pin->GetSharedSource()) {
|
||||
//pIn from BB
|
||||
mDb->mDbHelper.script_pLink.input = sharedSource->GetID();
|
||||
ss_Owner = sharedSource->GetOwner();
|
||||
mDb->mDbHelper.script_pLink.input_obj = ss_Owner->GetID();
|
||||
|
||||
switch (ss_Owner->GetClassID()) {
|
||||
case CKCID_BEHAVIOR: // CKBehavior
|
||||
{
|
||||
if (((CKBehavior*)ss_Owner)->IsUsingTarget() && (((CKBehavior*)ss_Owner)->GetTargetParameter() == sharedSource)) {
|
||||
//pTarget
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PTARGET;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = TRUE;
|
||||
mDb->mDbHelper.script_pLink.input_index = -1; // omit
|
||||
|
||||
} else {
|
||||
//pIn
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PIN;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = TRUE;
|
||||
mDb->mDbHelper.script_pLink.input_index = ((CKBehavior*)ss_Owner)->GetInputParameterPosition(sharedSource);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CKCID_PARAMETEROPERATION: // CKParameterOperation
|
||||
{
|
||||
//pOper only have pIn.
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_PIN;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE;
|
||||
mDb->mDbHelper.script_pLink.input_index = ((CKParameterOperation*)ss_Owner)->GetInParameter1() == sharedSource ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// the unexpected value. according to SDK manual,
|
||||
// there are only 2 possible types
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if the header of pLink has been analysed successfully,
|
||||
// we can add tail info and push into database
|
||||
if (sharedSource != NULL || directSource != NULL) {
|
||||
mDb->mDbHelper.script_pLink.output = analysed_pin->GetID();
|
||||
mDb->mDbHelper.script_pLink.output_obj = parents;
|
||||
mDb->mDbHelper.script_pLink.output_type = isTarget ? DataStruct::pLinkInputOutputType_PTARGET : DataStruct::pLinkInputOutputType_PIN;
|
||||
mDb->mDbHelper.script_pLink.output_is_bb = executedFromBB;
|
||||
mDb->mDbHelper.script_pLink.output_index = pin_index;
|
||||
mDb->mDbHelper.script_pLink.parent = grandparents;
|
||||
|
||||
mDb->write_script_pLink(mDb->mDbHelper.script_pLink);
|
||||
}
|
||||
}
|
||||
|
||||
void Generate_pLink(CKContext* ctx, CKParameterOut* analysed_pout, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int pout_index, BOOL executedFromBB) {
|
||||
// check eLink first
|
||||
// check whether expoer parameter and write to database
|
||||
if (((CKBehavior*)ctx->GetObject(grandparents))->GetOutputParameterPosition(analysed_pout) != -1) {
|
||||
mDb->mDbHelper.script_eLink.export_obj = analysed_pout->GetID();
|
||||
mDb->mDbHelper.script_eLink.internal_obj = parents;
|
||||
mDb->mDbHelper.script_eLink.is_in = FALSE;
|
||||
mDb->mDbHelper.script_eLink.index = pout_index;
|
||||
mDb->mDbHelper.script_eLink.parent = grandparents;
|
||||
|
||||
mDb->write_script_eLink(mDb->mDbHelper.script_eLink);
|
||||
// if an eLink has been generated, skip following pLink generation
|
||||
return;
|
||||
}
|
||||
|
||||
// try generate pLink
|
||||
CKParameter* cache_Dest = NULL;
|
||||
CKObject* cache_DestOwner = NULL;
|
||||
for (int j = 0, jCount = analysed_pout->GetDestinationCount(); j < jCount; j++) {
|
||||
cache_Dest = analysed_pout->GetDestination(j);
|
||||
|
||||
mDb->mDbHelper.script_pLink.input = analysed_pout->GetID();
|
||||
mDb->mDbHelper.script_pLink.input_obj = parents;
|
||||
mDb->mDbHelper.script_pLink.input_type = DataStruct::pLinkInputOutputType_POUT;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = executedFromBB;
|
||||
mDb->mDbHelper.script_pLink.input_index = pout_index;
|
||||
|
||||
mDb->mDbHelper.script_pLink.output = cache_Dest->GetID();
|
||||
if (cache_Dest->GetClassID() == CKCID_PARAMETERLOCAL) {
|
||||
//pLocal
|
||||
mDb->mDbHelper.script_pLink.output_obj = cache_Dest->GetID();
|
||||
mDb->mDbHelper.script_pLink.output_type = DataStruct::pLinkInputOutputType_PLOCAL;
|
||||
mDb->mDbHelper.script_pLink.output_is_bb = FALSE; // omit
|
||||
mDb->mDbHelper.script_pLink.output_index = -1; // omit
|
||||
|
||||
} else {
|
||||
//pOut, it must belong to a graph BB (pOut can not be shared, and prototype bb or pOper do not have link-able pOut).
|
||||
cache_DestOwner = cache_Dest->GetOwner();
|
||||
switch (cache_DestOwner->GetClassID()) {
|
||||
case CKCID_BEHAVIOR:
|
||||
mDb->mDbHelper.script_pLink.output_obj = cache_DestOwner->GetID();
|
||||
mDb->mDbHelper.script_pLink.output_type = DataStruct::pLinkInputOutputType_POUT;
|
||||
mDb->mDbHelper.script_pLink.output_is_bb = TRUE;
|
||||
mDb->mDbHelper.script_pLink.output_index = ((CKBehavior*)cache_DestOwner)->GetOutputParameterPosition((CKParameterOut*)cache_Dest);
|
||||
break;
|
||||
case CKCID_DATAARRAY:
|
||||
// CKDataArray, see as virtual bb pLocal shortcut
|
||||
mDb->mDbHelper.script_pLink.output_obj = cache_Dest->GetID();
|
||||
mDb->mDbHelper.script_pLink.output_type = DataStruct::pLinkInputOutputType_PATTR;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE; // omit
|
||||
mDb->mDbHelper.script_pLink.input_index = -1; // omit
|
||||
Proc_pAttr(ctx, mDb, cache_Dest);
|
||||
break;
|
||||
default:
|
||||
// CKObject, because CKDataArray also a CKObject, so we test it first.
|
||||
// see as virtual bb pLocal shortcut
|
||||
mDb->mDbHelper.script_pLink.output_obj = cache_Dest->GetID();
|
||||
mDb->mDbHelper.script_pLink.output_type = DataStruct::pLinkInputOutputType_PATTR;
|
||||
mDb->mDbHelper.script_pLink.input_is_bb = FALSE; // omit
|
||||
mDb->mDbHelper.script_pLink.input_index = -1; // omit
|
||||
Proc_pAttr(ctx, mDb, cache_Dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mDb->mDbHelper.script_pLink.parent = grandparents;
|
||||
|
||||
mDb->write_script_pLink(mDb->mDbHelper.script_pLink);
|
||||
}
|
||||
}
|
||||
|
||||
void Proc_pTarget(CKContext* ctx, CKParameterIn* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents) {
|
||||
mDb->mDbHelper.script_pTarget.thisobj = cache->GetID();
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_pTarget.name, cache->GetName());
|
||||
Utils::CopyCKParamTypeStr(mDb->mDbHelper.script_pTarget.type, cache->GetType(), mDb->mDbHelper.param_manager);
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pTarget.type_guid, cache->GetGUID());
|
||||
mDb->mDbHelper.script_pTarget.parent = parents;
|
||||
mDb->mDbHelper.script_pTarget.direct_source = cache->GetDirectSource() ? cache->GetDirectSource()->GetID() : -1;
|
||||
mDb->mDbHelper.script_pTarget.shared_source = cache->GetSharedSource() ? cache->GetSharedSource()->GetID() : -1;
|
||||
|
||||
mDb->write_script_pTarget(mDb->mDbHelper.script_pTarget);
|
||||
|
||||
// try generate pLink and eLink
|
||||
Generate_pLink(ctx, cache, mDb, parents, grandparents, -1, TRUE, TRUE);
|
||||
}
|
||||
|
||||
void Proc_pIn(CKContext* ctx, CKParameterIn* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int index, BOOL executedFromBB) {
|
||||
mDb->mDbHelper.script_pIn.thisobj = cache->GetID();
|
||||
mDb->mDbHelper.script_pIn.index = index;
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_pIn.name, cache->GetName());
|
||||
Utils::CopyCKParamTypeStr(mDb->mDbHelper.script_pIn.type, cache->GetType(), mDb->mDbHelper.param_manager);
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pIn.type_guid, cache->GetGUID());
|
||||
mDb->mDbHelper.script_pIn.parent = parents;
|
||||
mDb->mDbHelper.script_pIn.direct_source = cache->GetDirectSource() ? cache->GetDirectSource()->GetID() : -1;
|
||||
mDb->mDbHelper.script_pIn.shared_source = cache->GetSharedSource() ? cache->GetSharedSource()->GetID() : -1;
|
||||
|
||||
mDb->write_script_pIn(mDb->mDbHelper.script_pIn);
|
||||
|
||||
// try generate pLink and eLink
|
||||
Generate_pLink(ctx, cache, mDb, parents, grandparents, index, executedFromBB, FALSE);
|
||||
|
||||
}
|
||||
|
||||
void Proc_pOut(CKContext* ctx, CKParameterOut* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int index, BOOL executedFromBB) {
|
||||
mDb->mDbHelper.script_pOut.thisobj = cache->GetID();
|
||||
mDb->mDbHelper.script_pOut.index = index;
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_pOut.name, cache->GetName());
|
||||
Utils::CopyCKParamTypeStr(mDb->mDbHelper.script_pOut.type, cache->GetType(), mDb->mDbHelper.param_manager);
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pOut.type_guid, cache->GetGUID());
|
||||
mDb->mDbHelper.script_pOut.parent = parents;
|
||||
|
||||
mDb->write_script_pOut(mDb->mDbHelper.script_pOut);
|
||||
|
||||
// try generate pLink and eLink
|
||||
Generate_pLink(ctx, cache, mDb, parents, grandparents, index, executedFromBB);
|
||||
}
|
||||
|
||||
void Proc_bIn(CKBehaviorIO* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, int index) {
|
||||
mDb->mDbHelper.script_bIn.thisobj = cache->GetID();
|
||||
mDb->mDbHelper.script_bIn.index = index;
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_bIn.name, cache->GetName());
|
||||
mDb->mDbHelper.script_bIn.parent = parents;
|
||||
|
||||
mDb->write_script_bIn(mDb->mDbHelper.script_bIn);
|
||||
}
|
||||
|
||||
void Proc_bOut(CKBehaviorIO* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, int index) {
|
||||
mDb->mDbHelper.script_bOut.thisobj = cache->GetID();
|
||||
mDb->mDbHelper.script_bOut.index = index;
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_bOut.name, cache->GetName());
|
||||
mDb->mDbHelper.script_bOut.parent = parents;
|
||||
|
||||
mDb->write_script_bOut(mDb->mDbHelper.script_bOut);
|
||||
}
|
||||
|
||||
void Proc_bLink(CKBehaviorLink* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
CKBehaviorIO* io = cache->GetInBehaviorIO();
|
||||
CKBehavior* beh = io->GetOwner();
|
||||
mDb->mDbHelper.script_bLink.input = io->GetID();
|
||||
mDb->mDbHelper.script_bLink.input_obj = beh->GetID();
|
||||
mDb->mDbHelper.script_bLink.input_type = (io->GetType() == CK_BEHAVIORIO_IN ? DataStruct::bLinkInputOutputType_INPUT : DataStruct::bLinkInputOutputType_OUTPUT);
|
||||
mDb->mDbHelper.script_bLink.input_index = (io->GetType() == CK_BEHAVIORIO_IN ? io->GetOwner()->GetInputPosition(io) : io->GetOwner()->GetOutputPosition(io));
|
||||
io = cache->GetOutBehaviorIO();
|
||||
beh = io->GetOwner();
|
||||
mDb->mDbHelper.script_bLink.output = io->GetID();
|
||||
mDb->mDbHelper.script_bLink.output_obj = beh->GetID();
|
||||
mDb->mDbHelper.script_bLink.output_type = (io->GetType() == CK_BEHAVIORIO_IN ? DataStruct::bLinkInputOutputType_INPUT : DataStruct::bLinkInputOutputType_OUTPUT);
|
||||
mDb->mDbHelper.script_bLink.output_index = (io->GetType() == CK_BEHAVIORIO_IN ? io->GetOwner()->GetInputPosition(io) : io->GetOwner()->GetOutputPosition(io));
|
||||
|
||||
mDb->mDbHelper.script_bLink.delay = cache->GetActivationDelay();
|
||||
mDb->mDbHelper.script_bLink.parent = parents;
|
||||
|
||||
mDb->write_script_bLink(mDb->mDbHelper.script_bLink);
|
||||
}
|
||||
|
||||
void Proc_pLocal(CKParameterLocal* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, BOOL is_setting) {
|
||||
mDb->mDbHelper.script_pLocal.thisobj = cache->GetID();
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_pLocal.name, cache->GetName());
|
||||
Utils::CopyCKParamTypeStr(mDb->mDbHelper.script_pLocal.type, cache->GetType(), mDb->mDbHelper.param_manager);
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pLocal.type_guid, cache->GetGUID());
|
||||
mDb->mDbHelper.script_pLocal.is_setting = is_setting;
|
||||
mDb->mDbHelper.script_pLocal.parent = parents;
|
||||
|
||||
mDb->write_script_pLocal(mDb->mDbHelper.script_pLocal);
|
||||
|
||||
//export plocal metadata
|
||||
DigParameterData(cache, mDb, cache->GetID());
|
||||
}
|
||||
|
||||
void Proc_pOper(CKContext* ctx, CKParameterOperation* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
mDb->mDbHelper.script_pOper.thisobj = cache->GetID();
|
||||
mDb->mDbHelper.script_pOper.op = mDb->mDbHelper.param_manager->OperationGuidToName(cache->GetOperationGuid());
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pOper.op_guid, cache->GetOperationGuid());
|
||||
mDb->mDbHelper.script_pOper.parent = parents;
|
||||
|
||||
mDb->write_script_pOper(mDb->mDbHelper.script_pOper);
|
||||
|
||||
//export 2 input param and 1 output param
|
||||
Proc_pIn(ctx, cache->GetInParameter1(), mDb, cache->GetID(), parents, 0, FALSE);
|
||||
Proc_pIn(ctx, cache->GetInParameter2(), mDb, cache->GetID(), parents, 1, FALSE);
|
||||
Proc_pOut(ctx, cache->GetOutParameter(), mDb, cache->GetID(), parents, 0, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* pAttr do not have any explict interface to get them
|
||||
* so they only can be find via pLink analyse.
|
||||
* 2 pLink analyse funcstions will call this function to record each pAttr
|
||||
* due to this mechanism, it might cause a duplication problem so
|
||||
* we need check possible duplication here.
|
||||
*/
|
||||
void Proc_pAttr(CKContext* ctx, Database::DocumentDatabase* mDb, CKParameter* cache) {
|
||||
// check duplication
|
||||
if (mDb->is_attr_duplicated(cache->GetID())) return;
|
||||
|
||||
// write self first to detect conflict
|
||||
mDb->mDbHelper.script_pAttr.thisobj = cache->GetID();
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_pAttr.name, cache->GetName());
|
||||
Utils::CopyCKParamTypeStr(mDb->mDbHelper.script_pAttr.type, cache->GetType(), mDb->mDbHelper.param_manager);
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_pAttr.type_guid, cache->GetGUID());
|
||||
|
||||
mDb->write_script_pAttr(mDb->mDbHelper.script_pAttr);
|
||||
|
||||
// continue write some properties to indicate the host of this attribute
|
||||
CKObject* host = cache->GetOwner();
|
||||
// write owner id
|
||||
DataDictWritter("attr.owner", (long)host->GetID(), mDb, cache->GetID());
|
||||
}
|
||||
|
||||
void Proc_Behavior(CKContext* ctx, CKBehavior* bhv, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
//write self data
|
||||
mDb->mDbHelper.script_behavior.thisobj = bhv->GetID();
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_behavior.name, bhv->GetName());
|
||||
mDb->mDbHelper.script_behavior.type = bhv->GetType();
|
||||
Utils::CopyCKString(mDb->mDbHelper.script_behavior.proto_name, bhv->GetPrototypeName());
|
||||
Utils::CopyGuid(mDb->mDbHelper.script_behavior.proto_guid, bhv->GetPrototypeGuid());
|
||||
mDb->mDbHelper.script_behavior.flags = bhv->GetFlags();
|
||||
mDb->mDbHelper.script_behavior.priority = bhv->GetPriority();
|
||||
mDb->mDbHelper.script_behavior.version = bhv->GetVersion();
|
||||
mDb->mDbHelper.script_behavior.parent = parents;
|
||||
Utils::StdstringPrintf(mDb->mDbHelper.script_behavior.pin_count, "%d,%d,%d,%d,%d",
|
||||
(bhv->IsUsingTarget() ? 1 : 0),
|
||||
bhv->GetInputParameterCount(),
|
||||
bhv->GetOutputParameterCount(),
|
||||
bhv->GetInputCount(),
|
||||
bhv->GetOutputCount());
|
||||
mDb->write_script_behavior(mDb->mDbHelper.script_behavior);
|
||||
|
||||
//write target
|
||||
if (bhv->IsUsingTarget())
|
||||
Proc_pTarget(ctx, bhv->GetTargetParameter(), mDb, bhv->GetID(), parents);
|
||||
|
||||
int count = 0, i = 0;
|
||||
//pIn
|
||||
for (i = 0, count = bhv->GetInputParameterCount(); i < count; i++)
|
||||
Proc_pIn(ctx, bhv->GetInputParameter(i), mDb, bhv->GetID(), parents, i, TRUE);
|
||||
//pOut
|
||||
for (i = 0, count = bhv->GetOutputParameterCount(); i < count; i++)
|
||||
Proc_pOut(ctx, bhv->GetOutputParameter(i), mDb, bhv->GetID(), parents, i, TRUE);
|
||||
//bIn
|
||||
for (i = 0, count = bhv->GetInputCount(); i < count; i++)
|
||||
Proc_bIn(bhv->GetInput(i), mDb, bhv->GetID(), i);
|
||||
//bOut
|
||||
for (i = 0, count = bhv->GetOutputCount(); i < count; i++)
|
||||
Proc_bOut(bhv->GetOutput(i), mDb, bhv->GetID(), i);
|
||||
//bLink
|
||||
for (i = 0, count = bhv->GetSubBehaviorLinkCount(); i < count; i++)
|
||||
Proc_bLink(bhv->GetSubBehaviorLink(i), mDb, bhv->GetID());
|
||||
//pLocal
|
||||
for (i = 0, count = bhv->GetLocalParameterCount(); i < count; i++)
|
||||
Proc_pLocal(bhv->GetLocalParameter(i), mDb, bhv->GetID(),
|
||||
bhv->IsLocalParameterSetting(i));
|
||||
//pOper
|
||||
for (i = 0, count = bhv->GetParameterOperationCount(); i < count; i++)
|
||||
Proc_pOper(ctx, bhv->GetParameterOperation(i), mDb, bhv->GetID());
|
||||
|
||||
//iterate sub bb
|
||||
for (i = 0, count = bhv->GetSubBehaviorCount(); i < count; i++)
|
||||
Proc_Behavior(ctx, bhv->GetSubBehavior(i), mDb, bhv->GetID());
|
||||
}
|
||||
|
||||
void IterateScript(CKContext* ctx, Database::DocumentDatabase* mDb) {
|
||||
// get all CKBeObject to try to get all scripts.
|
||||
// because only CKBeObject can load script.
|
||||
CKBeObject* beobj = NULL;
|
||||
CKBehavior* beh = NULL;
|
||||
XObjectPointerArray objArray = ctx->GetObjectListByType(CKCID_BEOBJECT, TRUE);
|
||||
int len = objArray.Size();
|
||||
int scriptLen = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
beobj = (CKBeObject*)objArray.GetObjectA(i);
|
||||
if ((scriptLen = beobj->GetScriptCount()) == 0) continue;
|
||||
for (int j = 0; j < scriptLen; j++) {
|
||||
//write script table
|
||||
beh = beobj->GetScript(j);
|
||||
|
||||
mDb->mDbHelper.script.thisobj = beobj->GetID();
|
||||
mDb->mDbHelper.script.host_name = beobj->GetName();
|
||||
mDb->mDbHelper.script.index = j;
|
||||
mDb->mDbHelper.script.behavior = beh->GetID();
|
||||
mDb->write_script(mDb->mDbHelper.script);
|
||||
|
||||
//iterate script
|
||||
Proc_Behavior(ctx, beh, mDb, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region message & obj
|
||||
|
||||
void IterateMessage(CKContext* ctx, Database::DocumentDatabase* mDb) {
|
||||
CKMessageManager* msgManager = ctx->GetMessageManager();
|
||||
int count = msgManager->GetMessageTypeCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
mDb->mDbHelper.msg.index = i;
|
||||
Utils::CopyCKString(mDb->mDbHelper.msg.name, msgManager->GetMessageTypeName(i));
|
||||
|
||||
mDb->write_msg(mDb->mDbHelper.msg);
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<CK_CLASSID> g_CommonClassId{
|
||||
#if defined(VIRTOOLS_50) || defined(VIRTOOLS_40) || defined(VIRTOOLS_35)
|
||||
// export video for non-21/25 virtools ver
|
||||
CKCID_VIDEO,
|
||||
#endif
|
||||
// export beobj object will export almost objects
|
||||
CKCID_OBJECTANIMATION, CKCID_ANIMATION, CKCID_BEOBJECT
|
||||
};
|
||||
void IterateObj(CKContext* ctx, Database::DocumentDatabase* mDb) {
|
||||
for (auto it = g_CommonClassId.begin(); it != g_CommonClassId.end(); ++it) {
|
||||
XObjectPointerArray objArray = ctx->GetObjectListByType(*it, TRUE);
|
||||
int len = objArray.Size();
|
||||
int scriptLen = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
CKSceneObject* scene_obj = (CKSceneObject*)objArray.GetObjectA(i);
|
||||
|
||||
mDb->mDbHelper.obj.id = scene_obj->GetID();
|
||||
Utils::CopyCKString(mDb->mDbHelper.obj.name, scene_obj->GetName());
|
||||
mDb->mDbHelper.obj.classid = scene_obj->GetClassID();
|
||||
Utils::CopyCKClassId(mDb->mDbHelper.obj.classtype, scene_obj->GetClassID(), mDb->mDbHelper.param_manager);
|
||||
mDb->write_obj(mDb->mDbHelper.obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region data process
|
||||
|
||||
void DigParameterData(CKParameter* p, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
// due to our algorithm, parameter can not be duplicated
|
||||
// so we don't need to check its duplication.
|
||||
CKGUID t = p->GetGUID();
|
||||
CKParameterType pt = p->GetType();
|
||||
|
||||
// export guid and type name corresponding with guid
|
||||
static std::string str_guid;
|
||||
static std::string str_typename;
|
||||
Utils::CopyGuid(str_guid, t);
|
||||
DataDictWritter("guid", str_guid.c_str(), mDb, parents);
|
||||
Utils::CopyCKParamTypeStr(str_typename, pt, mDb->mDbHelper.param_manager);
|
||||
DataDictWritter("typename", str_typename.c_str(), mDb, parents);
|
||||
|
||||
// value object
|
||||
if (p->GetParameterClassID() && p->GetValueObject(false)) {
|
||||
CKObject* vobj = p->GetValueObject(false);
|
||||
// write its id
|
||||
DataDictWritter("vobj", (long)vobj->GetID(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
|
||||
//nothing
|
||||
if (t == CKPGUID_NONE) return;
|
||||
|
||||
//float
|
||||
if (t == CKPGUID_FLOAT || t == CKPGUID_ANGLE || t == CKPGUID_PERCENTAGE || t == CKPGUID_TIME
|
||||
#if defined(VIRTOOLS_50) || defined(VIRTOOLS_40) || defined(VIRTOOLS_35)
|
||||
|| t == CKPGUID_FLOATSLIDER
|
||||
#endif
|
||||
) {
|
||||
DataDictWritter("float", *(float*)(p->GetReadDataPtr(false)), mDb, parents);
|
||||
return;
|
||||
}
|
||||
//int
|
||||
if (t == CKPGUID_INT || t == CKPGUID_KEY || t == CKPGUID_BOOL || t == CKPGUID_ID || t == CKPGUID_POINTER
|
||||
|| t == CKPGUID_MESSAGE || t == CKPGUID_ATTRIBUTE || t == CKPGUID_BLENDMODE || t == CKPGUID_FILTERMODE
|
||||
|| t == CKPGUID_BLENDFACTOR || t == CKPGUID_FILLMODE || t == CKPGUID_LITMODE || t == CKPGUID_SHADEMODE
|
||||
|| t == CKPGUID_ADDRESSMODE || t == CKPGUID_WRAPMODE || t == CKPGUID_3DSPRITEMODE || t == CKPGUID_FOGMODE
|
||||
|| t == CKPGUID_LIGHTTYPE || t == CKPGUID_SPRITEALIGN || t == CKPGUID_DIRECTION || t == CKPGUID_LAYERTYPE
|
||||
|| t == CKPGUID_COMPOPERATOR || t == CKPGUID_BINARYOPERATOR || t == CKPGUID_SETOPERATOR
|
||||
|| t == CKPGUID_OBSTACLEPRECISION || t == CKPGUID_OBSTACLEPRECISIONBEH) {
|
||||
DataDictWritter("int", (long)(*(int*)(p->GetReadDataPtr(false))), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_VECTOR) {
|
||||
VxVector vec;
|
||||
memcpy(&vec, p->GetReadDataPtr(false), sizeof(vec));
|
||||
static std::string str_vector;
|
||||
Utils::StdstringPrintf(str_vector, "%f, %f, %f",
|
||||
vec.x, vec.y, vec.z);
|
||||
DataDictWritter("vector", str_vector.c_str(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_2DVECTOR) {
|
||||
Vx2DVector vec;
|
||||
memcpy(&vec, p->GetReadDataPtr(false), sizeof(vec));
|
||||
static std::string str_2dvector;
|
||||
Utils::StdstringPrintf(str_2dvector, "%f, %f",
|
||||
vec.x, vec.y);
|
||||
DataDictWritter("2dvector", str_2dvector.c_str(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_MATRIX) {
|
||||
VxMatrix mat;
|
||||
memcpy(&mat, p->GetReadDataPtr(false), sizeof(mat));
|
||||
|
||||
static std::string str_matrix;
|
||||
Utils::StdstringPrintf(str_matrix, "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f",
|
||||
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
|
||||
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
|
||||
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
|
||||
mat[3][0], mat[3][1], mat[3][2], mat[3][3]
|
||||
);
|
||||
DataDictWritter("matrix", str_matrix.c_str(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_COLOR) {
|
||||
VxColor col;
|
||||
memcpy(&col, p->GetReadDataPtr(false), sizeof(col));
|
||||
static std::string str_color;
|
||||
Utils::StdstringPrintf(str_color, "%f, %f, %f, %f",
|
||||
col.r, col.g, col.b, col.a);
|
||||
DataDictWritter("color", str_color.c_str(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_2DCURVE) {
|
||||
//CK2dCurve* c;
|
||||
CK2dCurve* c = NULL;
|
||||
memcpy(&c, p->GetReadDataPtr(false), sizeof(c));
|
||||
|
||||
// we need construct a fake json body as our data
|
||||
static std::string str_2dcurve;
|
||||
static std::string str_2dcurve_entry;
|
||||
|
||||
str_2dcurve = "[";
|
||||
int cpcount = c->GetControlPointCount();
|
||||
for (int i = 0; i < cpcount; ++i) {
|
||||
if (i != 0) str_2dcurve += ','; // extra splitter
|
||||
|
||||
str_2dcurve += '{'; // object start
|
||||
CK2dCurvePoint* cp = c->GetControlPoint(i);
|
||||
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"x\": %f, \"y\": %f,", cp->GetPosition().x, cp->GetPosition().y);
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
|
||||
if (cp->IsLinear()) str_2dcurve += "\"linear\": true,";
|
||||
else str_2dcurve += "\"linear\": false,";
|
||||
|
||||
if (cp->IsTCB()) {
|
||||
str_2dcurve += "\"tcb\": true,";
|
||||
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"bias\": %f,", cp->GetBias());
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"continuity\": %f,", cp->GetContinuity());
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"tension\": %f", cp->GetTension());
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
|
||||
} else {
|
||||
str_2dcurve += "\"tcb\": false,";
|
||||
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"intangent\": {\"x\": %f, \"y\": %f},", cp->GetInTangent().x, cp->GetInTangent().y);
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
Utils::StdstringPrintf(str_2dcurve_entry, "\"outtangent\": {\"x\": %f, \"y\": %f}", cp->GetOutTangent().x, cp->GetOutTangent().y);
|
||||
str_2dcurve += str_2dcurve_entry.c_str();
|
||||
|
||||
}
|
||||
|
||||
str_2dcurve += '}';
|
||||
}
|
||||
str_2dcurve = "]";
|
||||
DataDictWritter("2dcurve", str_2dcurve.c_str(), mDb, parents);
|
||||
return;
|
||||
}
|
||||
if (t == CKPGUID_STRING) {
|
||||
char* cptr = (char*)p->GetReadDataPtr(false);
|
||||
int cc = p->GetDataSize();
|
||||
|
||||
// virtools internal data may not have null terminal, so we use raw add function here
|
||||
// resize data and copy
|
||||
mDb->mDbHelper.data.data.resize(cc);
|
||||
memcpy((void*)mDb->mDbHelper.data.data.data(), cptr, cc);
|
||||
mDb->mDbHelper.data.field = "string";
|
||||
mDb->mDbHelper.data.parent = parents;
|
||||
mDb->write_data(mDb->mDbHelper.data);
|
||||
return;
|
||||
}
|
||||
|
||||
//if it gets here, we have no idea what it really is. so simply dump it.
|
||||
//buffer-like
|
||||
if (t == CKPGUID_VOIDBUF
|
||||
#if defined(VIRTOOLS_50) || defined(VIRTOOLS_40) || defined(VIRTOOLS_35)
|
||||
|| t == CKPGUID_SHADER || t == CKPGUID_TECHNIQUE || t == CKPGUID_PASS
|
||||
#endif
|
||||
) {
|
||||
// raw data also need use raw export feature
|
||||
// we use base64 encode to encode all data
|
||||
char* cptr = (char*)p->GetReadDataPtr(false);
|
||||
int ds = p->GetDataSize();
|
||||
|
||||
// dump data
|
||||
static std::string str_raw;
|
||||
if (ds > 10240) {
|
||||
// data is too big, clamp it to 10240
|
||||
Utils::StdstringGetBase64(str_raw, cptr, 10240);
|
||||
DataDictWritter("raw.partial_data", str_raw.c_str(), mDb, parents);
|
||||
} else {
|
||||
Utils::StdstringGetBase64(str_raw, cptr, ds);
|
||||
DataDictWritter("raw.data", str_raw.c_str(), mDb, parents);
|
||||
}
|
||||
|
||||
//dump data length
|
||||
DataDictWritter("dump.length", (long)ds, mDb, parents);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DataDictWritter(const char* field, const char* data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
mDb->mDbHelper.data.field = field;
|
||||
mDb->mDbHelper.data.data = data;
|
||||
mDb->mDbHelper.data.parent = parents;
|
||||
|
||||
mDb->write_data(mDb->mDbHelper.data);
|
||||
}
|
||||
void DataDictWritter(const char* field, float data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
static std::string float_conv;
|
||||
Utils::StdstringPrintf(float_conv, "%f", data);
|
||||
DataDictWritter(field, float_conv.c_str(), mDb, parents);
|
||||
}
|
||||
void DataDictWritter(const char* field, long data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents) {
|
||||
static std::string int_conv;
|
||||
Utils::StdstringPrintf(int_conv, "%d", data);
|
||||
DataDictWritter(field, int_conv.c_str(), mDb, parents);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "database.hpp"
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace DocumentExporter {
|
||||
|
||||
void Generate_pLink(CKContext* ctx, CKParameterIn* analysed_pin, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int pin_index, BOOL executedFromBB, BOOL isTarget);
|
||||
void Generate_pLink(CKContext* ctx, CKParameterOut* analysed_pout, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int pout_index, BOOL executedFromBB);
|
||||
void Proc_pTarget(CKContext* ctx, CKParameterIn* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents);
|
||||
void Proc_pIn(CKContext* ctx, CKParameterIn* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int index, BOOL executedFromBB);
|
||||
void Proc_pOut(CKContext* ctx, CKParameterOut* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, DataStruct::EXPAND_CK_ID grandparents, int index, BOOL executedFromBB);
|
||||
void Proc_bIn(CKBehaviorIO* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, int index);
|
||||
void Proc_bOut(CKBehaviorIO* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, int index);
|
||||
void Proc_bLink(CKBehaviorLink* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void Proc_pLocal(CKParameterLocal* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents, BOOL is_setting);
|
||||
void Proc_pOper(CKContext* ctx, CKParameterOperation* cache, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void Proc_pAttr(CKContext* ctx, Database::DocumentDatabase* mDb, CKParameter* cache);
|
||||
|
||||
void Proc_Behavior(CKContext* ctx, CKBehavior* bhv, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void IterateScript(CKContext* ctx, Database::DocumentDatabase* mDb);
|
||||
|
||||
void IterateMessage(CKContext* ctx, Database::DocumentDatabase* mDb);
|
||||
void IterateObj(CKContext* ctx, Database::DocumentDatabase* mDb);
|
||||
|
||||
void DigParameterData(CKParameter* p, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void DataDictWritter(const char* field, long data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void DataDictWritter(const char* field, float data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
void DataDictWritter(const char* field, const char* data, Database::DocumentDatabase* mDb, DataStruct::EXPAND_CK_ID parents);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
#include "env_export.hpp"
|
||||
#include "string_helper.hpp"
|
||||
|
||||
//disable shit tip
|
||||
#pragma warning(disable:26812)
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace EnvironmentExporter {
|
||||
|
||||
void IterateParameterOperation(CKParameterManager* parameterManager, Database::EnvironmentDatabase* mDb) {
|
||||
int count = parameterManager->GetParameterOperationCount();
|
||||
CKOperationDesc* opList = NULL;
|
||||
CKGUID _guid;
|
||||
int listCount = 0, cacheListCount = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
//fill basic data
|
||||
mDb->mDbHelper.op.op_code = i;
|
||||
_guid = parameterManager->OperationCodeToGuid(i);
|
||||
Utils::CopyGuid(mDb->mDbHelper.op.op_guid, _guid);
|
||||
mDb->mDbHelper.op.op_name = parameterManager->OperationCodeToName(i);
|
||||
|
||||
//allocate mem
|
||||
cacheListCount = parameterManager->GetAvailableOperationsDesc(_guid, NULL, NULL, NULL, NULL);
|
||||
if (cacheListCount > listCount) {
|
||||
listCount = cacheListCount;
|
||||
opList = (CKOperationDesc*)realloc(opList, listCount * sizeof(CKOperationDesc));
|
||||
if (opList == NULL) return;
|
||||
}
|
||||
|
||||
parameterManager->GetAvailableOperationsDesc(_guid, NULL, NULL, NULL, opList);
|
||||
for (int j = 0; j < cacheListCount; j++) {
|
||||
Utils::CopyGuid(mDb->mDbHelper.op.in1_guid, opList[j].P1Guid);
|
||||
Utils::CopyGuid(mDb->mDbHelper.op.in2_guid, opList[j].P2Guid);
|
||||
Utils::CopyGuid(mDb->mDbHelper.op.out_guid, opList[j].ResGuid);
|
||||
mDb->mDbHelper.op.funcPtr = opList[j].Fct;
|
||||
|
||||
mDb->write_op(mDb->mDbHelper.op);
|
||||
}
|
||||
}
|
||||
if (opList != NULL) free(opList);
|
||||
|
||||
}
|
||||
|
||||
void IterateParameter(CKParameterManager* parameterManager, Database::EnvironmentDatabase* mDb) {
|
||||
int count = parameterManager->GetParameterTypesCount();
|
||||
CKParameterTypeDesc* desc = NULL;
|
||||
for (int i = 0; i < count; i++) {
|
||||
desc = parameterManager->GetParameterTypeDescription(i);
|
||||
|
||||
mDb->mDbHelper.param.index = desc->Index;
|
||||
Utils::CopyGuid(mDb->mDbHelper.param.guid, desc->Guid);
|
||||
Utils::CopyGuid(mDb->mDbHelper.param.derived_from, desc->DerivedFrom);
|
||||
mDb->mDbHelper.param.type_name = desc->TypeName.CStr();
|
||||
mDb->mDbHelper.param.default_size = desc->DefaultSize;
|
||||
mDb->mDbHelper.param.func_CreateDefault = desc->CreateDefaultFunction;
|
||||
mDb->mDbHelper.param.func_Delete = desc->DeleteFunction;
|
||||
mDb->mDbHelper.param.func_SaveLoad = desc->SaveLoadFunction;
|
||||
mDb->mDbHelper.param.func_Check = desc->CheckFunction;
|
||||
mDb->mDbHelper.param.func_Copy = desc->CopyFunction;
|
||||
mDb->mDbHelper.param.func_String = desc->StringFunction;
|
||||
mDb->mDbHelper.param.func_UICreator = desc->UICreatorFunction;
|
||||
CKPluginEntry* plgEntry = desc->CreatorDll;
|
||||
if (plgEntry != NULL) {
|
||||
mDb->mDbHelper.param.creator_dll_index = plgEntry->m_PluginDllIndex;
|
||||
mDb->mDbHelper.param.creator_plugin_index = plgEntry->m_PositionInDll;
|
||||
} else {
|
||||
mDb->mDbHelper.param.creator_dll_index = -1;
|
||||
mDb->mDbHelper.param.creator_plugin_index = -1;
|
||||
}
|
||||
mDb->mDbHelper.param.dw_param = desc->dwParam;
|
||||
mDb->mDbHelper.param.dw_flags = desc->dwFlags;
|
||||
mDb->mDbHelper.param.cid = desc->Cid;
|
||||
Utils::CopyGuid(mDb->mDbHelper.param.saver_manager, desc->Saver_Manager);
|
||||
|
||||
mDb->write_param(mDb->mDbHelper.param);
|
||||
}
|
||||
}
|
||||
|
||||
void IterateAttribute(CKAttributeManager* attrManager, Database::EnvironmentDatabase* mDb) {
|
||||
int count = attrManager->GetAttributeCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
mDb->mDbHelper.attr.index = i;
|
||||
mDb->mDbHelper.attr.name = attrManager->GetAttributeNameByType(i);
|
||||
mDb->mDbHelper.attr.category_index = attrManager->GetAttributeCategoryIndex(i);
|
||||
Utils::CopyCKString(mDb->mDbHelper.attr.category_name, attrManager->GetAttributeCategory(i));
|
||||
mDb->mDbHelper.attr.flags = attrManager->GetAttributeFlags(i);
|
||||
mDb->mDbHelper.attr.param_index = attrManager->GetAttributeParameterType(i);
|
||||
mDb->mDbHelper.attr.compatible_classid = attrManager->GetAttributeCompatibleClassId(i);
|
||||
Utils::CopyCKString(mDb->mDbHelper.attr.default_value, attrManager->GetAttributeDefaultValue(i));
|
||||
|
||||
mDb->write_attr(mDb->mDbHelper.attr);
|
||||
}
|
||||
}
|
||||
|
||||
void IteratePlugin(CKPluginManager* plgManager, Database::EnvironmentDatabase* mDb) {
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
int catCount = plgManager->GetPluginCount(i);
|
||||
mDb->mDbHelper.plugin.category = plgManager->GetCategoryName(i);
|
||||
for (int j = 0; j < catCount; j++) {
|
||||
CKPluginEntry* plgEntry = plgManager->GetPluginInfo(i, j);
|
||||
CKPluginInfo* plgInfo = &(plgEntry->m_PluginInfo);
|
||||
CKPluginDll* plgDll = plgManager->GetPluginDllInfo(plgEntry->m_PluginDllIndex);
|
||||
|
||||
mDb->mDbHelper.plugin.dll_index = plgEntry->m_PluginDllIndex;
|
||||
|
||||
mDb->mDbHelper.plugin.dll_name = plgDll->m_DllFileName.CStr();
|
||||
|
||||
mDb->mDbHelper.plugin.plugin_index = plgEntry->m_PositionInDll;
|
||||
mDb->mDbHelper.plugin.active = plgEntry->m_Active;
|
||||
|
||||
Utils::CopyGuid(mDb->mDbHelper.plugin.guid, plgInfo->m_GUID);
|
||||
mDb->mDbHelper.plugin.desc = plgInfo->m_Description.CStr();
|
||||
mDb->mDbHelper.plugin.author = plgInfo->m_Author.CStr();
|
||||
mDb->mDbHelper.plugin.summary = plgInfo->m_Summary.CStr();
|
||||
mDb->mDbHelper.plugin.version = plgInfo->m_Version;
|
||||
mDb->mDbHelper.plugin.func_init = plgInfo->m_InitInstanceFct;
|
||||
mDb->mDbHelper.plugin.func_exit = plgInfo->m_ExitInstanceFct;
|
||||
|
||||
mDb->write_plugin(mDb->mDbHelper.plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(VIRTOOLS_21)
|
||||
void IterateVariable(CKVariableManager* varManager, Database::EnvironmentDatabase* mDb) {
|
||||
CKVariableManager::Iterator it = varManager->GetVariableIterator();
|
||||
CKVariableManager::Variable* varobj = NULL;
|
||||
XString dataCopyCache;
|
||||
for (; !it.End(); it++) {
|
||||
varobj = it.GetVariable();
|
||||
mDb->mDbHelper.variable.name = it.GetName();
|
||||
Utils::CopyCKString(mDb->mDbHelper.variable.desciption, varobj->GetDescription());
|
||||
mDb->mDbHelper.variable.flags = varobj->GetFlags();
|
||||
mDb->mDbHelper.variable.type = varobj->GetType();
|
||||
Utils::CopyCKString(mDb->mDbHelper.variable.representation, varobj->GetRepresentation());
|
||||
varobj->GetStringValue(dataCopyCache);
|
||||
mDb->mDbHelper.variable.data = dataCopyCache.CStr();
|
||||
|
||||
mDb->write_variable(mDb->mDbHelper.variable);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "database.hpp"
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace EnvironmentExporter {
|
||||
|
||||
void IterateParameterOperation(CKParameterManager* parameterManager, Database::EnvironmentDatabase* mDb);
|
||||
void IterateParameter(CKParameterManager* parameterManager, Database::EnvironmentDatabase* mDb);
|
||||
void IterateAttribute(CKAttributeManager* attrManager, Database::EnvironmentDatabase* mDb);
|
||||
void IteratePlugin(CKPluginManager* plgManager, Database::EnvironmentDatabase* mDb);
|
||||
|
||||
#if !defined(VIRTOOLS_21)
|
||||
void IterateVariable(CKVariableManager* varManager, Database::EnvironmentDatabase* mDb);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "vt_menu.hpp"
|
||||
#include "vt_player.hpp"
|
||||
|
||||
#if defined(VIRTOOLS_PLUGIN)
|
||||
PluginInterface* s_Plugininterface = NULL;
|
||||
PluginInfo g_PluginInfo0;
|
||||
|
||||
int GetVirtoolsPluginInfoCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
PluginInfo* GetVirtoolsPluginInfo(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return &g_PluginInfo0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class SuperScriptMaterializer : CWinApp {
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
virtual int ExitInstance();
|
||||
};
|
||||
|
||||
SuperScriptMaterializer theApp;
|
||||
|
||||
BOOL SuperScriptMaterializer::InitInstance() {
|
||||
CWinApp::InitInstance();
|
||||
|
||||
strcpy(g_PluginInfo0.m_Name, "SSMaterializer");
|
||||
g_PluginInfo0.m_PluginType = PluginInfo::PT_EDITOR;
|
||||
g_PluginInfo0.m_PluginType = (PluginInfo::PLUGIN_TYPE)(g_PluginInfo0.m_PluginType | PluginInfo::PTF_RECEIVENOTIFICATION);
|
||||
g_PluginInfo0.m_PluginCallback = PluginCallback;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int SuperScriptMaterializer::ExitInstance() {
|
||||
return CWinApp::ExitInstance();
|
||||
}
|
||||
|
||||
#elif defined(VIRTOOLS_STANDALONE)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 4) {
|
||||
printf("Arguments too less!\n");
|
||||
printf("Format: SuperScriptMaterializer.exe [virtools composition] [script db path] [env db path]\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
PlayerMain(argv[1], argv[2], argv[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#define _WIN32_WINNT 0x0A00
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#include <afxext.h> // MFC extensions
|
||||
|
||||
#ifndef _AFX_NO_OLE_SUPPORT
|
||||
#include <afxole.h> // MFC OLE classes
|
||||
#include <afxodlgs.h> // MFC OLE dialog classes
|
||||
#include <afxdisp.h> // MFC Automation classes
|
||||
#endif // _AFX_NO_OLE_SUPPORT
|
||||
|
||||
|
||||
#ifndef _AFX_NO_DB_SUPPORT
|
||||
#include <afxdb.h> // MFC ODBC SSMaterializerDatabase classes
|
||||
#endif // _AFX_NO_DB_SUPPORT
|
||||
|
||||
#ifndef _AFX_NO_DAO_SUPPORT
|
||||
#include <afxdao.h> // MFC DAO SSMaterializerDatabase classes
|
||||
#endif // _AFX_NO_DAO_SUPPORT
|
||||
|
||||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
//PLUGIN PRECOMPILED HEADER INCLUDED
|
||||
#include "CKAll.h"
|
||||
|
||||
#if defined(VIRTOOLS_PLUGIN)
|
||||
|
||||
#include "VIControls.h"
|
||||
#include "CKControlsAll.h"
|
||||
#include "VEP_ScriptActionMenu.h"
|
||||
#include "VEP_KeyboardShortcutManager.h"
|
||||
#include "VEP_All.h"
|
||||
|
||||
using namespace CKControl;
|
||||
|
||||
#elif defined(VIRTOOLS_STANDALONE)
|
||||
|
||||
#endif
|
||||
@@ -1,58 +0,0 @@
|
||||
#include "string_helper.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace Utils {
|
||||
|
||||
void StdstringPrintf(std::string& strl, const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
StdstringVPrintf(strl, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
void StdstringVPrintf(std::string& strl, const char* format, va_list argptr) {
|
||||
int count = _vsnprintf(NULL, 0, format, argptr);
|
||||
count++;
|
||||
|
||||
strl.resize(count);
|
||||
strl[count - 1] = '\0';
|
||||
int write_result = _vsnprintf((char*)strl.data(), count, format, argptr);
|
||||
|
||||
if (write_result < 0 || write_result >= count) {
|
||||
//something goes wrong
|
||||
strl.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Reference: https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||
void StdstringGetBase64(std::string& strl, const char* data, size_t datalen) {
|
||||
static const char* base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const int mod_table[] = { 0, 2, 1 };
|
||||
|
||||
// compute size
|
||||
size_t output_length = 4 * ((datalen + 2) / 3);
|
||||
strl.resize(output_length);
|
||||
|
||||
// compute
|
||||
for (size_t i = 0, j = 0; i < datalen;) {
|
||||
|
||||
uint32_t octet_a = i < datalen ? (unsigned char)data[i++] : 0;
|
||||
uint32_t octet_b = i < datalen ? (unsigned char)data[i++] : 0;
|
||||
uint32_t octet_c = i < datalen ? (unsigned char)data[i++] : 0;
|
||||
|
||||
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||
|
||||
strl[j++] = base64_table[(triple >> 3 * 6) & 0x3F];
|
||||
strl[j++] = base64_table[(triple >> 2 * 6) & 0x3F];
|
||||
strl[j++] = base64_table[(triple >> 1 * 6) & 0x3F];
|
||||
strl[j++] = base64_table[(triple >> 0 * 6) & 0x3F];
|
||||
}
|
||||
|
||||
// fill blank
|
||||
for (int i = 0; i < mod_table[datalen % 3]; i++)
|
||||
strl[output_length - 1 - i] = '=';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <string>
|
||||
|
||||
namespace SSMaterializer {
|
||||
namespace Utils {
|
||||
|
||||
constexpr const char g_Unknow[] = "!!UNKNOW!!";
|
||||
|
||||
void StdstringPrintf(std::string& strl, const char* format, ...);
|
||||
void StdstringVPrintf(std::string& strl, const char* format, va_list argptr);
|
||||
void StdstringGetBase64(std::string& strl, const char* data, size_t datalen);
|
||||
|
||||
inline void CopyGuid(std::string& str, CKGUID& guid) {
|
||||
StdstringPrintf(str, "0x%08X, 0x%08X", guid.d1, guid.d2);
|
||||
}
|
||||
inline void CopyCKString(std::string& storage, const char* str) {
|
||||
storage = str == NULL ? g_Unknow : str;
|
||||
}
|
||||
inline void CopyCKParamTypeStr(std::string& strl, CKParameterType ckpt, CKParameterManager* pm) {
|
||||
if (ckpt != -1) strl = pm->ParameterTypeToName(ckpt);
|
||||
else strl = g_Unknow;
|
||||
}
|
||||
inline void CopyCKClassId(std::string& strl, CK_CLASSID clsid, CKParameterManager* pm) {
|
||||
CKSTRING ckstr = pm->ParameterGuidToName(pm->ClassIDToGuid(clsid));
|
||||
strl = ckstr == NULL ? g_Unknow : ckstr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "virtools_compatible.hpp"
|
||||
|
||||
#if defined(VIRTOOLS_50) && defined(VIRTOOLS_STANDALONE)
|
||||
|
||||
//#define stdin (__acrt_iob_func(0))
|
||||
//#define stdout (__acrt_iob_func(1))
|
||||
//#define stderr (__acrt_iob_func(2))
|
||||
//
|
||||
//FILE _iob[] = { *stdin, *stdout, *stderr };
|
||||
//extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
|
||||
|
||||
#endif
|
||||
|
||||
//void __declspec(noreturn) FAKE_THROW() {
|
||||
// throw "Unimplemented function called.";
|
||||
//}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
//void __declspec(noreturn) FAKE_THROW();
|
||||
|
||||
#if defined(VIRTOOLS_21)
|
||||
#define UNIVERSAL_VAR_TYPE void*
|
||||
#elif defined(VIRTOOLS_25) || defined(VIRTOOLS_35) || defined(VIRTOOLS_40) || defined(VIRTOOLS_50)
|
||||
#define UNIVERSAL_VAR_TYPE CKVariableManager::Variable::Type
|
||||
#endif
|
||||
@@ -1,165 +0,0 @@
|
||||
#include "vt_menu.hpp"
|
||||
#include "database.hpp"
|
||||
#include "doc_export.hpp"
|
||||
#include "env_export.hpp"
|
||||
|
||||
#if defined(VIRTOOLS_PLUGIN)
|
||||
|
||||
extern PluginInterface* s_Plugininterface;
|
||||
CMenu* s_MainMenu = NULL;
|
||||
|
||||
void PluginCallback(PluginInfo::CALLBACK_REASON reason, PluginInterface* plugininterface) {
|
||||
switch (reason) {
|
||||
case PluginInfo::CR_LOAD:
|
||||
{
|
||||
s_Plugininterface = plugininterface;
|
||||
InitMenu();
|
||||
UpdateMenu();
|
||||
}break;
|
||||
case PluginInfo::CR_UNLOAD:
|
||||
{
|
||||
RemoveMenu();
|
||||
s_Plugininterface = NULL;
|
||||
}break;
|
||||
case PluginInfo::CR_NEWCOMPOSITIONNAME:
|
||||
{
|
||||
}break;
|
||||
case PluginInfo::CR_NOTIFICATION:
|
||||
{
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitMenu() {
|
||||
if (!s_Plugininterface)
|
||||
return;
|
||||
|
||||
s_MainMenu = s_Plugininterface->AddPluginMenu("SSMaterializer", 20, NULL, (VoidFunc1Param)PluginMenuCallback);
|
||||
}
|
||||
|
||||
void RemoveMenu() {
|
||||
if (!s_Plugininterface || !s_MainMenu)
|
||||
return;
|
||||
|
||||
s_Plugininterface->RemovePluginMenu(s_MainMenu);
|
||||
}
|
||||
|
||||
void UpdateMenu() {
|
||||
s_Plugininterface->ClearPluginMenu(s_MainMenu); //clear menu
|
||||
|
||||
s_Plugininterface->AddPluginMenuItem(s_MainMenu, 0, "Export Document");
|
||||
s_Plugininterface->AddPluginMenuItem(s_MainMenu, 1, "Export Environment");
|
||||
|
||||
s_Plugininterface->AddPluginMenuItem(s_MainMenu, -1, NULL, TRUE);
|
||||
s_Plugininterface->AddPluginMenuItem(s_MainMenu, 2, "Report Bug");
|
||||
s_Plugininterface->AddPluginMenuItem(s_MainMenu, 3, "Plugin Homepage");
|
||||
|
||||
s_Plugininterface->UpdatePluginMenu(s_MainMenu); //update menu,always needed when you finished to update the menu
|
||||
//unless you want the menu not to have Virtools Dev main menu color scheme.
|
||||
}
|
||||
|
||||
void PluginMenuCallback(int commandID) {
|
||||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||||
CKContext* ctx = s_Plugininterface->GetCKContext();
|
||||
|
||||
//switch mode
|
||||
#if defined(_RELEASE)
|
||||
try {
|
||||
#endif
|
||||
switch (commandID) {
|
||||
case 0:
|
||||
{
|
||||
//Init file
|
||||
std::string file;
|
||||
OpenFileDialog(&file);
|
||||
if (file.empty())
|
||||
break;
|
||||
DeleteFile(file.c_str());
|
||||
|
||||
//Init resources
|
||||
SSMaterializer::Database::DocumentDatabase* db =
|
||||
new SSMaterializer::Database::DocumentDatabase(file.c_str(), ctx->GetParameterManager());
|
||||
|
||||
//iterate item
|
||||
SSMaterializer::DocumentExporter::IterateScript(ctx, db);
|
||||
SSMaterializer::DocumentExporter::IterateMessage(ctx, db);
|
||||
SSMaterializer::DocumentExporter::IterateObj(ctx, db);
|
||||
|
||||
//Close all resources
|
||||
delete db;
|
||||
|
||||
ctx->OutputToConsole("[SSMaterializer] Done");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
//Init file
|
||||
std::string file;
|
||||
OpenFileDialog(&file);
|
||||
if (file.empty())
|
||||
break;
|
||||
DeleteFile(file.c_str());
|
||||
|
||||
//Init
|
||||
SSMaterializer::Database::EnvironmentDatabase* db =
|
||||
new SSMaterializer::Database::EnvironmentDatabase(file.c_str());
|
||||
|
||||
//iterate parameter operation/param
|
||||
SSMaterializer::EnvironmentExporter::IterateParameterOperation(ctx->GetParameterManager(), db);
|
||||
SSMaterializer::EnvironmentExporter::IterateParameter(ctx->GetParameterManager(), db);
|
||||
SSMaterializer::EnvironmentExporter::IterateAttribute(ctx->GetAttributeManager(), db);
|
||||
SSMaterializer::EnvironmentExporter::IteratePlugin(CKGetPluginManager(), db);
|
||||
#if !defined(VIRTOOLS_21)
|
||||
SSMaterializer::EnvironmentExporter::IterateVariable(ctx->GetVariableManager(), db);
|
||||
#endif
|
||||
|
||||
//release all
|
||||
delete db;
|
||||
|
||||
ctx->OutputToConsole("[SSMaterializer] Done");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ShellExecute(NULL, "open", "https://github.com/yyc12345/SuperScriptMaterializer/issues", NULL, NULL, SW_SHOWNORMAL);
|
||||
break;
|
||||
case 3:
|
||||
ShellExecute(NULL, "open", "https://github.com/yyc12345/SuperScriptMaterializer", NULL, NULL, SW_SHOWNORMAL);
|
||||
break;
|
||||
}
|
||||
#if defined(_RELEASE)
|
||||
} catch (const std::exception & e) {
|
||||
std::string errstr;
|
||||
errstr = "An error occurs, application will exit. Please report to developer with this window and reproduce step.\nError message: ";
|
||||
errstr += e.what();
|
||||
AfxMessageBox(errstr.c_str(), MB_OK | MB_ICONSTOP);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BOOL OpenFileDialog(std::string* returned_file) {
|
||||
returned_file->clear();
|
||||
|
||||
char* file = (char*)malloc(1024 * sizeof(char));
|
||||
BOOL status;
|
||||
OPENFILENAME OpenFileStruct;
|
||||
ZeroMemory(&OpenFileStruct, sizeof(OPENFILENAME));
|
||||
OpenFileStruct.lStructSize = sizeof(OPENFILENAME);
|
||||
OpenFileStruct.lpstrFile = file;
|
||||
OpenFileStruct.lpstrFile[0] = '\0';
|
||||
OpenFileStruct.nMaxFile = 1024;
|
||||
OpenFileStruct.lpstrFilter = "Database file(*.db)\0*.db\0";
|
||||
OpenFileStruct.lpstrDefExt = "db";
|
||||
OpenFileStruct.lpstrFileTitle = NULL;
|
||||
OpenFileStruct.nMaxFileTitle = 0;
|
||||
OpenFileStruct.lpstrInitialDir = NULL;
|
||||
OpenFileStruct.Flags = OFN_EXPLORER;
|
||||
if (status = GetSaveFileName(&OpenFileStruct))
|
||||
*returned_file = file;
|
||||
|
||||
free(file);
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(VIRTOOLS_PLUGIN)
|
||||
#include "stdafx.h"
|
||||
#include "database.hpp"
|
||||
|
||||
void PluginCallback(PluginInfo::CALLBACK_REASON reason, PluginInterface* plugininterface);
|
||||
|
||||
void InitMenu();
|
||||
void RemoveMenu();
|
||||
void UpdateMenu();
|
||||
void PluginMenuCallback(int commandID);
|
||||
|
||||
BOOL OpenFileDialog(std::string* returned_file);
|
||||
#endif
|
||||
@@ -1,107 +0,0 @@
|
||||
#include "vt_player.hpp"
|
||||
#include "doc_export.hpp"
|
||||
#include "env_export.hpp"
|
||||
|
||||
#if defined(VIRTOOLS_STANDALONE)
|
||||
|
||||
void PlayerMain(const char* virtools_composition, const char* script_db_path, const char* env_db_path) {
|
||||
printf("Super Script Materializer\n");
|
||||
printf("Homepage: https://github.com/yyc12345/SuperScriptMaterializer\n");
|
||||
printf("Report bug: https://github.com/yyc12345/SuperScriptMaterializer/issues\n");
|
||||
|
||||
// ====================== Init ck2 engine
|
||||
#if defined(VIRTOOLS_21)
|
||||
CommonAssert(LoadLibrary("CK2.dll") != NULL, "Error loading CK2.dll");
|
||||
#endif
|
||||
|
||||
CommonAssert(!CKStartUp(), "CKStartUp Error");
|
||||
CKPluginManager* pluginManager = CKGetPluginManager();
|
||||
CommonAssert(pluginManager != NULL, "PluginManager = null");
|
||||
CommonAssert(pluginManager->ParsePlugins("RenderEngines") > 0, "Error loading RenderEngines");
|
||||
CommonAssert(pluginManager->ParsePlugins("Managers") > 0, "Error loading Managers");
|
||||
CommonAssert(pluginManager->ParsePlugins("BuildingBlocks") > 0, "Error loading BuildingBlocks");
|
||||
CommonAssert(pluginManager->ParsePlugins("Plugins") > 0, "Error loading Plugins");
|
||||
|
||||
// ====================== create context and load file
|
||||
CKContext* context = NULL;
|
||||
CommonAssert(!CKCreateContext(&context, NULL), "CKCreateContext Error");
|
||||
|
||||
CKObjectArray* array = CreateCKObjectArray();
|
||||
CommonAssert(!context->Load((char*)virtools_composition, array), "CKContext->Load() Error");
|
||||
|
||||
#if defined(_RELEASE)
|
||||
try {
|
||||
#endif
|
||||
printf("Parsing %s...\n", virtools_composition);
|
||||
|
||||
// ====================== do SSMaterializerDatabase export
|
||||
// define and Init
|
||||
scriptDatabase* _script_db = new scriptDatabase();
|
||||
dbScriptDataStructHelper* _script_helper = new dbScriptDataStructHelper();
|
||||
envDatabase* _env_db = new envDatabase();
|
||||
dbEnvDataStructHelper* _env_helper = new dbEnvDataStructHelper();
|
||||
|
||||
DeleteFile(script_db_path);
|
||||
DeleteFile(env_db_path);
|
||||
_script_db->open(script_db_path);
|
||||
_script_helper->init(context->GetParameterManager());
|
||||
_env_db->open(env_db_path);
|
||||
_env_helper->init();
|
||||
|
||||
// export
|
||||
IterateScript(context, _script_db, _script_helper);
|
||||
|
||||
IterateParameterOperation(context->GetParameterManager(), _env_db, _env_helper);
|
||||
IterateParameter(context->GetParameterManager(), _env_db, _env_helper);
|
||||
IterateMessage(context->GetMessageManager(), _env_db, _env_helper);
|
||||
IterateAttribute(context->GetAttributeManager(), _env_db, _env_helper);
|
||||
IteratePlugin(CKGetPluginManager(), _env_db, _env_helper);
|
||||
#if !defined(VIRTOOLS_21)
|
||||
IterateVariable(context->GetVariableManager(), _env_db, _env_helper);
|
||||
#endif
|
||||
|
||||
// free
|
||||
_script_helper->dispose();
|
||||
_script_db->close();
|
||||
_env_helper->dispose();
|
||||
_env_db->close();
|
||||
delete _script_helper;
|
||||
delete _script_db;
|
||||
delete _env_helper;
|
||||
delete _env_db;
|
||||
|
||||
printf("Done!");
|
||||
|
||||
#if defined(_RELEASE)
|
||||
} catch (const std::exception & e) {
|
||||
std::string errstr;
|
||||
errstr = "An error occurs, application will exit. Please report to developer with this window and reproduce step.\nError message: ";
|
||||
errstr += e.what();
|
||||
printf("[ERROR] %s", errstr.c_str());
|
||||
ExitProcess(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// ====================== free resources and shutdown engine
|
||||
DeleteCKObjectArray(array);
|
||||
context->Reset();
|
||||
context->ClearAll();
|
||||
|
||||
// todo: Virtools 4.0 standalone version throw exception in there, but i don't knwo why
|
||||
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
||||
CKCloseContext(context);
|
||||
|
||||
CKShutdown();
|
||||
|
||||
// todo: Virtools 2.5 standalone version throw exception in there, but i don't knwo why
|
||||
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
||||
}
|
||||
|
||||
void CommonAssert(BOOL condition, const char* desc) {
|
||||
if (!condition) {
|
||||
printf("[ERROR] %s\n", desc);
|
||||
ExitProcess(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(VIRTOOLS_STANDALONE)
|
||||
#include "stdafx.h"
|
||||
#include "database.hpp"
|
||||
|
||||
void PlayerMain(const char* virtools_composition, const char* script_db_path, const char* env_db_path);
|
||||
void CommonAssert(BOOL condition, const char* desc);
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
import locale
|
||||
|
||||
class DatabaseType:
|
||||
SQLite = 0
|
||||
MySQL = 1
|
||||
|
||||
database_type = DatabaseType.SQLite
|
||||
sqlite_path = "decorated.db"
|
||||
|
||||
'''
|
||||
database_type = DatabaseType.MySQL
|
||||
mysql_url = "http://yyc.bkt.moe:10000"
|
||||
mysql_username = "test"
|
||||
mysql_password = "test"
|
||||
mysql_database = "test_database"
|
||||
'''
|
||||
|
||||
debug_mode = False
|
||||
@@ -1,11 +0,0 @@
|
||||
import CustomConfig
|
||||
|
||||
class EmptyDatabase:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def CreateDatabase():
|
||||
return EmptyDatabase()
|
||||
|
||||
def CloseDatabase(db):
|
||||
pass
|
||||
@@ -1,101 +0,0 @@
|
||||
import CustomConfig
|
||||
import Database
|
||||
|
||||
from flask import Flask
|
||||
from flask import g
|
||||
from flask import render_template
|
||||
from flask import url_for
|
||||
from flask import request
|
||||
from flask import abort
|
||||
from flask import redirect
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# =============================================database
|
||||
def get_db():
|
||||
db = getattr(g, '_database', None)
|
||||
if db is None:
|
||||
db = g._database = Database.CreateDatabase()
|
||||
return db
|
||||
|
||||
@app.teardown_appcontext
|
||||
def close_connection(exception):
|
||||
db = getattr(g, '_database', None)
|
||||
if db is not None:
|
||||
Database.CloseDatabase(db)
|
||||
|
||||
# =============================================route
|
||||
|
||||
# =========== default
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def handle_nospec():
|
||||
return redirect(url_for('handle_index'))
|
||||
|
||||
# =========== basic pages
|
||||
|
||||
@app.route('/index', methods=['GET'])
|
||||
def handle_index():
|
||||
return app.send_static_file("html/index.html")
|
||||
|
||||
@app.route('/script', methods=['GET'])
|
||||
def handle_script():
|
||||
return redirect(url_for('handle_index'))
|
||||
|
||||
@app.route('/array', methods=['GET'])
|
||||
def handle_array():
|
||||
return redirect(url_for('handle_index'))
|
||||
|
||||
@app.route('/environment', methods=['GET'])
|
||||
def handle_environment():
|
||||
return redirect(url_for('handle_index'))
|
||||
|
||||
@app.route('/help', methods=['GET'])
|
||||
def handle_help():
|
||||
return app.send_static_file("html/help.html")
|
||||
|
||||
@app.route('/about', methods=['GET'])
|
||||
def handle_about():
|
||||
return app.send_static_file("html/about.html")
|
||||
|
||||
# =========== viewer
|
||||
# script and array should have at least 2 items splitted by slash(/)
|
||||
# the first one is document id and the second one is the real CK_ID of viewing object.
|
||||
# however, environment do not have this, environment only allow one item, the id of environment.
|
||||
|
||||
@app.route('/script/<path:script_path>', methods=['GET'])
|
||||
def handle_script_viewer(script_path):
|
||||
# check invalid url
|
||||
if len(script_path.split('/')) < 2:
|
||||
return redirect(url_for('handle_index'))
|
||||
return app.send_static_file("html/viewer_script.html")
|
||||
|
||||
@app.route('/array/<path:array_path>', methods=['GET'])
|
||||
def handle_array_viewer(array_path):
|
||||
# check invalid url
|
||||
if len(script_path.split('/')) < 2:
|
||||
return redirect(url_for('handle_index'))
|
||||
return app.send_static_file("html/viewer_array.html")
|
||||
|
||||
@app.route('/environment/<path:environment_path>', methods=['GET'])
|
||||
def handle_environment_viewer(environment_path):
|
||||
# check invalid url
|
||||
if len(script_path.split('/')) > 1:
|
||||
return redirect(url_for('handle_index'))
|
||||
return app.send_static_file("html/viewer_environment.html")
|
||||
|
||||
# =========== viewer
|
||||
|
||||
@app.route('/api/index/getList', methods=['POST'])
|
||||
def handle_api_index_getList(scriptPath):
|
||||
return {
|
||||
"document": [],
|
||||
"script": [],
|
||||
"array": [],
|
||||
"environment": []
|
||||
}
|
||||
|
||||
# =========== startup
|
||||
def run():
|
||||
app.run()
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import ServerCore
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
import logging
|
||||
|
||||
# todo: load db and cfg
|
||||
|
||||
# todo: start flask
|
||||
ServerCore.run()
|
||||
@@ -1,17 +0,0 @@
|
||||
table.envOutput {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
table.envOutput tr:nth-child(odd) {
|
||||
background:#cfcfcf;
|
||||
}
|
||||
|
||||
table.envOutput tr:nth-child(2n) {
|
||||
background:white;
|
||||
}
|
||||
|
||||
table.envOutput tr:nth-child(1) td {
|
||||
background: blue;
|
||||
color: white;
|
||||
border: 1px solid black;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
body {
|
||||
background: silver;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
div.simple-menu {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
div.simple-menu > p {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/*side panel style*/
|
||||
div.tabitem-activated {
|
||||
background: #0000ff;
|
||||
}
|
||||
div.tabitem-activated b {
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.tabitem-deactivated {
|
||||
background: #ffffff00;
|
||||
}
|
||||
div.tabitem-deactivated b {
|
||||
color: black;
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*navigation style*/
|
||||
p.hamburger {
|
||||
margin: 0 5px 0 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*graph style*/
|
||||
div.block-target {
|
||||
position: absolute;
|
||||
background: green;
|
||||
}
|
||||
|
||||
div.block-b {
|
||||
position: absolute;
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
div.block-p {
|
||||
position: absolute;
|
||||
background: blue;
|
||||
}
|
||||
|
||||
p.block-text {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
p.block-expandable-text {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
color: #5f5f5f;
|
||||
}
|
||||
|
||||
p.block-asstext {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 9px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.block-body {
|
||||
position: absolute;
|
||||
background: #8f8f8f;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
div.cell-ptarget {
|
||||
position: absolute;
|
||||
background: green;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
div.cell-plocal {
|
||||
position: absolute;
|
||||
background: #8f8f8f;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
div.cell-shortcut {
|
||||
position: absolute;
|
||||
background: purple;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
div.cell-pio {
|
||||
position: absolute;
|
||||
background: blue;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
div.cell-bio {
|
||||
position: absolute;
|
||||
background: yellow;
|
||||
border: 1px solid #cfcfcf;
|
||||
}
|
||||
|
||||
text.link-delay {
|
||||
font-size: 12px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* property list*/
|
||||
|
||||
pre.propertyItem {
|
||||
border: 1px solid black;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
background: #3f3f3f;
|
||||
color: white;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
code.propertyItem {
|
||||
border: 1px solid black;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
background: gray;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.propertyItem {
|
||||
margin: 5px;
|
||||
border: 1px solid gray;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>About - SuperScriptMaterializer</title>
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/imgs/icon.jpg" />
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="/static/js/global.js"/></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xp.css@0.3.0/dist/98.css">
|
||||
<link rel="stylesheet" href="/static/css/global.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="/static/imgs/icon.jpg" width="64" height="64" style="margin: 0 10px 0 10px;"/>Super Script Materializer</h1>
|
||||
<p>There are no secret script behind Virtools. Super Script Materializer will destroy all locks and show you the real code.<br />
|
||||
But Super Script Materializer only show you code. It couldn't analyse the result and touch author's heart and intention. This is your work.<br />
|
||||
So, let we crack all scripts and destroy close-source illusion.</p>
|
||||
|
||||
<p><a href="https://github.com/yyc12345/SuperScriptMaterializer">SuperScriptMaterializer</a>. All codes are under GPLv3.<br />
|
||||
Web frontend is powered by <a href="https://gulpjs.com/">gulp</a>, <a href="https://jquery.com/">jQuery</a>, <a href="https://www.jsviews.com/">JsRender/JsViews</a> and <a href="https://botoxparty.github.io/XP.css/">98.css</a>.<br />
|
||||
Web backend is powered by <a href="https://github.com/pallets/flask">Flask</a>.<br />
|
||||
Ancestor projects: <a href="https://github.com/BearKidsTeam/VirtoolsScriptDeobfuscation">BearKidsTeam/VirtoolsScriptDeobfuscation</a> and <a href="https://github.com/BearKidsTeam/Script-Materializer">BearKidsTeam/Script-Materializer</a>.<br />
|
||||
Thank <a href="https://github.com/chirs241097">chirs241097</a> and <a href="https://github.com/instr3">2jjy</a>.<br />
|
||||
Icon is created by <a href="https://github.com/ShadowPower">ShadowPower</a> via diffusion.</p>
|
||||
|
||||
<p>Super Script Materializer version: 2.0</p>
|
||||
|
||||
<div class="simple-menu">
|
||||
<p><a href="/index">Hierarchy</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/help">Help</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/about">About</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,173 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Help - SuperScriptMaterializer</title>
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/imgs/icon.jpg" />
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="/static/js/global.js"/></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xp.css@0.3.0/dist/98.css">
|
||||
<link rel="stylesheet" href="/static/css/global.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Help Center</h1>
|
||||
<div class="simple-menu">
|
||||
<p><a href="/index">Hierarchy</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/help">Help</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/about">About</a></p>
|
||||
</div>
|
||||
<p>This page is help center, providing useful link for some detailed help page. Choose what you want to use and enter corresponding tabs.</p>
|
||||
|
||||
<section class="tabs">
|
||||
<menu role="tablist" aria-label="help-tab">
|
||||
<button role="tab" aria-selected="true" aria-controls="tab-legend">Legend</button>
|
||||
<button role="tab" aria-controls="tab-misc1">Misc Help</button>
|
||||
<button role="tab" aria-controls="tab-misc2">Misc Help2</button>
|
||||
</menu>
|
||||
<!-- the tab content -->
|
||||
<article role="tabpanel" id="tab-legend">
|
||||
|
||||
<h2>Layout</h2>
|
||||
<p>In viewer page, it can be divided into 3 panels:</p>
|
||||
<table border="1">
|
||||
<tr style="height: 50px;">
|
||||
<td style="width: 200px;">Navigation panel</td>
|
||||
<td style="width: 100px;" rowspan="2">Information & tools panel</td>
|
||||
</tr>
|
||||
<tr style="height: 50px;">
|
||||
<td>Graph panel</td>
|
||||
</tr>
|
||||
</table>
|
||||
<ul>
|
||||
<li><b>Navigation panel</b>: Display current script's hierarchy. And you can click all layers which located in this panel to jump into it.</li>
|
||||
<li><b>Information & tools panel</b>: Provide property data, display configuration and some useful tools.</li>
|
||||
<li><b>Graph panel</b>: Core panel. Display current browsing behavior graph's data. Some legend will be desscribe in the follwing sector.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Graph legend</h2>
|
||||
<h3>Block</h3>
|
||||
<div style="background: #7f7f7f; padding: 20px;">
|
||||
<div style="display: flex; flex-flow: row; align-items: center; margin-top: 10px; margin-bottom: 10px;">
|
||||
<div style="height: 5px; width: 15px;background: #8f8f8f;border: 1px solid #cfcfcf;"></div>
|
||||
<div style="margin-left: 10px;">pLocal (including arrtibute) (ParameterLocal abbr.)</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-flow: row; align-items: center; margin-top: 10px; margin-bottom: 10px;">
|
||||
<div style="height: 5px; width: 15px;background: purple;border: 1px solid #cfcfcf;"></div>
|
||||
<div style="margin-left: 10px;">Shortcut (Only shortcut output)</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-flow: row; align-items: center; margin-top: 10px; margin-bottom: 10px;">
|
||||
<div style="height: 6px; width: 6px;background: yellow;border: 1px solid #cfcfcf;"></div>
|
||||
<div style="margin-left: 10px;">bIn / bOut (BehaviorIn / BehaviorOut abbr.)</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-flow: row; align-items: center; margin-top: 10px; margin-bottom: 10px;">
|
||||
<div style="height: 6px; width: 6px;background: blue;border: 1px solid #cfcfcf;"></div>
|
||||
<div style="margin-left: 10px;">pIn / pOut (ParameterIn / ParameterOut abbr.)</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-flow: row; align-items: center; margin-top: 10px; margin-bottom: 10px;">
|
||||
<div style="height: 6px; width: 6px;background: green;border: 1px solid #cfcfcf;"></div>
|
||||
<div style="margin-left: 10px;">pTarget (ParameterTarget abbr.)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h3>Building block</h3>
|
||||
|
||||
<p>Building block (abbr. BB)</p>
|
||||
<p>All building block can be devided into 2 types: prototype building block and behavior graph</p>
|
||||
|
||||
<div style="background: #7f7f7f; padding: 20px; width: 500px;">
|
||||
<div style="height: 72.0px; width: 104.0px;background: #8f8f8f;border: 1px solid #cfcfcf;position: relative; top: 0; left: 0;">
|
||||
|
||||
<div class="block-target" style="height: 6px; width: 6px; top: 0; left: 0;position: absolute;background: green;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 20px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 46px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; bottom: 0; left: 20px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 10px; left: 0;position: absolute;background: yellow;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 10px; right: 0;position: absolute;background: yellow;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 36px; right: 0;position: absolute;background: yellow;"></div>
|
||||
|
||||
<p style="top: 10px; left: 20px;position: absolute;margin: 0;padding: 0;font-size: 12px;color: black;">Get Cell</p>
|
||||
<p style="top: 24px; left: 20px;position: absolute; margin: 0;padding: 0;font-size: 9px;color: white;">Get Cell</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>This is a typical prototype building block. Some port are attached into this building block.<br />
|
||||
pIn and pTarget are at the top, pOut are at the bottom, bIn are on the left, and bOut are on the right.<br />
|
||||
In the middle of building block, the name of this building block is written in black font, and the name of this building block's prototype is written in white font.</p>
|
||||
|
||||
<div style="background: #7f7f7f; padding: 20px; width: 500px;">
|
||||
<div class="block-body" style="height: 72.0px; width: 196.0px;background: #8f8f8f;border: 1px solid #cfcfcf;position: relative; top: 0; left: 0;">
|
||||
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 20px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 46px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 72px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 98px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 124px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 0; left: 150px;position: absolute;background: blue;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 10px; left: 0;position: absolute;background: yellow;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 10px; right: 0;position: absolute;background: yellow;"></div>
|
||||
<div style="height: 6px; width: 6px; top: 36px; right: 0;position: absolute;background: yellow;"></div>
|
||||
|
||||
<p style="top: 10px; left: 20px;position: absolute;margin: 0;padding: 0;font-size: 12px;color: black;"><a href="/help/legend">vt2obj</a></p>
|
||||
<p style="top: 24px; left: 20px;position: absolute; margin: 0;padding: 0;font-size: 9px;color: white;"></p>
|
||||
</div>
|
||||
</div>
|
||||
<p>This is a typical behavior graph. It is very similar to prototype building block.<br />
|
||||
It don't have the name of prototype. Instead, you can click on the name to see what is inside this graph(jump into this graph).</p>
|
||||
|
||||
<h3>Link</h3>
|
||||
|
||||
<svg version="1.1" width="500px" height="350px" style="position: relative; top: 0; left: 0;background: #7f7f7f; padding: 20px;">
|
||||
<line x1="0" y1="20" x2="100" y2="20" stroke="black" stroke-width="1px"></line>
|
||||
<text x="50" y="20" fill="black" style="font-size: 12px; color: black;">0</text>
|
||||
<text x="120" y="20" fill="black">bLink (BehaviorLink)</text>
|
||||
<line x1="0" y1="70" x2="100" y2="70" stroke="blue" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
<text x="120" y="70" fill="black">pLink (ParameterLink)</text>
|
||||
<line x1="0" y1="120" x2="100" y2="120" stroke="cyan" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
<text x="120" y="120" fill="black">eLink (ExportParameterLink)</text>
|
||||
|
||||
<line x1="0" y1="170" x2="100" y2="170" stroke="yellow" stroke-width="1px"></line>
|
||||
<text x="50" y="170" fill="yellow" style="font-size: 12px;">0</text>
|
||||
<text x="120" y="170" fill="black">Highlight bLink</text>
|
||||
<line x1="0" y1="220" x2="100" y2="220" stroke="orange" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
<text x="120" y="220" fill="black">Highlight pLink</text>
|
||||
<line x1="0" y1="270" x2="100" y2="270" stroke="orangered" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
<text x="120" y="270" fill="black">Highlight eLink</text>
|
||||
</svg>
|
||||
|
||||
<h3>Operation</h3>
|
||||
<ul>
|
||||
<li>You can highlight the associated links by clicking Block or BB, and click again to cancel the highlight.</li>
|
||||
<li>You can double-click Block or prototoye BB to get the properties associated with it.</li>
|
||||
<li>You can hover over the Block to view its name and type through tooltip.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Properties</h2>
|
||||
<p>Properties can be visited in Information & tools panel. It can display the information of the object currently being double-clicked.</p>
|
||||
|
||||
<div style="margin: 5px;border: 1px solid gray;border-radius: 2px;padding: 5px; width: 400px;">
|
||||
<p><code style="border: 1px solid black; border-radius: 2px;padding: 5px;margin: 5px;background: gray;color: white;">S</code><b>Rectangle/Box Mode</b><i>(176)</i></p>
|
||||
<p>dump.data</p>
|
||||
<pre style="border: 1px solid black;border-radius: 2px;padding: 5px;background: #3f3f3f;color: white;white-space: pre-wrap;word-wrap: break-word;">0x01, 0x00, 0x00, 0x00</pre>
|
||||
<p>dump.length</p>
|
||||
<pre style="border: 1px solid black;border-radius: 2px;padding: 5px;background: #3f3f3f;color: white;white-space: pre-wrap;word-wrap: break-word;">4</pre>
|
||||
</div>
|
||||
<p>This is a typical property unit. You may see more than 1 property unit in property list. A property unit may contain more than 1 key-value pair to describe it.<br />
|
||||
In the first line, the name of the current property unit (actually a pLocal) will be displayed. The number in brackets is CK_ID. If an S is displayed in front of it (as shown in the figure above), then it is also a setting.</p>
|
||||
|
||||
</article>
|
||||
<article role="tabpanel" hidden id="tab-misc1">
|
||||
<p>No Content</p>
|
||||
</article>
|
||||
<article role="tabpanel" hidden id="tab-misc2">
|
||||
<p>No Content</p>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hierarchy - SuperScriptMaterializer</title>
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/imgs/icon.jpg" />
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="/static/js/global.js"/></script>
|
||||
<script type="text/javascript" src="/static/js/index.js"/></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xp.css@0.3.0/dist/98.css">
|
||||
<link rel="stylesheet" href="/static/css/global.css">
|
||||
<link rel="stylesheet" href="/static/css/index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Hierarchy</h1>
|
||||
<p>Choose a script to read it.</p>
|
||||
|
||||
|
||||
<p>Generated by SuperScriptMaterializer</p>
|
||||
<div class="simple-menu">
|
||||
<p><a href="/index">Hierarchy</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/help">Help</a></p>
|
||||
<p>|</p>
|
||||
<p><a href="/about">About</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 184 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M18 2H12V9L9.5 7.5L7 9V2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V4C20 2.89 19.1 2 18 2M17.68 18.41C17.57 18.5 16.47 19.25 16.05 19.5C15.63 19.79 14 20.72 14.26 18.92C14.89 15.28 16.11 13.12 14.65 14.06C14.27 14.29 14.05 14.43 13.91 14.5C13.78 14.61 13.79 14.6 13.68 14.41S13.53 14.23 13.67 14.13C13.67 14.13 15.9 12.34 16.72 12.28C17.5 12.21 17.31 13.17 17.24 13.61C16.78 15.46 15.94 18.15 16.07 18.54C16.18 18.93 17 18.31 17.44 18C17.44 18 17.5 17.93 17.61 18.05C17.72 18.22 17.83 18.3 17.68 18.41M16.97 11.06C16.4 11.06 15.94 10.6 15.94 10.03C15.94 9.46 16.4 9 16.97 9C17.54 9 18 9.46 18 10.03C18 10.6 17.54 11.06 16.97 11.06Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 752 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M17.8,20C17.4,21.2 16.3,22 15,22H5C3.3,22 2,20.7 2,19V18H5L14.2,18C14.6,19.2 15.7,20 17,20H17.8M19,2H8C6.3,2 5,3.3 5,5V16H16V17C16,17.6 16.4,18 17,18H18V5C18,4.4 18.4,4 19,4C19.6,4 20,4.4 20,5V6H22V5C22,3.3 20.7,2 19,2Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 318 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000000" d="M5,4H19A2,2 0 0,1 21,6V18A2,2 0 0,1 19,20H5A2,2 0 0,1 3,18V6A2,2 0 0,1 5,4M5,8V12H11V8H5M13,8V12H19V8H13M5,14V18H11V14H5M13,14V18H19V14H13Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 238 B |
@@ -1,220 +0,0 @@
|
||||
// ============================= conv 1
|
||||
|
||||
function doConv1_I2O() {
|
||||
var textSp = $("#conv1Input").val().split("\n");
|
||||
var result = new Array();
|
||||
|
||||
for (var index = 0; index < textSp.length; index++) {
|
||||
var lines = textSp[index];
|
||||
var successful = true;
|
||||
var resultCache = new Array();
|
||||
|
||||
lineSp = lines.split(',');
|
||||
var innerIndex = lineSp.length - 1;
|
||||
for (var forwardIndex = 0; forwardIndex < lineSp.length; forwardIndex++) {
|
||||
var words = lineSp[forwardIndex];
|
||||
words = words.trim().toLowerCase();
|
||||
if (!checkByteUnit(words)) {
|
||||
resultCache.length = 0;
|
||||
successful = false;
|
||||
break;
|
||||
} else
|
||||
resultCache[innerIndex] = words;
|
||||
innerIndex--;
|
||||
}
|
||||
|
||||
if (successful)
|
||||
result[index] = resultCache.join(", ");
|
||||
else
|
||||
result[index] = "";
|
||||
|
||||
}
|
||||
|
||||
$("#conv1Output").val(result.join("\n"));
|
||||
}
|
||||
|
||||
// ============================= conv 2
|
||||
|
||||
function doConv2_I2O() {
|
||||
var textSp = $("#conv2Input").val().split("\n");
|
||||
var result = new Array();
|
||||
|
||||
for (var index = 0; index < textSp.length; index++) {
|
||||
var lines = textSp[index];
|
||||
var successful = true;
|
||||
var resultCache = "";
|
||||
|
||||
lineSp = lines.split(',');
|
||||
var innerIndex = lineSp.length - 1;
|
||||
for (var forwardIndex = 0; forwardIndex < lineSp.length; forwardIndex++) {
|
||||
var words = lineSp[forwardIndex];
|
||||
words = words.trim().toLowerCase();
|
||||
if (!checkByteUnit(words)) {
|
||||
resultCache.length = 0;
|
||||
successful = false;
|
||||
break;
|
||||
} else
|
||||
resultCache = words.substr(2, 2) + resultCache;
|
||||
innerIndex--;
|
||||
}
|
||||
|
||||
if (successful)
|
||||
result[index] = resultCache;
|
||||
else
|
||||
result[index] = "";
|
||||
|
||||
}
|
||||
|
||||
$("#conv2Output").val(result.join("\n"));
|
||||
}
|
||||
|
||||
function doConv2_O2I() {
|
||||
var textSp = $("#conv2Output").val().split("\n");
|
||||
var result = new Array();
|
||||
|
||||
for (var index = 0; index < textSp.length; index++) {
|
||||
var lines = textSp[index].toLowerCase();
|
||||
var resultCache = new Array();
|
||||
|
||||
if (!checkHexInput(lines)) {
|
||||
result[index] = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
var sectorCount = parseInt(lines.length / 2);
|
||||
var remainCount = lines.length % 2;
|
||||
|
||||
for (var innerIndex = 0; innerIndex < sectorCount; innerIndex++) {
|
||||
if (innerIndex == 0)
|
||||
resultCache[innerIndex] = "0x" + lines.slice(-(innerIndex + 1) * 2);
|
||||
else
|
||||
resultCache[innerIndex] = "0x" + lines.slice(-(innerIndex + 1) * 2, -innerIndex * 2);
|
||||
}
|
||||
if (remainCount != 0)
|
||||
resultCache[sectorCount] = "0x0" + lines[0];
|
||||
|
||||
for (var addedIndex = resultCache.length; addedIndex < 4; addedIndex++) {
|
||||
resultCache[addedIndex] = "0x00";
|
||||
}
|
||||
|
||||
result[index] = resultCache.join(", ");
|
||||
}
|
||||
|
||||
$("#conv2Input").val(result.join("\n"));
|
||||
}
|
||||
|
||||
// ============================= conv 3
|
||||
|
||||
function doConv3_I2O() {
|
||||
var textSp = $("#conv3Input").val().split("\n");
|
||||
var result = new Array();
|
||||
|
||||
for (var index = 0; index < textSp.length; index++) {
|
||||
var lines = textSp[index];
|
||||
var successful = true;
|
||||
var resultCache = "";
|
||||
|
||||
lineSp = lines.split(',');
|
||||
var innerIndex = lineSp.length - 1;
|
||||
for (var forwardIndex = 0; forwardIndex < lineSp.length; forwardIndex++) {
|
||||
var words = lineSp[forwardIndex];
|
||||
words = words.trim().toLowerCase();
|
||||
if (!checkByteUnit(words)) {
|
||||
resultCache.length = 0;
|
||||
successful = false;
|
||||
break;
|
||||
} else
|
||||
resultCache = words.substr(2, 2) + resultCache;
|
||||
innerIndex--;
|
||||
}
|
||||
|
||||
if (successful) {
|
||||
var bigInt = BigInt("0x" + resultCache);
|
||||
result[index] = bigInt.toString(10);
|
||||
}
|
||||
else
|
||||
result[index] = "";
|
||||
|
||||
}
|
||||
|
||||
$("#conv3Output").val(result.join("\n"));
|
||||
}
|
||||
|
||||
function doConv3_O2I() {
|
||||
var textSp = $("#conv3Output").val().split("\n");
|
||||
var result = new Array();
|
||||
|
||||
for (var index = 0; index < textSp.length; index++) {
|
||||
var declines = textSp[index];
|
||||
var resultCache = new Array();
|
||||
|
||||
if (!checkDecInput(declines)) {
|
||||
result[index] = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
var bigInt = BigInt(declines);
|
||||
var lines = bigInt.toString(16).toLowerCase();
|
||||
|
||||
var sectorCount = parseInt(lines.length / 2);
|
||||
var remainCount = lines.length % 2;
|
||||
|
||||
for (var innerIndex = 0; innerIndex < sectorCount; innerIndex++) {
|
||||
if (innerIndex == 0)
|
||||
resultCache[innerIndex] = "0x" + lines.slice(-(innerIndex + 1) * 2);
|
||||
else
|
||||
resultCache[innerIndex] = "0x" + lines.slice(-(innerIndex + 1) * 2, -innerIndex * 2);
|
||||
}
|
||||
if (remainCount != 0)
|
||||
resultCache[sectorCount] = "0x0" + lines[0];
|
||||
|
||||
for (var addedIndex = resultCache.length; addedIndex < 4; addedIndex++) {
|
||||
resultCache[addedIndex] = "0x00";
|
||||
}
|
||||
|
||||
result[index] = resultCache.join(", ");
|
||||
}
|
||||
|
||||
$("#conv3Input").val(result.join("\n"));
|
||||
}
|
||||
|
||||
// ============================= conv 4
|
||||
|
||||
function doConv4_I2O() {
|
||||
$("#conv4Output").val($("#conv4Input").val().toUpperCase());
|
||||
}
|
||||
|
||||
function doConv4_O2I() {
|
||||
$("#conv4Input").val($("#conv4Output").val().toLowerCase());
|
||||
}
|
||||
|
||||
// ============================= utils
|
||||
|
||||
function checkDecInput(s) {
|
||||
var legalWords = "0123456789";
|
||||
if (s.length == 0) return false;
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (legalWords.indexOf(s[i]) == -1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkHexInput(s) {
|
||||
var legalWords = "0123456789abcdef";
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (legalWords.indexOf(s[i]) == -1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkByteUnit(s) {
|
||||
var legalWords = "0123456789abcdefABCDEF";
|
||||
if (s.length != 4) return false;
|
||||
if (s[0] != '0') return false;
|
||||
if (s[1] != 'x') return false;
|
||||
if (legalWords.indexOf(s[2]) == -1) return false;
|
||||
if (legalWords.indexOf(s[3]) == -1) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
function doQuery(fieldIndex, queryTag) {
|
||||
// collect data
|
||||
var readyData = {};
|
||||
$("#queryTable_" + fieldIndex + " tr:not(:first-child)").each(function() {
|
||||
var isEnabled = $(this).find(":nth-child(1) input").prop("checked");
|
||||
if (!isEnabled) return;
|
||||
|
||||
var fieldName = $(this).find(":nth-child(2)").attr("queryName");
|
||||
var fieldValue = $(this).find(":nth-child(3) input").val();
|
||||
|
||||
readyData[fieldName] = fieldValue;
|
||||
});
|
||||
|
||||
var jsonData = JSON.stringify(readyData);
|
||||
|
||||
// raise post
|
||||
$.post(window.location,
|
||||
{
|
||||
tag: queryTag,
|
||||
data: jsonData
|
||||
},
|
||||
function (data, status) {
|
||||
// remove data
|
||||
$("#resultTable_" + fieldIndex + " tr:not(:first-child)").remove();
|
||||
|
||||
// check
|
||||
if (!data['status']) {
|
||||
alert("Fail to query!");
|
||||
return;
|
||||
}
|
||||
|
||||
// check overflow
|
||||
if (data['overflow']) $("#resultTableOverflow_" + fieldIndex).show();
|
||||
else $("#resultTableOverflow_" + fieldIndex).hide();
|
||||
|
||||
// insert data
|
||||
for(var i = 0; i < data['data'].length; i++) {
|
||||
$("#resultTable_" + fieldIndex).append("<tr></tr>");
|
||||
for(var j = 0; j < data['data'][i].length; j++) {
|
||||
$("#resultTable_" + fieldIndex + " tr:last").append("<td></td>");
|
||||
$("#resultTable_" + fieldIndex + " tr:last td:last").text(data['data'][i][j]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
// tab switcher
|
||||
$(document).ready(function() {
|
||||
// References
|
||||
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role
|
||||
$('[role="tab"]').click(function() {
|
||||
$('[aria-selected="true"]').attr('aria-selected', false);
|
||||
$(this).attr('aria-selected', true);
|
||||
$('[role="tabpanel"]').attr('hidden', true);
|
||||
$(`#${$(this).attr('aria-controls')}`).removeAttr('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
function tabControlSwitcher(tabcontrolIndex, neededIndex) {
|
||||
//disable all
|
||||
$(".tabnavigation_" + tabcontrolIndex).each(function () {
|
||||
$(this).removeClass("tabitem-activated").addClass("tabitem-deactivated");
|
||||
});
|
||||
$(".tabpanel_" + tabcontrolIndex).each(function () {
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
// set current
|
||||
$("#tabnavigation_" + tabcontrolIndex + "_" + neededIndex).removeClass("tabitem-deactivated").addClass("tabitem-activated");
|
||||
$("#tabpanel_" + tabcontrolIndex + "_" + neededIndex).show();
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
//=======================================settings
|
||||
currentSettings = {
|
||||
"plink": true,
|
||||
"properties": true,
|
||||
"highlight": true,
|
||||
"move": true
|
||||
};
|
||||
$(document).ready(function () {
|
||||
//read settings and apply it
|
||||
for (var key in currentSettings) {
|
||||
currentSettings[key] = localstorageAssist_Get("ssm-settings-" + key, "true") == "true";
|
||||
if (currentSettings[key]) $("#sidepanel-display-" + key).prop("checked", true);
|
||||
else $("#sidepanel-display-" + key).removeProp("checked");
|
||||
}
|
||||
//additional settings
|
||||
if (!currentSettings["plink"]) {
|
||||
$(".link-elink").hide();
|
||||
$(".link-plink").hide();
|
||||
}
|
||||
|
||||
// read sidepanel display property
|
||||
var sidepanelDisplay = localstorageAssist_Get("ssm-settings-sidepanelDisplay", "true") == "true";
|
||||
if (sidepanelDisplay){
|
||||
$("#sidepanelContainer").show();
|
||||
$("#sidepanelToggle").text(">>>");
|
||||
} else {
|
||||
$("#sidepanelContainer").hide();
|
||||
$("#sidepanelToggle").text("<<<");
|
||||
}
|
||||
|
||||
});
|
||||
function settingChange(target) {
|
||||
newValue = $("#sidepanel-display-" + target).prop("checked");
|
||||
currentSettings[target] = newValue;
|
||||
localstorageAssist_Set("ssm-settings-" + target, newValue);
|
||||
|
||||
if (target == "plink") {
|
||||
if (currentSettings["plink"]) {
|
||||
$(".link-elink").show();
|
||||
$(".link-plink").show();
|
||||
} else {
|
||||
$(".link-elink").hide();
|
||||
$(".link-plink").hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
function sidepanelDisplayChange() {
|
||||
$("#sidepanelContainer").toggle();
|
||||
if ($("#sidepanelContainer").is(":hidden")) {
|
||||
$("#sidepanelToggle").text("<<<");
|
||||
localstorageAssist_Set("ssm-settings-sidepanelDisplay", false)
|
||||
} else {
|
||||
$("#sidepanelToggle").text(">>>");
|
||||
localstorageAssist_Set("ssm-settings-sidepanelDisplay", true)
|
||||
}
|
||||
}
|
||||
function localstorageAssist_Get(index, defaultValue) {
|
||||
var cache = localStorage.getItem(index);
|
||||
if (cache == null) {
|
||||
localstorageAssist_Set(index, defaultValue);
|
||||
return defaultValue;
|
||||
} else return cache;
|
||||
}
|
||||
function localstorageAssist_Set(index, value) {
|
||||
localStorage.setItem(index, value);
|
||||
}
|
||||
|
||||
|
||||
//=======================================internal event
|
||||
previousHighlight = "";
|
||||
function highlightLink(target) {
|
||||
realTarget = ".target" + target;
|
||||
|
||||
if (previousHighlight != "") {
|
||||
//need restore
|
||||
$(previousHighlight).each(function () {
|
||||
if ($(this).hasClass("link-blink")) {
|
||||
$(this).attr("stroke", "black");
|
||||
}
|
||||
if ($(this).hasClass("link-blinkDelay")) {
|
||||
$(this).attr("fill", "black");
|
||||
}
|
||||
if ($(this).hasClass("link-plink")) {
|
||||
$(this).attr("stroke", "blue");
|
||||
}
|
||||
if ($(this).hasClass("link-elink")) {
|
||||
$(this).attr("stroke", "cyan");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// double one-click, only cancel highlight and don't apply any hightlight
|
||||
// or user disable hightlight
|
||||
if ((realTarget == previousHighlight) || !currentSettings["highlight"]) {
|
||||
previousHighlight = "";
|
||||
} else {
|
||||
//apply new highlight
|
||||
$(realTarget).each(function () {
|
||||
if ($(this).hasClass("link-blink")) {
|
||||
$(this).attr("stroke", "yellow");
|
||||
}
|
||||
if ($(this).hasClass("link-blinkDelay")) {
|
||||
$(this).attr("fill", "yellow");
|
||||
}
|
||||
if ($(this).hasClass("link-plink")) {
|
||||
$(this).attr("stroke", "orange");
|
||||
}
|
||||
if ($(this).hasClass("link-elink")) {
|
||||
$(this).attr("stroke", "orangered");
|
||||
}
|
||||
});
|
||||
|
||||
previousHighlight = realTarget;
|
||||
}
|
||||
|
||||
//cancel event seperate
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
// type = 0: call from cell
|
||||
// type = 1: call from bb
|
||||
function queryInfo(type, obj) {
|
||||
// confirm user enable this function
|
||||
if (!currentSettings["properties"])
|
||||
return;
|
||||
|
||||
$.post(window.location,
|
||||
{
|
||||
operation: "info",
|
||||
tag: type,
|
||||
target: obj
|
||||
},
|
||||
function (data, status) {
|
||||
//set target
|
||||
$("#sidepanel-properties-target b").text(obj);
|
||||
|
||||
//set data
|
||||
$("#sidepanel-properties-container").empty();
|
||||
for (var key in data) {
|
||||
$("#sidepanel-properties-container").append("<div class=\"propertyItem\"></div>");
|
||||
|
||||
var box = $("#sidepanel-properties-container div:last");
|
||||
if (data[key]["is_setting"])
|
||||
$(box).append("<p><code class=\"propertyItem\">S</code><b></b><i></i></p>");
|
||||
else
|
||||
$(box).append("<p><b></b><i></i></p>");
|
||||
|
||||
$(box).find("p b").text(data[key]["name"]);
|
||||
$(box).find("p i").text("(" + key + ")");
|
||||
|
||||
for (var i = 0; i < data[key]['data'].length; i++) {
|
||||
$(box).append("<p></p><pre class=\"propertyItem\"></pre>");
|
||||
$(box).find("p:last").text(data[key]['data'][i][0]);
|
||||
$(box).find("pre:last").text(data[key]['data'][i][1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>About Super Script Materializer</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="{{ static_icon }}" width="64" height="64" style="margin: 0 10px 0 10px;"/>Super Script Materializer</h1>
|
||||
<p>There are no secret script behind Virtools. Super Script Materializer will destroy all locks and show you the real code.<br />
|
||||
But Super Script Materializer only show you code. It couldn't analyse the result and touch author's heart and intention. This is your work.<br />
|
||||
So, let we crack all scripts and destroy close-source illusion.</p>
|
||||
<br />
|
||||
<p><a href="https://github.com/yyc12345/SuperScriptMaterializer">SuperScriptMaterializer</a>. All codes are under GPLv3.<br />
|
||||
Web interface is powered by <a href="https://github.com/pallets/flask">Flask</a>.<br />
|
||||
Ancestor projects: <a href="https://github.com/BearKidsTeam/VirtoolsScriptDeobfuscation">BearKidsTeam/VirtoolsScriptDeobfuscation</a> and <a href="https://github.com/BearKidsTeam/Script-Materializer">BearKidsTeam/Script-Materializer</a>.<br />
|
||||
Thank <a href="https://github.com/chirs241097">chirs241097</a> and <a href="https://github.com/instr3">2jjy</a>.</p>
|
||||
<br />
|
||||
<p>Current Super Script Materializer version: 1.0</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Super Script Viewer Help</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Super Script Viewer Help</h1>
|
||||
<p>This page is help center, providing useful link for some detailed help page. Choose what you want to use and enter corresponding page.</p>
|
||||
<br />
|
||||
<br />
|
||||
<h2>Converter</h2>
|
||||
<ul>
|
||||
<li><a href="/help/converter">Converter</a>: The page containing converter which can convert the data with various style for some convenient operations.</li>
|
||||
</ul>
|
||||
<h2>Environment database query</h2>
|
||||
<ul>
|
||||
<li><a href="/help/env">Environment data query</a>: The page which can query environment data.</li>
|
||||
</ul>
|
||||
<h2>Viewer legend</h2>
|
||||
<ul>
|
||||
<li><a href="/help/legend">Viewer legend</a>: The page which introduce how to use viewer page.</li>
|
||||
</ul>
|
||||
<br />
|
||||
<br />
|
||||
<!-- todo: finish this-->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,133 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Help - Converter</title>
|
||||
<link rel="stylesheet" href="{{tabcontrol_css}}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
|
||||
<script src="{{tabcontrol_js}}"></script>
|
||||
<script src="{{converter_js}}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Converter</h1>
|
||||
<p>This page provide some useful converter for your decoding work.</p>
|
||||
<br />
|
||||
|
||||
<div style="display: flex; flex-flow: row; height: 30px; width: 100%; margin: 0; padding: 0; border-bottom: 1px solid black;">
|
||||
<div id="tabnavigation_1_1" class="tabnavigation_1 tabitem-activated" style="height: 100%; padding-left: 20px; padding-right: 20px;" onclick="tabControlSwitcher(1, 1);"><b>Reverse C style byte array</b></div>
|
||||
<div id="tabnavigation_1_2" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; padding-left: 20px; padding-right: 20px;" onclick="tabControlSwitcher(1, 2);"><b>C style byte array to HEX</b></div>
|
||||
<div id="tabnavigation_1_3" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; padding-left: 20px; padding-right: 20px;" onclick="tabControlSwitcher(1, 3);"><b>C style byte array to DEC</b></div>
|
||||
<div id="tabnavigation_1_4" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; padding-left: 20px; padding-right: 20px;" onclick="tabControlSwitcher(1, 4);"><b>Lowcase upcase converter</b></div>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_1" class="tabpanel_1">
|
||||
<p>This converter will reverse your inputed C style byte array. Actually, it take responsibility for the convert between big-endian and little-endian.<br />
|
||||
Typical and legal input just like this: <code>0x00, 0xBb, 0xff, 0xFF</code><br />
|
||||
Support multi-input. Use line break to split each input.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv1Input" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Input</td>
|
||||
<th colspan="2"> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100px;" align="left"><button style="width: 50px;" onclick="doConv1_I2O();">v</button></td>
|
||||
<td style="width: 150px;"> </td>
|
||||
<td style="width: 100px;" align="right"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2"> </th>
|
||||
<td align="right">Output</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv1Output" style="width: 100%; height: 100%; resize: none;" readonly="true"></textarea></th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_2" class="tabpanel_1" style="display: none;">
|
||||
<p>This converter will converte provided C style byte array into HEX number. It is double interactive.<br />
|
||||
Acceptable byte array should follow little-endian format.<br />
|
||||
Support multi-input. Use line break to split each input.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv2Input" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Byte array</td>
|
||||
<th colspan="2"> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100px;" align="left"><button style="width: 50px;" onclick="doConv2_I2O();">v</button></td>
|
||||
<td style="width: 150px;"> </td>
|
||||
<td style="width: 100px;" align="right"><button style="width: 50px;" onclick="doConv2_O2I();">^</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2"> </th>
|
||||
<td align="right">HEX number</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv2Output" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_3" class="tabpanel_1" style="display: none;">
|
||||
<p>This converter will converte provided C style byte array into DEC number. It is double interactive.<br />
|
||||
Acceptable byte array should follow little-endian format.<br />
|
||||
Support multi-input. Use line break to split each input.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv3Input" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Byte array</td>
|
||||
<th colspan="2"> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100px;" align="left"><button style="width: 50px;" onclick="doConv3_I2O();">v</button></td>
|
||||
<td style="width: 150px;"> </td>
|
||||
<td style="width: 100px;" align="right"><button style="width: 50px;" onclick="doConv3_O2I();">^</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2"> </th>
|
||||
<td align="right">DEC number</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv3Output" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_4" class="tabpanel_1" style="display: none;">
|
||||
<p>This converter will provide the convert between lowcase and upcase string. It is double interactive.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv4Input" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Lowcase</td>
|
||||
<th colspan="2"> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 100px;" align="left"><button style="width: 50px;" onclick="doConv4_I2O();">v</button></td>
|
||||
<td style="width: 150px;"> </td>
|
||||
<td style="width: 100px;" align="right"><button style="width: 50px;" onclick="doConv4_O2I();">^</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2"> </th>
|
||||
<td align="right">Upcase</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="3" style="height: 150px;"><textarea id="conv4Output" style="width: 100%; height: 100%; resize: none;"></textarea></th>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Help - Environment data query</title>
|
||||
<link rel="stylesheet" href="{{tabcontrol_css}}">
|
||||
<link rel="stylesheet" href="{{env_css}}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
|
||||
<script src="{{tabcontrol_js}}"></script>
|
||||
<script src="{{env_js}}"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Environment data query</h1>
|
||||
<p>This page can query environment data.</p>
|
||||
<br />
|
||||
|
||||
|
||||
<div style="display: flex; flex-flow: row; height: 30px; width: 100%; margin: 0; padding: 0; border-bottom: 1px solid black;">
|
||||
{% for item in database_data %}
|
||||
<div id="tabnavigation_1_{{ loop.index }}" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; padding-left: 20px; padding-right: 20px;" onclick="tabControlSwitcher(1, {{ loop.index }});"><b>{{ item.name }}</b></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for item in database_data %}
|
||||
<div id="tabpanel_1_{{ loop.index }}" class="tabpanel_1" style="display: none;">
|
||||
<p>Query field:</p>
|
||||
<table id="queryTable_{{ loop.index }}" border="1" cellspacing="0" cellpadding="5" style="margin: 10px;">
|
||||
<tr>
|
||||
<td><b>Use this</b></td>
|
||||
<td><b>Field name</b></td>
|
||||
<td style="width: 150px;"><b>Value</b></td>
|
||||
<td><b>Example</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
|
||||
{% for innerItem in item.data %}
|
||||
<tr>
|
||||
<td><input type="checkbox" value="1"></input></td>
|
||||
<td queryName="{{ innerItem[0]|e }}">{{ innerItem[0]|e }}</td>
|
||||
<td><input type="text"></input></td>
|
||||
<td>{{ innerItem[1]|e }}</td>
|
||||
<td>{{ innerItem[2]|e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<button style="padding: 5px;" onclick="doQuery({{ loop.index }}, "{{ item.queryKey }}");">Query</button>
|
||||
<p>Query result:</p>
|
||||
<p id="resultTableOverflow_{{ loop.index }}" style="color: red; display: none;">The count of query result is more than 100 items(Only the first 100 items will be shown). Please give more limitation.</p>
|
||||
|
||||
<table id="resultTable_{{ loop.index }}" class="envOutput" cellspacing="0" cellpadding="5" style="margin: 10px;">
|
||||
<tr>
|
||||
{% for innerItem in item.data %}
|
||||
<td>{{ innerItem[0]|e }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Help - Viewer legend</title>、
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Viewer legend</h1>
|
||||
<p>This page introduce how to use viewer page.</p>
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,8 +0,0 @@
|
||||
{% for key, value in scripts.items() %}
|
||||
<h2>{{ key|e }}</h2>
|
||||
<ol>
|
||||
{% for i in value %}
|
||||
<li><a href="{{ "/viewer/%s"|format(i.id) }}">{{ i.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% endfor %}
|
||||
@@ -1,126 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="height: 100%; margin: 0; padding: 0;">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Script Viewer</title>
|
||||
<link rel="stylesheet" href="{{viewer_css}}">
|
||||
<link rel="stylesheet" href="{{tabcontrol_css}}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.min.js"></script>
|
||||
<script src="{{viewer_js}}"></script>
|
||||
<script src="{{tabcontrol_js}}"></script>
|
||||
</head>
|
||||
|
||||
<body style="display: flex; flex-flow: row; height: 100%; width: 100%; margin: 0; padding: 0;">
|
||||
<div style="display: flex; flex-flow: column; height: 100%; width: 100%; margin: 0; padding: 0;">
|
||||
<div style="display: flex; flex-flow: row; width: 100%;">
|
||||
<div id="hamburgerMenu" style="display: flex; background: #cfcfcf; flex-flow: row; width: 100%; height: 50px; overflow: scroll;">
|
||||
|
||||
<p class="hamburger"><a href="/index"><b>Script Hierarchy</b></a></p>
|
||||
|
||||
{% for i in hamburgerHistory %}
|
||||
<p class="hamburger">>></p>
|
||||
<p class="hamburger"><a href="{{ "/viewer%s"|format(i.path) }}">{{ i.name|e }}</a></p>
|
||||
{% endfor %}
|
||||
|
||||
<p class="hamburger">>></p>
|
||||
<p class="hamburger"><b>{{ hamburgerCurrent|e }}</b></p>
|
||||
|
||||
</div>
|
||||
<button id="sidepanelToggle" style="width: 50px;" title="Toggle sidepanel display" onclick="sidepanelDisplayChange();"></button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="graphContainer" style="background: #7f7f7f; width: 100%; height: 100%; overflow: scroll; position: relative;">
|
||||
<div>
|
||||
{# blocks content #}
|
||||
{% for i in blocks %}
|
||||
<div class="block-body" style="height: {{ i[12] }}px; width: {{ i[11] }}px; top: {{ i[10] }}px; left: {{ i[9] }}px;" ondblclick="queryInfo(1,{{ i[1] }});" onclick="highlightLink({{ i[1] }});">
|
||||
{% if i[4] != '{}' %}
|
||||
<div class="block-target" title="{{ "Name: %s\nType: %s"|format(*pinDecoder2(i[4])) }}" style="height: 6px; width: 6px; top: 0; left: 0;" onclick="highlightLink({{ pinDecoder(i[4]).id }});"></div>
|
||||
{% endif %}
|
||||
{% for pin in pinDecoder(i[5]) %}
|
||||
<div class="block-p" title="{{ "Name: %s\nType: %s"|format(pin.name, pin.type) }}" style="height: 6px; width: 6px; top: 0; left: {{ 20 + loop.index0 * ( 6 + 20) }}px;" onclick="highlightLink({{ pin.id }});"></div>
|
||||
{% endfor %}
|
||||
{% for pout in pinDecoder(i[6]) %}
|
||||
<div class="block-p" title="{{ "Name: %s\nType: %s"|format(pout.name, pout.type) }}" style="height: 6px; width: 6px; bottom: 0; left: {{ 20 + loop.index0 * ( 6 + 20) }}px;" onclick="highlightLink({{ pout.id }});"></div>
|
||||
{% endfor %}
|
||||
{% for bin in pinDecoder(i[7]) %}
|
||||
<div class="block-b" title="{{ "Name: %s\nType: %s"|format(bin.name, bin.type) }}" style="height: 6px; width: 6px; top: {{ 10 + loop.index0 * ( 6 + 20) }}px; left: 0;" onclick="highlightLink({{ bin.id }});"></div>
|
||||
{% endfor %}
|
||||
{% for bout in pinDecoder(i[8]) %}
|
||||
<div class="block-b" title="{{ "Name: %s\nType: %s"|format(bout.name, bout.type) }}" style="height: 6px; width: 6px; top: {{ 10 + loop.index0 * ( 6 + 20) }}px; right: 0;" onclick="highlightLink({{ bout.id }});"></div>
|
||||
{% endfor %}
|
||||
|
||||
{% if i[13] != -1 %}
|
||||
<p class="block-expandable-text" style="top: 10px; left: 20px;"><a href="{{ "/viewer/%s/%s"|format(currentPath, i[13]) }}">{{ i[2]|e }}</a></p>
|
||||
{% else %}
|
||||
<p class="block-text" style="top: 10px; left: 20px;">{{ i[2]|e }}</p>
|
||||
{% endif %}
|
||||
<p class="block-asstext" style="top: 24px; left: 20px;">{{ i[3]|e }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{# cells content #}
|
||||
{% for i in cells %}
|
||||
<div class="{% if i[6] == 0 %}cell-plocal{% elif i[6] == 1 %}cell-shortcut{% elif i[6] == 2 %}cell-pio{% elif i[6] == 3 %}cell-bio{% else %}cell-ptarget{% endif %}"
|
||||
style="height: {% if i[6] == 2 or i[6] == 3 %}6{% else %}5{% endif %}px; width: {% if i[6] == 2 or i[6] == 3 %}6{% else %}15{% endif %}px; top: {{ i[5] }}px; left: {{ i[4] }}px;"
|
||||
title="{{ "Name: %s\nType: %s"|format(i[2], i[3]) }}" ondblclick="queryInfo(0,{{ i[1] }});" onclick="highlightLink({{ i[1] }});"></div>
|
||||
{% endfor %}
|
||||
|
||||
<svg version="1.1" width="{{ gWidth }}px" height="{{ gHeight }}px" style="position: absolute; top: 0; left: 0;pointer-events: none;">
|
||||
{# links content #}
|
||||
{% for i in links %}
|
||||
{% if i[1] == -2 %}
|
||||
<line class="link-elink target{{ i[2] }} target{{ i[3] }} target{{ i[4] }} target{{ i[5] }}" x1="{{ i[10] }}" y1="{{ i[11] }}" x2="{{ i[12] }}" y2="{{ i[13] }}" stroke="cyan" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
{% elif i[1] == -1 %}
|
||||
<line class="link-plink target{{ i[2] }} target{{ i[3] }} target{{ i[4] }} target{{ i[5] }}" x1="{{ i[10] }}" y1="{{ i[11] }}" x2="{{ i[12] }}" y2="{{ i[13] }}" stroke="blue" stroke-width="1px" stroke-dasharray="5, 1"></line>
|
||||
{% else %}
|
||||
<line class="link-blink target{{ i[2] }} target{{ i[3] }} target{{ i[4] }} target{{ i[5] }}" x1="{{ i[10] }}" y1="{{ i[11] }}" x2="{{ i[12] }}" y2="{{ i[13] }}" stroke="black" stroke-width="1px"></line>
|
||||
<text class="link-blinkDelay target{{ i[2] }} target{{ i[3] }} link-delay target{{ i[4] }} target{{ i[5] }}" x="{{ (i[10] + i[12]) / 2 }}" y="{{ (i[11] + i[13]) / 2 }}" fill="black">{{ i[1] }}</text>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="sidepanelContainer" style="display: flex; flex-flow: column; background: #cfcfcf; height: 100%; width: 25%; margin: 0; padding: 0; border-left: 1px solid black;">
|
||||
<div style="display: flex; flex-flow: row; height: 30px; width: 100%; margin: 0; padding: 0; border-bottom: 1px solid black;">
|
||||
<div id="tabnavigation_1_1" class="tabnavigation_1 tabitem-activated" style="height: 100%; width: 33.33%; text-align: center;" onclick="tabControlSwitcher(1, 1);"><b style="margin: 0;">Properties</b></div>
|
||||
<div id="tabnavigation_1_2" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; width: 33.33%; text-align: center;" onclick="tabControlSwitcher(1, 2);"><b style="margin: 0;">Display</b></div>
|
||||
<div id="tabnavigation_1_3" class="tabnavigation_1 tabitem-deactivated" style="height: 100%; width: 33.33%; text-align: center;" onclick="tabControlSwitcher(1, 3);"><b style="margin: 0;">Tools</b></div>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_1" class="tabpanel_1" style="display: flex; flex-flow: column;width: 100%; height: 100%; display: flex; flex-flow: column; overflow-x: hidden;">
|
||||
<p style="margin: 5px;" id="sidepanel-properties-target">Selected target: <b></b></p>
|
||||
<div id="sidepanel-properties-container" style="width: 100%; height: 100%; overflow: scroll;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_2" class="tabpanel_1" id="sidepanel-display" style="width: 100%; height: 100%; display: flex; flex-flow: column; overflow: scroll; overflow-x: hidden; display: none;">
|
||||
<p style="margin: 5px;">Render:<br />
|
||||
<input type="checkbox" id="sidepanel-display-plink" value="1" onclick="settingChange("plink");">Show pLink and eLink</input>
|
||||
</p>
|
||||
<p style="margin: 5px;">Action:<br />
|
||||
<input type="checkbox" id="sidepanel-display-properties" value="1" onclick="settingChange("properties");">Interactive property inspector</input><br />
|
||||
<input type="checkbox" id="sidepanel-display-highlight" value="1" onclick="settingChange("highlight");">Highlight focused object</input><br />
|
||||
<input type="checkbox" id="sidepanel-display-move" value="1" onclick="settingChange("move");" disabled="true">Move objects</input>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="tabpanel_1_3" class="tabpanel_1" style="width: 100%; height: 100%; display: flex; flex-flow: column; overflow: scroll; overflow-x: hidden; display: none;">
|
||||
<p style="margin: 5px;">Object finder:<br />
|
||||
<input type="text" id="sidepanel-tools-objfinder" disabled="true"></input><br />
|
||||
<button style="height: 30px; margin: 10px 0 10px 0;" disabled="true">Find</button>
|
||||
</p>
|
||||
<p style="margin: 5px;">Misc:<br />
|
||||
<button style="height: 30px; margin: 10px 0 10px 0;" onclick="window.open("/help");">Help</button><br />
|
||||
<button style="height: 30px; margin: 10px 0 10px 0;" onclick="window.open("/about");">About</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
24
cmake/check_materializer_env.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
# Check Windows platform
|
||||
if (NOT WIN32)
|
||||
message(FATAL_ERROR "VirtoolsSchematicWeaver::Materializer only supports Windows platform.")
|
||||
endif ()
|
||||
# Check MSVC toolchain
|
||||
if (NOT MSVC)
|
||||
message(FATAL_ERROR "VirtoolsSchematicWeaver::Materializer only supports MSVC build toolchain.")
|
||||
endif ()
|
||||
# Check architecture
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
message(FATAL_ERROR "VirtoolsSchematicWeaver::Materializer only supports 32-bit platform.")
|
||||
endif ()
|
||||
# Check build type
|
||||
set(VSW_MATERIALIZER_BUILD_TYPES
|
||||
"plugin" "standalone"
|
||||
)
|
||||
if (VSW_MATERIALIZER_BUILD_TYPE IN_LIST VSW_MATERIALIZER_BUILD_TYPES)
|
||||
message( "VirtoolsSchematicWeaver::Materializer build type: ${VSW_MATERIALIZER_BUILD_TYPE}")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"VirtoolsSchematicWeaver::Materializer do not have correct type."
|
||||
"Please assign a legal value (\"plugin\" or \"standalone\") to VSW_MATERIALIZER_BUILD_TYPE."
|
||||
)
|
||||
endif ()
|
||||
0
cmake/custom_import_sqlite.cmake
Normal file
35
cmake/custom_import_virtools.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
# ========== Check Variables ==========
|
||||
# Check Virtools version variable
|
||||
set(SPECIAL_VIRTOOLS_VERSIONS
|
||||
"21"
|
||||
)
|
||||
set(LEGACY_VIRTOOLS_VERSIONS
|
||||
"25"
|
||||
"30"
|
||||
"35"
|
||||
"40"
|
||||
"50"
|
||||
)
|
||||
if (VIRTOOLS_VERSION IN_LIST SPECIAL_VIRTOOLS_VERSIONS)
|
||||
message(
|
||||
"Specified Virtools version: ${VIRTOOLS_VERSION}."
|
||||
"Please note in this verions, your provided Virtools root path must be the root of GitHub repository: doyaGu/Virtools-SDK-2.1"
|
||||
)
|
||||
elseif (VIRTOOLS_VERSION IN_LIST LEGACY_VIRTOOLS_VERSIONS)
|
||||
message("Specified Virtools version: ${VIRTOOLS_VERSION}.")
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"You must set VIRTOOLS_VERSION variable to specify the version of your target Virtools before configurating this project."
|
||||
"The valid Virtools version are 21, 25, 30, 35, 40, 50."
|
||||
)
|
||||
endif ()
|
||||
|
||||
# Check Virtools path variable
|
||||
if (NOT DEFINED VIRTOOLS_PATH)
|
||||
message(FATAL_ERROR
|
||||
"You must set VIRTOOLS_PATH variable to specify the root folder of Virtools before configurating this project."
|
||||
"Please note this path is different when you picking Virtools 2.1 version."
|
||||
)
|
||||
endif()
|
||||
|
||||
# ========== Import library ==========
|
||||
10
cmake/custom_import_yycc.cmake
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
# Check YYCC path variable
|
||||
if (NOT DEFINED YYCC_PATH)
|
||||
message(FATAL_ERROR "You must set YYCC_PATH variable to one of CMake distribution of YYCC installation path.")
|
||||
endif()
|
||||
|
||||
# Find YYCC library
|
||||
find_package(YYCCommonplace REQUIRED
|
||||
HINTS ${YYCC_PATH} NO_DEFAULT_PATH
|
||||
)
|
||||
44
decorator/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
# Create executable
|
||||
add_executable(VSWDecorator "")
|
||||
# Setup source files
|
||||
target_sources(VSWDecorator
|
||||
PRIVATE
|
||||
# Sources
|
||||
main.cpp
|
||||
)
|
||||
# Setup header files
|
||||
target_sources(VSWDecorator
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
# Headers
|
||||
)
|
||||
# Setup header infomations
|
||||
target_include_directories(VSWDecorator
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
# Setup C++ standard
|
||||
set_target_properties(VSWDecorator
|
||||
PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED 20
|
||||
CXX_EXTENSION OFF
|
||||
)
|
||||
# MSVC specific correction
|
||||
target_compile_definitions(VSWDecorator
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
|
||||
)
|
||||
# Order build as UTF-8 in MSVC
|
||||
target_compile_options(VSWDecorator
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/utf-8>
|
||||
)
|
||||
|
||||
# Install binary
|
||||
install(TARGETS VSWDecorator
|
||||
CONFIGURATIONS Release
|
||||
RUNTIME DESTINATION ${VSW_INSTALL_BIN_PATH}
|
||||
)
|
||||
0
decorator/main.cpp
Normal file
@@ -1,65 +0,0 @@
|
||||
# 编译
|
||||
|
||||
本文档将指导您编译或调试`SuperScriptMaterializer`以及对`SuperScriptViewer`的编译。
|
||||
|
||||
## SuperScriptMaterializer
|
||||
|
||||
### 需求
|
||||
|
||||
- Visual Studio 2010,即VC++ v100的工具集(不能使用Virtools 2015及以上版本进行编译,在编译Virtools 5.0 Standalone版本的时候亲测会出错且无法解决,但对于其他版本您可以尝试使用高版本的工具集进行编译)
|
||||
- Virtools SDK 或 Ballance Mod Loader(如果以Virtools 2.1作为目标)
|
||||
- SQlite SDK
|
||||
- Python 3.x
|
||||
|
||||
### 编译之前
|
||||
|
||||
编译之前,对于SQLite SDK,您可以从[sqlite.org](http://www.sqlite.org/)下载,然后使用Visual C++的工具集执行`LIB /DEF:sqlite3.def /machine:IX86`以获取可以用于编译的文件。
|
||||
|
||||
然后您需要先进入项目根目录下,在此处打开终端,我们首先需要生成编译的参数。自上一个版本以来,我们将编译时需要的一些参数全部转为Visual Studio可识别的宏,定义在独立的`Virtools.props`中,此步操作便是生成这个文件,以确定编译文件的相关参数。
|
||||
|
||||
按如下格式运行指令:
|
||||
|
||||
```
|
||||
python3 mk_materializer_cfg.py [plugin|standalone] [21|25|35|40|50] [virtools_root_path] [sqlite_header] [sqlite_lib] [bml path]
|
||||
```
|
||||
|
||||
每一项参数的含义:
|
||||
|
||||
* `[plugin|standalone]`:编译为插件还是独立程序
|
||||
* `[21|25|35|40|50]`:Virtools版本
|
||||
* `[virtools_root_path]`:Virtools Dev的根目录,用于Virtools SDK的头文件,链接库的寻找,也决定程序编译后的输出位置
|
||||
* `[sqlite_header]`:SQlite头文件路径,通常来说指向SQlite头文件所在的文件夹
|
||||
* `[sqlite_lib]`:SQlite链接库的路径,通常来说是指向`sqlite3.lib`的路径
|
||||
* `[bml path]`:BML的路径,只有在以Virtools 2.1为目标编译时才有用
|
||||
|
||||
以下是一些指令示例:
|
||||
|
||||
```
|
||||
python3 .\mk_materializer_cfg.py plugin 50 "E:\Virtools\Virtools Dev 5.0" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py standalone 50 "E:\Virtools\Virtools Dev 5.0" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py plugin 40 "E:\Virtools\Virtools Dev 4.0" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py standalone 40 "E:\Virtools\Virtools Dev 4.0" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py plugin 35 "E:\Virtools\Virtools Dev 3.5" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py standalone 35 "E:\Virtools\Virtools Dev 3.5" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py standalone 25 "E:\Virtools\Virtools Dev 2.5" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
python3 .\mk_materializer_cfg.py standalone 21 "E:\Virtools\Virtools Dev 2.1" "D:\CppLib\SQLite\sqlite-amalgamation-3310100" "D:\CppLib\SQLite\sqlite-dll-win32-x86-3310100" sqlite3.lib "D:\BallanceModLoader"
|
||||
```
|
||||
|
||||
### 编译
|
||||
|
||||
使用`Visual Studio`打开`SuperScriptMaterializer.sln`,选择`SuperScriptMaterializer`工程。然后选择编译模式(Debug或Release),然后编译即可,基本上只要配置无误,编译会很快完成
|
||||
|
||||
## SuperScriptViewer
|
||||
|
||||
### 需求
|
||||
|
||||
* Node.js
|
||||
* gulp
|
||||
* gulp插件:待补充
|
||||
|
||||
### 编译
|
||||
|
||||
`SuperScriptViewer`本身分为2个部分:由Python配合Flask所写的后端,以及前端。后端无需编译,而前端需要通过**gulp**进行操作,以减少文档本身的大小,进而减小传输开销。
|
||||
|
||||
编译的方法很简单,在`Viewer`目录下执行`gulp xxxx`即可让gulp自动完成相关操作。
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# 部署
|
||||
|
||||
本文档将指导您部署属于您的`SuperScriptMaterializer`。它可以让您摆脱Virtools的限制,在所有平台上都可以浏览到Virtools的脚本。您需要先了解README中标准的操作方式,然后,我们会根据部署的一些特殊性,对标准步骤进行修改。
|
||||
|
||||
## 导出脚本
|
||||
|
||||
首先我们需要使用`SuperScriptMaterializer`将我们需要查看的脚本导出。众所周知,Virtools各个版本之间的兼容性很差,为一个版本的所作的文档可能在另一个版本中就无法打开,或者是丢失相关的Building Block,因此,首先您需要根据您所需要查看的Virtools文件的对应版本来选取合适版本的插件,这样可以获得更好的导出效果,因为一旦文档中出现一些Building Block丢失之类的错误,那么Virtools会让一些本可读的字段变成完全不可读的Binary格式。这也是我们的`Materializer`提供如此多版本选项的原因,为的是让每一份可能的文档都可以被正确地加载。
|
||||
|
||||
此外,如果您遇到了NMS文件,那么您可能需要使用Virtools创作环境并配合插件模式的`Materializer`来导出,通过新建一个随意物件然后让脚本加载在其上,进而导出。您可能无法在NMS文件上使用独立模式的`Materializer`,因为它没有办法识别NMS文件。
|
||||
|
||||
当然,您如果遇到了很多文件的情况,您可以将需要的文件放在一起,然后编写一个Shell脚本,然后使用独立模式的`Materializer`来进行批量导出(如果可以的话)。这是一个针对Ballance游戏所有文件的脚本导出的Shell脚本和其生成器的示例,可供您参考。
|
||||
|
||||
// todo: 贴上链接
|
||||
|
||||
如果您有来自不同Virtools版本,您需要分别用对应的导出器进行导出,然后将他们整理归类以供下一级的输入。无需担心不同版本的Virtools导出会导致错误,`Decorator`会正确处理它们。
|
||||
|
||||
## 分析脚本
|
||||
|
||||
您需要准备好`SuperScriptDecorator`,和一份`import.txt`。正如标准操作方式中所言,您需要把需要综合的所有的导出数据库及各个文件的名字写入`import.txt`。我的操作是在上一步生成批处理的时候一并生成`import.txt`,因为它们之间联系很紧密。当然,您完全手写`import.txt`也是可以的。在完成之后,与标准操作方式内所述一致,直接运行即可。分析脚本的时间与您输入的脚本的数量和脚本的复杂度相关。
|
||||
|
||||
## 发布脚本
|
||||
|
||||
分析脚本完成后,我们就该将数据输入到`SuperScriptViewer`中了。与普通运行方式不同,我们需要以非调试模式启动Flask部署后端,并同时完成前端部署。您可以参阅[Flask部署文档](https://flask.palletsprojects.com/en/2.0.x/deploying/)来根据您的情况来进行选择。
|
||||
|
||||
我所作的Ballance脚本展示网页使用Gunicorn,部署指令是`gunicorn ServerCore:app`,其中唯一需要注意的是`ServerCore:app`这个程序入口点,在您选择不同于我的部署方式时,这个入口点将不会改变。与此同时我使用Nginx做了反向代理,具体配置可参考这里
|
||||
|
||||
// todo: 贴上链接
|
||||
@@ -1,480 +0,0 @@
|
||||
# 开发帮助
|
||||
|
||||
此文档将叙述一些开发SuperScriptMaterializer中需要被记忆的一些原则。
|
||||
|
||||
# 可能的连线
|
||||
|
||||
该程序中最重要的事情之一是生成链接,而最困难的是pLink。 下图显示了将在此程序中分析的所有pLink情况。
|
||||
|
||||
```
|
||||
+--------------+ +-----------------+
|
||||
| pLocal +--------------> |
|
||||
+--------------+ | |
|
||||
| pIn (bb/oper) |
|
||||
+----------------+ | |
|
||||
| pIn (bb/oper) +------------> / |
|
||||
+----------------+ | |
|
||||
| pTarget (bb) |
|
||||
+----------------+ | |
|
||||
| pOut (bb/oper) +------------> |
|
||||
+----------------+ +-----------------+
|
||||
|
||||
|
||||
|
||||
|
||||
+------------------+ +-----------------+
|
||||
| +-----------> pOut (bb/oper) |
|
||||
| | +-----------------+
|
||||
| pOut (bb/oper) |
|
||||
| | +--------------+
|
||||
| +-----------> pLocal |
|
||||
+------------------+ +--------------+
|
||||
|
||||
```
|
||||
|
||||
如果链接的一个端点不在当前图形中,则此端点将创建为快捷方式。 但是,如果链接的一个端点是当前分析的Building Graph的pIO,并且与另一个端点具有相同的CK_ID,则应创建一个eLink。
|
||||
|
||||
# 数据库
|
||||
|
||||
SuperScriptMaterializer处理流程里会涉及很多不同的数据库文件,以下是这些数据库和其内表的格式。
|
||||
其中这些是Materializer直接输出的基于文档的数据库:
|
||||
|
||||
* doc.db
|
||||
* env.db
|
||||
|
||||
这些数据库是上面数据库经过Decorator处理可以被Viewer接受的数据库:
|
||||
|
||||
* decorated.db
|
||||
* sheet.db
|
||||
* query.db
|
||||
* composition.db
|
||||
|
||||
## doc.db 格式
|
||||
|
||||
doc.db导出的是当前Virtools文档内的脚本及其它重要数据。
|
||||
|
||||
表列表:
|
||||
|
||||
- script:文档里的每个脚本
|
||||
- script_behavior:behavior本身,包括behavior graph和prototype behavior之类的
|
||||
- script_bIn:behavior的行为输入
|
||||
- script_bOut:behavior的行为输出
|
||||
- script_eLink:export link
|
||||
- script_pAttr:attribute类型的parameter
|
||||
- script_pIn:behavior的parameter输入
|
||||
- script_pLink:parameter link
|
||||
- script_pLocal:local parameter
|
||||
- script_pOper:parameter operator
|
||||
- script_pOut:behavior的parameter输出
|
||||
- script_pTarget:behavior的target输入,实际上是一个特殊的parameter输入
|
||||
- msg:文档内定义的message标号与数值的对应
|
||||
- array:文档里的每个CKDataArray
|
||||
- array_header:CKDataArray的表头
|
||||
- array_cell:CKDataArray的数据体
|
||||
- data:文档中所有涉及导出的parameter参数属性,以类似字典的形式存储每个parameter参数的各个部分
|
||||
|
||||
### script
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|脚本依附对象的`CK_ID`|
|
||||
|name|TEXT|脚本依附对象的名字|
|
||||
|index|INTEGER|脚本在依附对象的排序序号|
|
||||
|behavior|INTEGER|真正的脚本Behavior的`CK_ID`|
|
||||
|
||||
### script_behavior
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|name|TEXT|当前对象的名字|
|
||||
|type|INTEGER|`CKBehavior::GetType`|
|
||||
|proto_name|TEXT|原型名称,没有原型则留空。`CKBehavior::GetPrototypeName`|
|
||||
|proto_guid|TEXT|原型的GUID,如果没有原型则填写`0,0`,格式为`guid1,guid2`,用逗号分隔Virtools的GUID的两部分|
|
||||
|flags|INTEGER|`CKBehavior::GetFlags`|
|
||||
|priority|INTEGER|`CKBehavior::GetPriority`|
|
||||
|version|INTEGER|`CKBehavior::GetVersion`|
|
||||
|pin_count|TEXT|Behavior的接口个数,由5部分组成,用`,`分隔,分别代表:pTarget, pIn, pOut, bIn, bOut|
|
||||
|parent|INTEGER|当前对象父级Behavior的`CK_ID`,如是顶层Behavior则填写-1|
|
||||
|
||||
### script_bIn / script_bOut
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|index|INTEGER|bIn/bOut在所属Behavior的次序号|
|
||||
|name|TEXT|bIn/bOut名称|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|
||||
### script_bLink
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|input|INTEGER|连线输入端的`CK_ID`,不能确认此`CK_ID`是`bOut`还是`bIn`,由于连线也可以是从`parent`的`bIn`连接到子元素的`bIn`|
|
||||
|output|INTEGER|连线输出端的`CK_ID`,不能确认是`bOut`还是`bIn`,理由同上|
|
||||
|delay|INTEGER|连线时延`CKBehaviorLink::GetActivationDelay()`|
|
||||
|input_obj|INTEGER|输入端所属Behavior的`CK_ID`|
|
||||
|input_type|INTEGER|指示输入端类型,0为bIn,1为bOut|
|
||||
|input_index|INTEGER|指示连线位于输入端所在Behavior的第几个bIO口|
|
||||
|output_obj|INTEGER|输出端所属Behavior的`CK_ID`|
|
||||
|output_type|INTEGER|指示输出端类型,0为bIn,1为bOut|
|
||||
|output_index|INTEGER|指示连线位于输出端所在Behavior的第几个bIO口|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|
||||
### script_eLink
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|export_obj|INTEGER|需要被导出的`pIn`或`pOut`的`CK_ID`|
|
||||
|internal_obj|INTEGER|导出连线中`pIn`或`pOut`所属Behavior中层次较深者的`CK_ID`|
|
||||
|is_in|INTEGER|指示连线是对`pIn`还是`pOut`进行导出,如果是`pIn`则设置为1,否则设置为0|
|
||||
|index|INTEGER|导出连线`pIn`或`pOut`在所属Behavior中层次较深者中的参数序号|
|
||||
|parent|INTEGER|导出连线中`pIn`或`pOut`所属Behavior中层次较浅者的`CK_ID`,同时也就是导出连线所归属的Behavior的`CK_ID`|
|
||||
|
||||
导出连线eLink是一种将父级的pIn或pOut链接至器内部Behavior的pIn与pOut的连线。pIn只能链接pIn,pOut只能链接pOut。导出连线一旦链接完成,则意味着两端的pIn或pOut将具有相同的`CK_ID`。
|
||||
|
||||
### script_pAttr
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|name|TEXT|pAttr名称|
|
||||
|type|TEXT|Attribute的类型名|
|
||||
|type_guid|TEXT|Attribute类型的GUID|
|
||||
|
||||
### script_pIn
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|index|INTEGER|pIn在所属Behavior中的序号|
|
||||
|name|TEXT|名称|
|
||||
|type|TEXT|类型名|
|
||||
|type_guid|TEXT|类型GUID|
|
||||
|parent|INTEGER|当前对象所归属的Behavior或Operator的`CK_ID`|
|
||||
|direct_source|INTEGER|`CKParameterIn::GetDirectSource()`|
|
||||
|shared_source|INTEGER|`CKParameterIn::GetSharedSource()`|
|
||||
|
||||
### script_pLink
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|input|INTEGER|pLink起点parameter的`CK_ID`|
|
||||
|output|INTEGER|pLink终点parameter的`CK_ID`|
|
||||
|input_obj|INTEGER|起点parameter所属behavior或operator的`CK_ID`|
|
||||
|input_type|INTEGER|起点来源类型|
|
||||
|input_is_bb|INTEGER|指示起点parameter所属是Behavior还是Operator,如果是Behavior,则填写为1,否则为0|
|
||||
|input_index|INTEGER|起点parameter所属Behavior的序号值|
|
||||
|output_obj|INTEGER|终点parameter所属behavior或operator的`CK_ID`|
|
||||
|output_type|INTEGER|终点来源类型|
|
||||
|output_is_bb|INTEGER|指示终点parameter所属是Behavior还是Operator|
|
||||
|output_index|INTEGER|终点parameter所属Behavior的序号值|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|
||||
`input_type`与`output_type`使用下列数值:
|
||||
|
||||
* pIn:0
|
||||
* pOut:1
|
||||
* pLocal:2
|
||||
* pTarget:3
|
||||
* pAttr:4
|
||||
|
||||
当其值不是`pIn`或`pOut`中任何一个时,忽略对应输入或输出的`is_bb`与`index`值。
|
||||
|
||||
### script_pLocal
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|name|TEXT|名称|
|
||||
|type|TEXT|类型名|
|
||||
|type_guid|TEXT|类型GUID|
|
||||
|is_setting|INTEGER|是否是所属Behavior的Setting,调用所属Behavior的`CKBehavior::IsLocalParameterSetting()`|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|
||||
### script_pOper
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|op|TEXT|名称|
|
||||
|op_guid|TEXT|Operator采用的转换函数的GUID|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|
||||
### script_pOut
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|index|INTEGER|在所属Behavior中的序号|
|
||||
|name|TEXT|名称|
|
||||
|type|TEXT|类型名|
|
||||
|type_guid|TEXT|类型GUID|
|
||||
|parent|INTEGER|当前对象所归属的Behavior或Operator的`CK_ID`|
|
||||
|
||||
### script_pTarget
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|name|TEXT|名称|
|
||||
|type|TEXT|类型名|
|
||||
|type_guid|TEXT|类型GUID|
|
||||
|parent|INTEGER|当前对象所归属的Behavior的`CK_ID`|
|
||||
|direct_source|INTEGER|`CKParameterIn::GetDirectSource()`|
|
||||
|shared_source|INTEGER|`CKParameterIn::GetSharedSource()`|
|
||||
|
||||
与`pIn`类似,仅缺少`index`描述,因为对于一个Behavior,pTarget至多只能有1个。
|
||||
|
||||
### msg
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|index|INTEGER|message的标号|
|
||||
|name|TEXT|message的名称|
|
||||
|
||||
### array
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|thisobj|INTEGER|当前对象的`CK_ID`|
|
||||
|name|TEXT|表的名称|
|
||||
|rows|INTEGER|表的行数|
|
||||
|columns|INTEGER|表的列数|
|
||||
|
||||
### array_header
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|index|INTEGER|当前表头的是第几列|
|
||||
|name|TEXT|名称|
|
||||
|type|INTEGER|列类型,`CKDataArray::GetColumnType`|
|
||||
|param_type|TEXT|列的类型|
|
||||
|param_type_guid|TEXT|列的类型的GUID|
|
||||
|parent|INTEGER|表头所属表的`CK_ID`|
|
||||
|
||||
当列类型为Parameter时,`param_type`和`param_type_guid`为其所属CKParameterType的类型文本和GUID,当列类型为Object时,`param_type`和`param_type_guid`均无效,因为无法确认对应CKObject的类型。列类型为其它类型时,`param_type`和`param_type_guid`也均无效。
|
||||
|
||||
### array_cell
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|row|INTEGER|当前单元格所在行|
|
||||
|column|INTEGER|当前单元格所在列|
|
||||
|showcase|TEXT|单元格可视化文本|
|
||||
|inner_param|INTEGER|单元格内部数据,为对应CKParameter或CKObject的`CK_ID`|
|
||||
|parent|INTEGER|单元格所属表的`CK_ID`|
|
||||
|
||||
当且仅当对应列的类型为Parameter或Object时,`inner_param`才有效。
|
||||
|
||||
### data
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|field|TEXT|键值对的键|
|
||||
|data|TEXT|键值对的值|
|
||||
|parent|INTEGER|键值对所描述对象的`CK_ID`|
|
||||
|
||||
## env.db 格式
|
||||
|
||||
env.db导出的是当前Virtools环境的数据,与文档无关,这部分如果是多个文件共用一个环境,那么只需要导出和在`Decorator`里综合一次即可
|
||||
|
||||
表列表:
|
||||
|
||||
- attr:attribute
|
||||
- op:operator,parameter转换的定义
|
||||
- param:parameter的定义
|
||||
- plugin:当前环境插件
|
||||
- variable:全局变量数据
|
||||
|
||||
### attr
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|index|INTEGER|序号,总数由`CKAttributeManager::GetAttributeCount()`获取|
|
||||
|name|TEXT|`CKAttributeManager::GetAttributeNameByType()`|
|
||||
|category_index|INTEGER|`CKAttributeManager::GetAttributeCategoryIndex()`|
|
||||
|category_name|TEXT|`CKAttributeManager::GetAttributeCategory()`|
|
||||
|flags|INTEGER|`CKAttributeManager::GetAttributeFlags()`|
|
||||
|param_index|INTEGER|`CKAttributeManager::GetAttributeParameterType()`|
|
||||
|compatible_classid|INTEGER|`CKAttributeManager::GetAttributeCompatibleClassId()`|
|
||||
|default_value|TEXT|`CKAttributeManager::GetAttributeDefaultValue()`|
|
||||
|
||||
### op
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|funcptr|INTEGER|`CKOperationDesc::Fct`|
|
||||
|in1_guid|TEXT|`CKOperationDesc::P1Guid`|
|
||||
|in2_guid|TEXT|`CKOperationDesc::P2Guid`|
|
||||
|out_guid|TEXT|`CKOperationDesc::ResGuid`|
|
||||
|op_guid|TEXT|`CKParameterManager::OperationCodeToGuid()`|
|
||||
|op_name|TEXT|`CKParameterManager::OperationCodeToName`|
|
||||
|op_code|INTEGER|序号,总数由`CKParameterManager::GetParameterOperationCount()`获取|
|
||||
|
||||
### param
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|index|INTEGER|`CKParameterTypeDesc::Index`|
|
||||
|guid|TEXT|`CKParameterTypeDesc::Guid`|
|
||||
|derived_from|TEXT|`CKParameterTypeDesc::DerivedFrom`|
|
||||
|type_name|TEXT|`CKParameterTypeDesc::TypeName`|
|
||||
|default_size|INTEGER|`CKParameterTypeDesc::DefaultSize`|
|
||||
|func_CreateDefault|INTEGER|`CKParameterTypeDesc::CreateDefaultFunction`|
|
||||
|func_Delete|INTEGER|`CKParameterTypeDesc::DeleteFunction`|
|
||||
|func_SaveLoad|INTEGER|`CKParameterTypeDesc::SaveLoadFunction`|
|
||||
|func_Check|INTEGER|`CKParameterTypeDesc::CheckFunction`|
|
||||
|func_Copy|INTEGER|`CKParameterTypeDesc::CopyFunction`|
|
||||
|func_String|INTEGER|`CKParameterTypeDesc::StringFunction`|
|
||||
|func_UICreator|INTEGER|`CKParameterTypeDesc::UICreatorFunction`|
|
||||
|creator_dll_index|INTEGER|`CKParameterTypeDesc::CreatorDll`的`CKPluginEntry::m_PluginDllIndex`|
|
||||
|creator_plugin_index|INTEGER|`CKParameterTypeDesc::CreatorDll`的`CKPluginEntry::m_PositionInDll`|
|
||||
|dw_param|INTEGER|`CKParameterTypeDesc::dwParam`|
|
||||
|dw_flags|INTEGER|`CKParameterTypeDesc::dwFlags`|
|
||||
|cid|INTEGER|`CKParameterTypeDesc::Cid`|
|
||||
|saver_manager|TEXT|`CKParameterTypeDesc::Saver_Manager`|
|
||||
|
||||
### plugin
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|dll_index|INTEGER|`CKPluginEntry::m_PluginDllIndex`|
|
||||
|dll_name|TEXT|以`CKPluginEntry::m_PluginDllIndex`为参,使用`CKPluginManager::GetPluginDllInfo()`,获得的`CKPluginDll::m_DllFileName`|
|
||||
|plugin_index|INTEGER|`CKPluginEntry::m_PositionInDll`|
|
||||
|active|INTEGER|`CKPluginEntry::m_Active`|
|
||||
|guid|TEXT|`CKPluginEntry::m_PluginInfo`的`CKPluginInfo::m_GUID`|
|
||||
|desc|TEXT|`CKPluginEntry::m_Description`|
|
||||
|author|TEXT|`CKPluginEntry::m_Author`|
|
||||
|summary|TEXT|`CKPluginEntry::m_Summary`|
|
||||
|version|INTEGER|`CKPluginEntry::m_Version`|
|
||||
|func_init|INTEGER|`CKPluginEntry::m_InitInstanceFct`|
|
||||
|func_exit|INTEGER|`CKPluginEntry::m_ExitInstanceFct`|
|
||||
|
||||
### variable
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|name|TEXT|`CKVariableManager::Iterator::GetName()`|
|
||||
|description|TEXT|`CKVariableManager::Variable::GetDescription()`|
|
||||
|flags|INTEGER|`CKVariableManager::Variable::GetFlags()`|
|
||||
|type|INTEGER|`CKVariableManager::Variable::GetType()`|
|
||||
|representation|TEXT|`CKVariableManager::Variable::GetRepresentation()`|
|
||||
|data|TEXT|`CKVariableManager::Variable::GetStringValue()`|
|
||||
|
||||
## composition.db 格式
|
||||
|
||||
composition.db是`Decorator`输出的所有被综合的文档与接下来三个数据库分别的内部的编号的的对应表(为每一个被综合的数据库分配一个编号,但是因为有些部分文档共用一个Virtools环境等,就需要将这些编号转换成共用的)
|
||||
使用此表是为了保证网页URL基于编号的命名方式可以在三个表中正常通行,而不会出现在这个表中的编号在另一个表里指示的是另一个Virtools文件。
|
||||
因此在查询其他数据库前需要先读取此数据库获得对应各个数据库的内部编号,进而在剩下的数据库中以内部编号继续查询。
|
||||
|
||||
表只有一个:composition。
|
||||
|
||||
## decorated.db 格式
|
||||
|
||||
decorated.db是`Decorator`输出的脚本综合的数据库,包含了所有脚本的连线和图形位置。
|
||||
|
||||
表列表:
|
||||
|
||||
- block:behavior的图形结构
|
||||
- cell:类似local parameter的结构
|
||||
- graph:脚本schematic图形
|
||||
- link:脚本内的所有连线
|
||||
- param:脚本里的parameter的数据
|
||||
|
||||
### block
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|parent_graph|INTEGER||
|
||||
|thisobj|INTEGER||
|
||||
|name|TEXT||
|
||||
|assist_text|TEXT||
|
||||
|pin-ptarget|TEXT||
|
||||
|pin-pin|TEXT||
|
||||
|pin-pout|TEXT||
|
||||
|pin-bin|TEXT||
|
||||
|pin-bout|TEXT||
|
||||
|x|REAL||
|
||||
|y|REAL||
|
||||
|width|REAL||
|
||||
|height|REAL||
|
||||
|expandable|INTEGER||
|
||||
|
||||
### cell
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|parent_graph|INTEGER||
|
||||
|thisobj|INTEGER||
|
||||
|name|TEXT||
|
||||
|assist_text|TEXT||
|
||||
|x|REAL||
|
||||
|y|REAL||
|
||||
|type|INTEGER||
|
||||
|
||||
### graph
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|graph|INTEGER||
|
||||
|graph_name|TEXT||
|
||||
|width|INTEGER||
|
||||
|height|INTEGER||
|
||||
|index|INTEGER||
|
||||
|parent|TEXT||
|
||||
|
||||
### param
|
||||
|
||||
param为原来的info
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|target|INTEGER||
|
||||
|attach_bb|INTEGER||
|
||||
|is_setting|INTEGER||
|
||||
|name|TEXT||
|
||||
|field|TEXT||
|
||||
|data|TEXT||
|
||||
|
||||
### link
|
||||
|
||||
|字段|类型|含义|
|
||||
|:---|:---|:---|
|
||||
|parent_graph|INTEGER||
|
||||
|delay|INTEGER||
|
||||
|start_interface|INTEGER||
|
||||
|end_interface|INTEGER||
|
||||
|startobj|INTEGER||
|
||||
|endobj|INTEGER||
|
||||
|start_type|INTEGER||
|
||||
|end_type|INTEGER||
|
||||
|start_index|INTEGER||
|
||||
|end_index|INTEGER||
|
||||
|x1|REAL||
|
||||
|y1|REAL||
|
||||
|x2|REAL||
|
||||
|y2|REAL||
|
||||
|
||||
## sheet.db 格式
|
||||
|
||||
sheet.db是`Decorator`输出的文档数据综合的数据库,包含了所有脚本的连线和图形位置。
|
||||
|
||||
表列表:
|
||||
|
||||
- data:同下
|
||||
- header:同下
|
||||
- body:同下
|
||||
- param:与data.db几乎一致
|
||||
|
||||
## query.db 格式
|
||||
|
||||
query.db是`Decorator`输出的数据查询综合的数据库,包含了所有脚本内的数据部分,还有Virtools环境的可查询数据。
|
||||
|
||||
表列表:
|
||||
- msg:从data.db - msg综合
|
||||
- attr:同下
|
||||
- op:同下
|
||||
- param:同下
|
||||
- plugin:同下
|
||||
- variable:从env.db综合
|
||||
@@ -1,2 +0,0 @@
|
||||
Ballance/vt2obj "example.nmo" "export.db" "env.db"
|
||||
"Ballance/vt2obj mirror" Gameplay.nmo export.db env.db
|
||||
53
materializer/CMakeLists.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
# Check build environment
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/check_materializer_env.cmake)
|
||||
# Import virtools sdk
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/custom_import_virtools.cmake)
|
||||
|
||||
# Create library or executable according to build type
|
||||
if (VSW_MATERIALIZER_BUILD_TYPE STREQUAL "plugin")
|
||||
add_library(VSWMaterializer STATIC "")
|
||||
else ()
|
||||
add_executable(VSWMaterializer "")
|
||||
endif ()
|
||||
# Setup static library sources
|
||||
target_sources(VSWMaterializer
|
||||
PRIVATE
|
||||
# Sources
|
||||
main.cpp
|
||||
)
|
||||
target_sources(VSWMaterializer
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
# Headers
|
||||
stdafx.hpp
|
||||
resources.h
|
||||
)
|
||||
# Setup header infomations
|
||||
target_include_directories(VSWMaterializer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
# Setup C++ standard
|
||||
set_target_properties(VSWMaterializer
|
||||
PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED 20
|
||||
CXX_EXTENSION OFF
|
||||
)
|
||||
# MSVC specific correction
|
||||
target_compile_definitions(VSWMaterializer
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
|
||||
)
|
||||
target_compile_options(VSWMaterializer
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/utf-8>
|
||||
)
|
||||
|
||||
# Install binary and headers
|
||||
install(TARGETS VSWMaterializer
|
||||
CONFIGURATIONS Release
|
||||
RUNTIME DESTINATION ${VSW_INSTALL_BIN_PATH}
|
||||
)
|
||||
0
materializer/main.cpp
Normal file
0
materializer/stdafx.hpp
Normal file
BIN
preview.png
|
Before Width: | Height: | Size: 342 KiB |
@@ -1,331 +0,0 @@
|
||||
import vs_props_writer, vs_vcxproj_modifier
|
||||
import os, enum, sys, argparse
|
||||
|
||||
#region Constant Declarations
|
||||
|
||||
class BuildType(enum.Enum):
|
||||
Standalone: str = "standalone"
|
||||
Plugin: str = "plugin"
|
||||
|
||||
class VirtoolsVersion(enum.Enum):
|
||||
V21 = '21'
|
||||
V25 = '25'
|
||||
V30 = '30'
|
||||
V35 = '35'
|
||||
V40 = '40'
|
||||
V50 = '50'
|
||||
|
||||
VT_HEADER_PATH: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: 'Include',
|
||||
VirtoolsVersion.V25: 'Virtools_SDK\\Includes',
|
||||
VirtoolsVersion.V30: 'Sdk\\Includes',
|
||||
VirtoolsVersion.V35: 'Sdk\\Includes',
|
||||
VirtoolsVersion.V40: 'Sdk\\Includes',
|
||||
VirtoolsVersion.V50: 'Sdk\\Includes'
|
||||
}
|
||||
|
||||
VT_LIB_PATH: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: 'Lib',
|
||||
VirtoolsVersion.V25: 'Virtools_SDK\\Lib',
|
||||
VirtoolsVersion.V30: 'Sdk\\Lib',
|
||||
VirtoolsVersion.V35: 'Sdk\\Lib\\Win32\\Release',
|
||||
VirtoolsVersion.V40: 'Sdk\\Lib\\Win32\\Release',
|
||||
VirtoolsVersion.V50: 'Sdk\\Lib\\Win32\\Release'
|
||||
}
|
||||
|
||||
VT_STANDALONE_ATTACHED_LIBS: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: "VxMath.lib;CK2.lib",
|
||||
VirtoolsVersion.V25: "VxMath.lib;CK2.lib",
|
||||
VirtoolsVersion.V30: "VxMath.lib;CK2.lib",
|
||||
VirtoolsVersion.V35: "VxMath.lib;CK2.lib",
|
||||
VirtoolsVersion.V40: "VxMath.lib;CK2.lib",
|
||||
VirtoolsVersion.V50: "VxMath.lib;CK2.lib"
|
||||
}
|
||||
VT_PLUGIN_ATTACHED_LIBS: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: "",
|
||||
VirtoolsVersion.V25: "",
|
||||
VirtoolsVersion.V30: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
||||
VirtoolsVersion.V35: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
||||
VirtoolsVersion.V40: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib",
|
||||
VirtoolsVersion.V50: "VxMath.lib;DllEditor.lib;CK2.lib;InterfaceControls.lib;CKControls.lib"
|
||||
}
|
||||
|
||||
VT_PLUGIN_MACROS: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
||||
VirtoolsVersion.V25: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
||||
VirtoolsVersion.V30: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
||||
VirtoolsVersion.V35: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
||||
VirtoolsVersion.V40: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE",
|
||||
VirtoolsVersion.V50: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE"
|
||||
}
|
||||
VT_STANDALONE_MACROS: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V21: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
||||
VirtoolsVersion.V25: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
||||
VirtoolsVersion.V30: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
||||
VirtoolsVersion.V35: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
||||
VirtoolsVersion.V40: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG",
|
||||
VirtoolsVersion.V50: "_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;VIRTOOLS_USER_SDK"
|
||||
}
|
||||
|
||||
VT_PLUGIN_SUPPORTED_VER: set[VirtoolsVersion] = set((
|
||||
VirtoolsVersion.V30,
|
||||
VirtoolsVersion.V35,
|
||||
VirtoolsVersion.V40,
|
||||
VirtoolsVersion.V50,
|
||||
))
|
||||
VT_STANDALONE_SUPPORTED_VER: set[VirtoolsVersion] = set((
|
||||
VirtoolsVersion.V21,
|
||||
VirtoolsVersion.V25,
|
||||
VirtoolsVersion.V30,
|
||||
VirtoolsVersion.V35,
|
||||
VirtoolsVersion.V40,
|
||||
VirtoolsVersion.V50,
|
||||
))
|
||||
|
||||
VT_EXECUTABLE_DEV: dict[VirtoolsVersion, str] = {
|
||||
VirtoolsVersion.V25: "Dev.exe",
|
||||
VirtoolsVersion.V30: "devr.exe",
|
||||
VirtoolsVersion.V35: "devr.exe",
|
||||
VirtoolsVersion.V40: "devr.exe",
|
||||
VirtoolsVersion.V50: "devr.exe"
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Assist Functions
|
||||
|
||||
def get_project_root() -> str:
|
||||
# build project root path and return
|
||||
return os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
def check_project_root() -> None:
|
||||
"""
|
||||
Check whether this script is executed in correct folder.
|
||||
|
||||
If check failed, this function will exit script, otherwise, return directly.
|
||||
"""
|
||||
project_root: str = get_project_root()
|
||||
# check whether have readme file
|
||||
if not os.path.isfile(os.path.join(project_root, 'README.md')):
|
||||
print('Fail to get project root folder. This script may be placed at wrong location.')
|
||||
sys.exit(1)
|
||||
|
||||
def validate_combination(build_type: BuildType, vt_version: VirtoolsVersion) -> None:
|
||||
"""
|
||||
Check whether the given combination of build type and Virtools version is OK.
|
||||
|
||||
Some combination of build type and Virtools version is invalid.
|
||||
For example, because Virtools 2.5 do not have UI register so plugin build type is not available in Virtools 2.1
|
||||
|
||||
If validation failed, this function will exit script, otherwise, return directly.
|
||||
"""
|
||||
# fetch result
|
||||
is_okey: bool
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
is_okey = vt_version in VT_STANDALONE_SUPPORTED_VER
|
||||
case BuildType.Plugin:
|
||||
is_okey = vt_version in VT_PLUGIN_SUPPORTED_VER
|
||||
# output result
|
||||
if not is_okey:
|
||||
print(f'The combination of "{build_type.value}" and "{vt_version.value}" is not compatible currently.')
|
||||
sys.exit(1)
|
||||
|
||||
def ensure_trailing_slash(given_path: str) -> str:
|
||||
"""
|
||||
Ensure given path is end with slash or backslash.
|
||||
|
||||
@param given_path The path for checking.
|
||||
@return The path with trailing slash or backslash,
|
||||
or the given path self if it already has.
|
||||
"""
|
||||
# make sure return value is end with slash or backslash
|
||||
if given_path[-1] != '\\' or given_path[-1] != '/':
|
||||
return given_path + '\\'
|
||||
else:
|
||||
return given_path
|
||||
|
||||
def get_header_path(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
||||
return os.path.join(vt_root, VT_HEADER_PATH[vt_version])
|
||||
|
||||
def get_lib_path(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
||||
return os.path.join(vt_root, VT_LIB_PATH[vt_version])
|
||||
|
||||
def get_attached_libs(build_type: BuildType, vt_version: VirtoolsVersion) -> str:
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
return VT_STANDALONE_ATTACHED_LIBS[vt_version]
|
||||
case BuildType.Plugin:
|
||||
return VT_PLUGIN_ATTACHED_LIBS[vt_version]
|
||||
|
||||
def get_macros(build_type: BuildType, vt_version: VirtoolsVersion) -> str:
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
return VT_STANDALONE_MACROS[vt_version]
|
||||
case BuildType.Plugin:
|
||||
return VT_PLUGIN_MACROS[vt_version]
|
||||
|
||||
def get_executable_dev(vt_version: VirtoolsVersion, vt_root: str) -> str:
|
||||
"""
|
||||
Return the path to executable Virtools Dev according to given Virtools version.
|
||||
|
||||
Usually it is `Dev.exe` or `devr.exe`.
|
||||
|
||||
@param vt_version The version of Virtools.
|
||||
@param vt_root The path to Virtools root folder.
|
||||
@return The path to executable Virtools Dev.
|
||||
"""
|
||||
return os.path.join(vt_root, VT_EXECUTABLE_DEV[vt_version])
|
||||
|
||||
def get_output_path(build_type: BuildType, vt_root: str) -> str:
|
||||
"""
|
||||
Get the output path for plugin.
|
||||
|
||||
For plugin build type, script will try output binary into `InterfacePlugins` folder in Virtools environment.
|
||||
For standalone build type, script will try output binary in the root path of Virtools.
|
||||
|
||||
@param vt_version The version of Virtools.
|
||||
@param vt_root The path to Virtools root folder.
|
||||
@return The path where the compiled project binary will be placed.
|
||||
"""
|
||||
# fetch output path by build type
|
||||
ret: str
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
ret = vt_root
|
||||
case BuildType.Plugin:
|
||||
ret = os.path.join(vt_root, 'InterfacePlugins')
|
||||
# make sure return value is end with slash or backslash
|
||||
return ensure_trailing_slash(ret)
|
||||
|
||||
def get_binary_suffix(build_type: BuildType) -> str:
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
return 'exe'
|
||||
case BuildType.Plugin:
|
||||
return 'dll'
|
||||
|
||||
def get_module_define(build_type: BuildType) -> str:
|
||||
match(build_type):
|
||||
case BuildType.Standalone:
|
||||
return ''
|
||||
case BuildType.Plugin:
|
||||
return 'SuperScriptMaterializer.def'
|
||||
|
||||
#endregion
|
||||
|
||||
def main() -> None:
|
||||
# ========== Check Environment ==========
|
||||
check_project_root()
|
||||
|
||||
# ========== Accept User Input ==========
|
||||
# build args parser
|
||||
parser = argparse.ArgumentParser(description='Project Configuration Maker')
|
||||
parser.add_argument(
|
||||
'-b', '--build-type', required=True, action='store', dest='build_type', choices=tuple(item.value for item in BuildType),
|
||||
help='The build type of project.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-t', '--virtools-version', required=True, action='store', dest='virtools_version', choices=tuple(item.value for item in VirtoolsVersion),
|
||||
help='The Virtools version you picked.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-p', '--virtools-path', required=True, action='store', dest='virtools_path',
|
||||
help='''
|
||||
The path to the root folder of you picked Virtools version where you can find "Dev.exe".
|
||||
If you select Virtools 2.1, this path should be the root folder of GitHub project "doyaGu/Virtools-SDK-2.1".
|
||||
'''
|
||||
)
|
||||
parser.add_argument(
|
||||
'-a', '--sqlite-amalgamation-path', required=True, action='store', dest='sqlite_amalgamation_path',
|
||||
help='The path to downloaded sqlite amalgamation folder where you can find "sqlite3.h"'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-d', '--sqlite-dll-path', required=True, action='store', dest='sqlite_dll_path',
|
||||
help='The path to downloaded sqlite dll folder where you can find "sqlite3.dll" and "sqlite3.lib" you just built a few minutes ago.'
|
||||
)
|
||||
# parse arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# ========== Analyse Arguments ==========
|
||||
# extract arguments
|
||||
arg_virtools_version: VirtoolsVersion = VirtoolsVersion(args.virtools_version)
|
||||
arg_build_type: BuildType = BuildType(args.build_type)
|
||||
arg_virtools_path: str = args.virtools_path
|
||||
arg_sqlite_amalgamation_path: str = args.sqlite_amalgamation_path
|
||||
arg_sqlite_dll_path: str = args.sqlite_dll_path
|
||||
|
||||
# validate the combination
|
||||
validate_combination(arg_build_type, arg_virtools_version)
|
||||
|
||||
# build macros values
|
||||
# virtools version and build type macro
|
||||
macro_virtools_ver: str = f'VIRTOOLS_{arg_virtools_version.value}'
|
||||
macro_virtools_build_type: str = f'VIRTOOLS_{arg_build_type.value.upper()}'
|
||||
# virtools header and lib
|
||||
macro_virtools_header_path: str = get_header_path(arg_virtools_version, arg_virtools_path)
|
||||
macro_virtools_lib_path: str = get_lib_path(arg_virtools_version, arg_virtools_path)
|
||||
macro_virtools_attcahed_libs: str = get_attached_libs(arg_build_type, arg_virtools_version)
|
||||
# sqlite header and lib
|
||||
macro_sqlite_header_path: str = arg_sqlite_amalgamation_path
|
||||
macro_sqlite_lib_path: str = arg_sqlite_dll_path
|
||||
# output path macro
|
||||
macro_virtools_output_path: str = get_output_path(arg_build_type, arg_virtools_path)
|
||||
# virtools used macros
|
||||
macro_virtools_macros: str = get_macros(arg_build_type, arg_virtools_version)
|
||||
# misc
|
||||
macro_virtools_binary_suffix: str = get_binary_suffix(arg_build_type)
|
||||
macro_virtools_module_define: str = get_module_define(arg_build_type)
|
||||
|
||||
# ========== Create Property File ==========
|
||||
|
||||
props = vs_props_writer.VsPropsWriter()
|
||||
|
||||
# write subsystem
|
||||
match(arg_build_type):
|
||||
case BuildType.Standalone:
|
||||
props.SetSubSystem(vs_props_writer.VsSubSystem.Console)
|
||||
case BuildType.Plugin:
|
||||
props.SetSubSystem(vs_props_writer.VsSubSystem.Windows)
|
||||
|
||||
# write macro and misc
|
||||
# build type distinguish macro
|
||||
props.AddMacro('VIRTOOLS_VER', macro_virtools_ver)
|
||||
props.AddMacro('VIRTOOLS_BUILD_TYPE', macro_virtools_build_type)
|
||||
# header and libs
|
||||
props.AddMacro('VIRTOOLS_HEADER_PATH', macro_virtools_header_path)
|
||||
props.AddMacro('VIRTOOLS_LIB_PATH', macro_virtools_lib_path)
|
||||
props.AddMacro('VIRTOOLS_ATTACHED_LIBS', macro_virtools_attcahed_libs)
|
||||
props.AddMacro('SQLITE_HEADER_PATH', macro_sqlite_header_path)
|
||||
props.AddMacro('SQLITE_LIB_PATH', macro_sqlite_lib_path)
|
||||
# output
|
||||
props.AddMacro('VIRTOOLS_OUTPUT_PATH', macro_virtools_output_path)
|
||||
# essential build macro
|
||||
props.AddMacro('VIRTOOLS_MACROS', macro_virtools_macros)
|
||||
# misc macro
|
||||
props.AddMacro('VIRTOOLS_BINARY_SUFFIX', macro_virtools_binary_suffix)
|
||||
props.AddMacro('VIRTOOLS_MODULE_DEFINE', macro_virtools_module_define)
|
||||
|
||||
# output
|
||||
props.Generate(os.path.join(get_project_root(), 'Virtools.props'))
|
||||
|
||||
# ========== Modify ==========
|
||||
vcxproj = vs_vcxproj_modifier.VsVcxprojModifier(
|
||||
os.path.join(get_project_root(), 'SuperScriptMaterializer/SuperScriptMaterializer.vcxproj')
|
||||
)
|
||||
|
||||
# write build type
|
||||
match(arg_build_type):
|
||||
case BuildType.Standalone:
|
||||
vcxproj.SetBuildType(vcxproj.BUILDTYPE_EXE)
|
||||
case BuildType.Plugin:
|
||||
vcxproj.SetBuildType(vcxproj.BUILDTYPE_DLL)
|
||||
|
||||
# output
|
||||
vcxproj.Modify()
|
||||
|
||||
# ========== Done ==========
|
||||
print("Configuration OK!")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,80 +0,0 @@
|
||||
import xml.dom.minidom as minidom
|
||||
import enum, os, sys
|
||||
|
||||
class VsSubSystem(enum.Enum):
|
||||
Windows = 'Windows'
|
||||
Console = 'Console'
|
||||
|
||||
class VsPropsWriter():
|
||||
|
||||
__mMacroList: dict[str, str]
|
||||
__mSubSystem: VsSubSystem
|
||||
|
||||
def __init__(self):
|
||||
self.__mMacroList = {}
|
||||
self.__mSubSystem = VsSubSystem.Windows
|
||||
|
||||
def AddMacro(self, key: str, value: str):
|
||||
if key in self.__mMacroList:
|
||||
raise Exception(f'Duplicated Set Macro "{key}".')
|
||||
self.__mMacroList[key] = value
|
||||
|
||||
def SetSubSystem(self, subsys: VsSubSystem):
|
||||
self.__mSubSystem = subsys
|
||||
|
||||
def Generate(self, filename: str):
|
||||
# create some header
|
||||
document = minidom.getDOMImplementation().createDocument(None, 'Project', None)
|
||||
root: minidom.Element = document.documentElement
|
||||
root.setAttribute('ToolsVersion', '4.0')
|
||||
root.setAttribute('xmlns', 'http://schemas.microsoft.com/developer/msbuild/2003')
|
||||
|
||||
cache = document.createElement('ImportGroup')
|
||||
cache.setAttribute('Label', 'PropertySheets')
|
||||
root.appendChild(cache)
|
||||
|
||||
# write sub system
|
||||
for bt in ('Debug', 'Release'):
|
||||
node_IDG = document.createElement('ItemDefinitionGroup')
|
||||
node_IDG.setAttribute('Condition', f"'$(Configuration)|$(Platform)'=='{bt}|Win32'")
|
||||
|
||||
node_link = document.createElement('Link')
|
||||
node_sub_system = document.createElement('SubSystem')
|
||||
|
||||
node_sub_system.appendChild(document.createTextNode(self.__mSubSystem.value))
|
||||
|
||||
node_link.appendChild(node_sub_system)
|
||||
node_IDG.appendChild(node_link)
|
||||
root.appendChild(node_IDG)
|
||||
|
||||
# write macro
|
||||
node_PG = document.createElement('PropertyGroup') # macro node 1
|
||||
node_PG.setAttribute('Label', 'UserMacros')
|
||||
root.appendChild(node_PG)
|
||||
|
||||
cache = document.createElement('PropertyGroup') # dummy structure
|
||||
root.appendChild(cache)
|
||||
cache = document.createElement('ItemDefinitionGroup') #dummy structure
|
||||
root.appendChild(cache)
|
||||
|
||||
node_IG = document.createElement('ItemGroup') # macro node 2
|
||||
root.appendChild(node_IG)
|
||||
|
||||
for key, value in self.__mMacroList.items():
|
||||
# create for PropertyGroup
|
||||
node_macro_decl = document.createElement(key)
|
||||
if value != '': # check whether data is empty.
|
||||
node_macro_decl.appendChild(document.createTextNode(value))
|
||||
node_PG.appendChild(node_macro_decl)
|
||||
|
||||
# create for ItemGroup
|
||||
node_macro_ref = document.createElement("BuildMacro")
|
||||
node_macro_ref.setAttribute('Include', key)
|
||||
node_inner_macro_ref = document.createElement('Value')
|
||||
node_inner_macro_ref.appendChild(document.createTextNode("$({})".format(key)))
|
||||
node_macro_ref.appendChild(node_inner_macro_ref)
|
||||
node_IG.appendChild(node_macro_ref)
|
||||
|
||||
# write to file
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
document.writexml(f, addindent='\t', newl='\n', encoding='utf-8')
|
||||
@@ -1,51 +0,0 @@
|
||||
import xml.dom.minidom as minidom
|
||||
import xml.dom
|
||||
import os
|
||||
import sys
|
||||
|
||||
class VsVcxprojModifier():
|
||||
|
||||
BUILDTYPE_EXE: str = 'Application'
|
||||
BUILDTYPE_DLL: str = 'DynamicLibrary'
|
||||
|
||||
def __init__(self, vcfile: str):
|
||||
self.__Dom = minidom.parse(vcfile)
|
||||
self.__FileName: str = vcfile
|
||||
self.__BuildType: str = None
|
||||
|
||||
def SetBuildType(self, bt: str):
|
||||
self.__BuildType = bt
|
||||
|
||||
def Modify(self):
|
||||
# if no spec build type, do not modify
|
||||
if self.__BuildType is None:
|
||||
return
|
||||
|
||||
# get corresponding entry
|
||||
dom = self.__Dom
|
||||
node_project = dom.documentElement
|
||||
for node_PG in node_project.getElementsByTagName('PropertyGroup'):
|
||||
attr_label = node_PG.getAttribute('Label')
|
||||
attr_condition = node_PG.getAttribute('Condition')
|
||||
|
||||
# skip invalid node
|
||||
if attr_label != 'Configuration':
|
||||
continue
|
||||
if attr_condition != "'$(Configuration)|$(Platform)'=='Debug|Win32'" and attr_condition != "'$(Configuration)|$(Platform)'=='Release|Win32'":
|
||||
continue
|
||||
|
||||
# this is valid node, process it
|
||||
node_CT = node_PG.getElementsByTagName('ConfigurationType')
|
||||
if len(node_CT) != 0:
|
||||
# have node, change it
|
||||
node_CT[0].childNodes[0].nodeValue = self.__BuildType
|
||||
else:
|
||||
# don't have node, add one
|
||||
node_CT = dom.createElement('ConfigurationType')
|
||||
node_CT.appendChild(dom.createTextNode(self.__BuildType))
|
||||
node_PG.appendChild(node_CT)
|
||||
|
||||
# write file
|
||||
with open(self.__FileName, 'w', encoding='utf-8') as f:
|
||||
dom.writexml(f, encoding='utf-8')
|
||||
|
||||
37
shared/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
# Create static library
|
||||
add_library(VSWShared STATIC "")
|
||||
# Setup source files
|
||||
target_sources(VSWShared
|
||||
PRIVATE
|
||||
# Sources
|
||||
)
|
||||
# Setup header files
|
||||
target_sources(VSWShared
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
# Headers
|
||||
DataTypes.hpp
|
||||
)
|
||||
# Setup include directory
|
||||
target_include_directories(VSWShared
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
# Setup C++ standard
|
||||
set_target_properties(VSWShared
|
||||
PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED 20
|
||||
CXX_EXTENSION OFF
|
||||
)
|
||||
# MSVC specific correction
|
||||
target_compile_definitions(VSWShared
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
|
||||
)
|
||||
target_compile_options(VSWShared
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/utf-8>
|
||||
)
|
||||