Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

owent/xres-code-generator

Repository files navigation

xres-code-generator

Sample Usage

Common declare loaders

First import "xrescode_extensions_v3.proto"; and declare loaders. See pb_extension/xrescode_extensions_v3.proto for details.

syntax = "proto3";

import "xrescode_extensions_v3.proto";

message role_upgrade_cfg {
option (xrescode.loader) = {
file_path : "role_upgrade_cfg.bytes"
indexes : {
fields : "Id"
index_type : EN_INDEX_KL // Key - List index: (Id) => list
}
indexes : {
fields : "Id"
fields : "Level"
index_type : EN_INDEX_KV // Key - Value index: (Id, Level) => role_upgrade_cfg
}
// It's allow to add more indexes, the default name of index is [fields].join("_"), you can change name by name field.
tags : "client"
tags : "server"
};

int32 CostValue = 4;
int32 ScoreAdd = 5;
}

For C++

  1. Copy common files from template/common/cpp
  2. Generate loader codes by template template/config_manager.h.mako , template/config_manager.cpp.mako , template/config_easy_api.h.mako , template/config_easy_api.cpp.mako , template/config_set.h.mako , template/config_set.cpp.mako
mkdir -p "$REPO_DIR/sample/pbcpp";
cp -rvf "$REPO_DIR/template/common/cpp/"* "$REPO_DIR/sample/pbcpp";

PREBUILT_PROTOC="$("$PYTHON_BIN" "$REPO_DIR/tools/find_protoc.py")"
"$PREBUILT_PROTOC" -I "$REPO_DIR/sample/proto" -I "$REPO_DIR/pb_extension" "$REPO_DIR/sample/proto/"*.proto -o "$REPO_DIR/sample/sample.pb" ;

# You can use --pb-include-prefix "pbdesc/" to set subdirectory for generated files. This will influence the generated #include <...FILE_PATH>
python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/pbcpp" \
-g "$REPO_DIR/template/config_manager.h.mako" -g "$REPO_DIR/template/config_manager.cpp.mako" \
-g "$REPO_DIR/template/config_easy_api.h.mako" -g "$REPO_DIR/template/config_easy_api.cpp.mako" \
-l "H:$REPO_DIR/template/config_set.h.mako" -l "S:$REPO_DIR/template/config_set.cpp.mako" \
"$@"
  1. At last, just use the generated config_manager and config_easy_api to visit datas.
DebugString().c_str()); } return 0; }">#include <cstdio>

#include "config_manager.h"
#include "config_easy_api.h"

int main() {
// Initialize ....
excel::config_manager::me()->init();

// excel::config_manager::me()->set_version_loader([] (std::string& out) {
// // Read version from file and write it to out
// out.clear(); // Set version to empty will make config_manager ingore version and always reload data files.
// return true; // return true if load version success
// });

// If you want to intergrate file loader to your system(such as UE or Unity), you should provide buffer loader handle
// excel::config_manager::me()->set_buffer_loader([] (std::string& out, const char* file_path) {
// // Read binary data from file with path=file_path, and write all data into out
// // The value of file_path is the same as file_path field of option (xrescode.loader)
// return true; // return true if load file success
// });

// Set how much data group will be keep after reload.
// excel::config_manager::me()->set_group_number(5);

// Call set_override_same_version(true) to force to reload datas even version(load by set_version_loader(HANDLE)) not changed.
// excel::config_manager::me()->set_override_same_version(true);

// Set logger, the default logger is to write log into stdout
// excel::config_manager::me()->set_on_log([](const log_caller_info_t& caller, const char* content) {
// // ...
// });

// Any set any other event handles

// Call reload to generate a configure group
excel::config_manager::me()->reload();

// Now you can load data by easy api or config_manager's raw API
auto cfg = excel::get_role_upgrade_cfg_by_id_level(10001, 3); // using the Key-Value index: id_level
if (cfg) {
printf("%s\n", cfg->DebugString().c_str());
}
return 0;
}

For UE(UnrealEngine) Blueprint support

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/uepbcpp" \
--set ue_include_prefix=ExcelLoader --set ue_type_prefix=ExcelLoader \
--set ue_api_definition=EXCELLOADER_API --add-path "$REPO_DIR/template" \
--set "ue_excel_loader_include_rule=ExcelLoader/%(file_path_camelname)s.h" \
--set "ue_excel_group_api_include_rule=%(file_basename_without_ext)s.h" \
-f "H:$REPO_DIR/template/UEExcelLoader.h.mako:ExcelLoader/\${pb_file.get_file_path_camelname()}.h" \
-f "S:$REPO_DIR/template/UEExcelLoader.cpp.mako:ExcelLoader/\${pb_file.get_file_path_camelname()}.cpp" \
-g "H:$REPO_DIR/template/UEExcelGroupApi.h.mako" -g "S:$REPO_DIR/template/UEExcelGroupApi.cpp.mako" \
"$@"

Also, we can use UEBPProtocol.h.mako and UEBPProtocol.cpp.mako to generate protocol codes for Blueprints.

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/uepbcpp" \
--set ue_include_prefix=ExcelLoader --set ue_type_prefix=ExcelLoader --set ue_bp_protocol_type_prefix=Proto \
--set ue_api_definition=EXCELLOADER_API --add-path "$REPO_DIR/template" \
--set "ue_excel_loader_include_rule=ExcelLoader/%(file_path_camelname)s.h" \
--set "ue_bp_protocol_include_rule=ExcelLoader/%(directory_path)s/Proto%(file_base_camelname)s.h" \
--set "ue_excel_group_api_include_rule=%(file_basename_without_ext)s.h" \
--set "ue_excel_enum_include_rule=ExcelEnum/%(file_basename_without_ext)s.h" \
--pb-exclude-file "xrescode_extensions_v3.proto" \
-f "H:$REPO_DIR/template/UEExcelLoader.h.mako:ExcelLoader/\${pb_file.get_file_path_camelname()}.h" \
-f "S:$REPO_DIR/template/UEExcelLoader.cpp.mako:ExcelLoader/\${pb_file.get_file_path_camelname()}.cpp" \
-g "H:$REPO_DIR/template/UEExcelGroupApi.h.mako" -g "S:$REPO_DIR/template/UEExcelGroupApi.cpp.mako" \
-f "H:$REPO_DIR/template/UEExcelEnum.h.mako:ExcelEnum/\${pb_file.get_file_path_camelname()}.h" \
-f "H:$REPO_DIR/template/UEBPProtocol.h.mako:ExcelLoader/\${pb_file.get_directory_path()}/Proto\${pb_file.get_file_base_camelname()}.h" \
-f "S:$REPO_DIR/template/UEBPProtocol.cpp.mako:ExcelLoader/\${pb_file.get_directory_path()}/Proto\${pb_file.get_file_base_camelname()}.cpp" \
"$@"

For lua

  1. Copy common files from template/common/lua
  2. Generate loader codes by template template/DataTableCustomIndex.lua.mako , template/DataTableCustomIndex53.lua.mako
mkdir -p "$REPO_DIR/sample/pblua";
cp -rvf "$REPO_DIR/template/common/lua/"*.lua "$REPO_DIR/sample/pblua";

PREBUILT_PROTOC="$("$PYTHON_BIN" "$REPO_DIR/tools/find_protoc.py")"
"$PREBUILT_PROTOC" -I "$REPO_DIR/sample/proto" -I "$REPO_DIR/pb_extension" "$REPO_DIR/sample/proto/"*.proto -o "$REPO_DIR/sample/sample.pb" ;

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/pblua" \
-g "$REPO_DIR/template/DataTableCustomIndex.lua.mako" \
-g "$REPO_DIR/template/DataTableCustomIndex53.lua.mako" \
"$@"
  1. At last, just use the generated DataTableService53 to visit datas.
-- We will use require(...) to load DataTableService53,DataTableCustomIndex53 and custom data files, please ensure these can be load by require(FILE_PATH)
-- Assuming the generated lua files by xresloader is located at ../../../xresloader/sample/proto_v3
package.path = '../../../xresloader/sample/proto_v3/?.lua;' .. package.path
local excel_config_service = require('DataTableService53')

-- Set logger
-- excel_config_service:OnError = function (message, data_set, indexName, keys...) end

excel_config_service:ReloadTables()

local role_upgrade_cfg = excel_config_service:Get("role_upgrade_cfg")
local data = role_upgrade_cfg:GetByIndex("id_level", 10001, 3) -- using the Key-Value index: id_level
for k,v in pairs(data) do
print(string.format("%s=%s", k, tostring(v)))
end

-- We can also use DataTableService.GetCurrentGroup(self) and DataTableService.GetByGroup(self, group, loader_name) to support multi-version loader
local current_group = excel_config_service:GetCurrentGroup()
local role_upgrade_cfg2 = excel_config_service:GetByGroup(current_group, "role_upgrade_cfg")
local data2 = role_upgrade_cfg:GetByIndex("id", 10001) -- using the Key-List index: id
print("=======================")
for _,v1 in ipairs(data2) do
print(string.format("\tid: %s, level: %s", tostring(v1.Id), tostring(v1.Level)))
for k,v2 in pairs(v1) do
print(string.format("\t\t%s=%s", k, tostring(v2)))
end
end

For lua - upb

  1. Copy common files from template/common/upblua
  2. Generate loader codes by template template/DataTableCustomIndexUpb.lua.mako
mkdir -p "$REPO_DIR/sample/upblua";
cp -rvf "$REPO_DIR/template/common/upblua/"*.lua "$REPO_DIR/sample/upblua";
cp -rvf "$REPO_DIR/template/common/lua/vardump.lua" "$REPO_DIR/sample/upblua";

PREBUILT_PROTOC="$("$PYTHON_BIN" "$REPO_DIR/tools/find_protoc.py")"
"$PREBUILT_PROTOC" -I "$REPO_DIR/sample/proto" -I "$REPO_DIR/pb_extension" \
"--lua_out=$REPO_DIR/sample/upblua" "--plugin=protoc-gen-lua=" \
"$REPO_DIR/pb_extension/xrescode_extensions_v3.proto" "$REPO_DIR/sample/proto/"*.proto

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/upblua" \
-g "$REPO_DIR/template/DataTableCustomIndexUpb.lua.mako" \
"$@"
  1. At last, just use the generated DataTableCustomIndexUpb to visit datas.
json_encode: %s", upb.json_encode(data, { upb.JSONENC_PROTONAMES }))) print("----------------------- Get by reflection and Key-List index -----------------------") local current_group = excel_config_service:GetCurrentGroup() local role_upgrade_cfg2 = excel_config_service:GetByGroup(current_group, "role_upgrade_cfg") local data2 = role_upgrade_cfg2:GetByIndex("id", 10001) -- using the Key-List index: id for _, v1 in ipairs(data2) do print(string.format("\tid: %s, level: %s", tostring(v1.Id), tostring(v1.Level))) for fds in role_upgrade_cfg2:GetMessageDescriptor():fields() do print(string.format("\t\t%s=%s", fds:name(), tostring(v1[fds:name()]))) end end">-- We will use require(...) to load
-- - DataTableServiceUpb
-- - DataTableCustomIndexUpb
-- - xrescode_extensions_v3_pb
-- - pb_header_v3_pb
-- - upb
-- - google/protobuf/descriptor_pb
-- - Other custom proto files generated by protoc-gen-lua
-- Please ensure these can be load by require(FILE_PATH)
local excel_config_service = require("DataTableServiceUpb")
local upb = require('upb')

-- Set logger
-- excel_config_service:OnError = function (message, data_set, indexName, keys...) end

excel_config_service:ReloadTables()

local role_upgrade_cfg = excel_config_service:Get("role_upgrade_cfg")
print("======================= Lazy load begin =======================")
local data = role_upgrade_cfg:GetByIndex("id_level", 10001, 3) -- using the Key-Value index: id_level
print("======================= Lazy load end =======================")

print("----------------------- Get by Key-Value index -----------------------")
print(string.format("Data of role_upgrade_cfg: id=10001, level=3 -> json_encode: %s",
upb.json_encode(data, { upb.JSONENC_PROTONAMES })))

print("----------------------- Get by reflection and Key-List index -----------------------")
local current_group = excel_config_service:GetCurrentGroup()
local role_upgrade_cfg2 = excel_config_service:GetByGroup(current_group, "role_upgrade_cfg")
local data2 = role_upgrade_cfg2:GetByIndex("id", 10001) -- using the Key-List index: id
for _, v1 in ipairs(data2) do
print(string.format("\tid: %s, level: %s", tostring(v1.Id), tostring(v1.Level)))
for fds in role_upgrade_cfg2:GetMessageDescriptor():fields() do
print(string.format("\t\t%s=%s", fds:name(), tostring(v1[fds:name()])))
end
end

For lua - lua-protobuf

  1. Build lua-protobuf from https://github.com/starwing/lua-protobuf
  2. Copy common files from template/common/lua-protobuf
  3. Generate loader codes by template template/DataTableCustomIndexUpb.lua.mako and rename the output to DataTableCustomIndexLuaProtobuf.lua
mkdir -p "$REPO_DIR/sample/lua-protobuf";
cp -rvf "$REPO_DIR/template/common/lua-protobuf/"*.lua "$REPO_DIR/sample/lua-protobuf";
cp -rvf "$REPO_DIR/template/common/lua/vardump.lua" "$REPO_DIR/sample/lua-protobuf";

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/lua-protobuf" \
-g "$REPO_DIR/template/DataTableCustomIndexUpb.lua.mako:DataTableCustomIndexLuaProtobuf.lua" \
"$@"
  1. At last, just use the generated DataTableCustomIndexLuaProtobuf to visit datas.
local pb = require('pb')

-- ============== Begin: load dependency pb files ==============
local function load_pb(file_path)
local f = io.open(file_path, "rb")
if f == nil then
error(string.format("Open file %s failed", file_path))
return nil
end
local data = f:read("a")
f:close()
pb.load(data)
end

load_pb('pb_header_v3.pb')
load_pb('sample.pb')
-- ============== End: load dependency pb files ==============

local excel_config_service = require("DataTableServiceLuaProtobuf")
excel_config_service:ReloadTables()

print("----------------------- Get by reflection and Key-List index -----------------------")
local current_group = excel_config_service:GetCurrentGroup()
local role_upgrade_cfg2 = excel_config_service:GetByGroup(current_group, "role_upgrade_cfg")
-- require("vardump")
-- vardump(role_upgrade_cfg2, { show_all = true })
local data2 = role_upgrade_cfg2:GetByIndex("id", 10001) -- using the Key-List index: id
for _, v1 in ipairs(data2) do
print(string.format("\tid: %s, level: %s", tostring(v1.Id), tostring(v1.Level)))
end
print("Fields of " .. role_upgrade_cfg2:GetMessageDescriptor().name)
for _, fds in ipairs(role_upgrade_cfg2:GetMessageDescriptor().fields) do
if fds.type.type == nil then
print(string.format("\t%s %s=%s", fds.type.name, fds.name, tostring(fds.number)))
else
print(string.format("\t%s(%s) %s=%s", fds.type.name, fds.type.type, fds.name, tostring(fds.number)))
end
end

For C#/CSharp

  1. Generate loader codes by template template/ConfigSet.cs.mako , template/ConfigSetManager.cs.mako
mkdir -p "$REPO_DIR/sample/pbcs";

PREBUILT_PROTOC="$("$PYTHON_BIN" "$REPO_DIR/tools/find_protoc.py")"
"$PREBUILT_PROTOC" -I "$REPO_DIR/sample/proto" -I "$REPO_DIR/pb_extension" "$REPO_DIR/sample/proto/"*.proto -o "$REPO_DIR/sample/sample.pb" ;

python "$REPO_DIR/xrescode-gen.py" -i "$REPO_DIR/template" -p "$REPO_DIR/sample/sample.pb" -o "$REPO_DIR/sample/pbcs" \
-g "$REPO_DIR/template/ConfigSetManager.cs.mako" \
-l "$REPO_DIR/template/ConfigSet.cs.mako" \
"$@"
  1. Use the generated ConfigSetManager to visit datas.
using System;
using excel;
class Program {
static void Main(string[] args) {
ConfigSetManager.Instance.Reload();
// The C# configSet now generated by Singleton Classes.
// For the multi ConfigGroup management may be added when need.
var table = ConfigSetRoleUpgradeCfg.Instance.GetByIdLevel(10001, 3);
if (table != null) {
Console.WriteLine(table.ToString());
}
}
}

Custom rule and templates

You can custom your loader codes by providing code template files which just like files in $REPO_DIR/template .

  • Globale template: g: