diff --git a/BMapBindings/BMapSharp/.editorconfig b/BMapBindings/BMapSharp/.editorconfig
new file mode 100644
index 0000000..ca51e64
--- /dev/null
+++ b/BMapBindings/BMapSharp/.editorconfig
@@ -0,0 +1,364 @@
+root = true
+
+# All files
+[*]
+indent_style = space
+
+# Xml files
+[*.xml]
+indent_size = 2
+
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+[*.{cs,vb}]
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = false
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false:silent
+dotnet_style_qualification_for_field = false:silent
+dotnet_style_qualification_for_method = false:silent
+dotnet_style_qualification_for_property = false:silent
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:silent
+dotnet_style_predefined_type_for_member_access = true:silent
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_simplified_interpolation = true:suggestion
+
+# Field preferences
+dotnet_style_readonly_field = true:warning
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all:suggestion
+
+# Suppression preferences
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+#### C# Coding Conventions ####
+[*.cs]
+
+# var preferences
+csharp_style_var_elsewhere = false:silent
+csharp_style_var_for_built_in_types = false:silent
+csharp_style_var_when_type_is_apparent = false:silent
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_lambdas = true:suggestion
+csharp_style_expression_bodied_local_functions = false:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_prefer_not_pattern = true:suggestion
+csharp_style_prefer_pattern_matching = true:silent
+csharp_style_prefer_switch_expression = true:suggestion
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Modifier preferences
+csharp_prefer_static_local_function = true:warning
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
+
+# Code-block preferences
+csharp_prefer_braces = true:silent
+csharp_prefer_simple_using_statement = true:suggestion
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_prefer_index_operator = true:suggestion
+csharp_style_prefer_range_operator = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:silent
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = false
+csharp_new_line_before_else = false
+csharp_new_line_before_finally = false
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = none
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+[*.{cs,vb}]
+
+# Naming rules
+
+dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
+dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
+dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
+dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
+
+dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
+dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
+dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
+
+dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
+dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
+dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.events_should_be_pascalcase.symbols = events
+dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
+dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
+dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
+
+dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
+dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
+dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
+
+dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
+dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
+dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
+
+dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
+dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion
+dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields
+dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase
+
+dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
+dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
+dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
+
+dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
+dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
+dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
+dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
+dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
+dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
+dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
+
+dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
+
+# Symbol specifications
+
+dotnet_naming_symbols.interfaces.applicable_kinds = interface
+dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interfaces.required_modifiers =
+
+dotnet_naming_symbols.enums.applicable_kinds = enum
+dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.enums.required_modifiers =
+
+dotnet_naming_symbols.events.applicable_kinds = event
+dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.events.required_modifiers =
+
+dotnet_naming_symbols.methods.applicable_kinds = method
+dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.methods.required_modifiers =
+
+dotnet_naming_symbols.properties.applicable_kinds = property
+dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.properties.required_modifiers =
+
+dotnet_naming_symbols.public_fields.applicable_kinds = field
+dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
+dotnet_naming_symbols.public_fields.required_modifiers =
+
+dotnet_naming_symbols.private_fields.applicable_kinds = field
+dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
+dotnet_naming_symbols.private_fields.required_modifiers =
+
+dotnet_naming_symbols.private_static_fields.applicable_kinds = field
+dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
+dotnet_naming_symbols.private_static_fields.required_modifiers = static
+
+dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
+dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types_and_namespaces.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
+dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
+dotnet_naming_symbols.type_parameters.required_modifiers =
+
+dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
+dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
+dotnet_naming_symbols.private_constant_fields.required_modifiers = const
+
+dotnet_naming_symbols.local_variables.applicable_kinds = local
+dotnet_naming_symbols.local_variables.applicable_accessibilities = local
+dotnet_naming_symbols.local_variables.required_modifiers =
+
+dotnet_naming_symbols.local_constants.applicable_kinds = local
+dotnet_naming_symbols.local_constants.applicable_accessibilities = local
+dotnet_naming_symbols.local_constants.required_modifiers = const
+
+dotnet_naming_symbols.parameters.applicable_kinds = parameter
+dotnet_naming_symbols.parameters.applicable_accessibilities = *
+dotnet_naming_symbols.parameters.required_modifiers =
+
+dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
+dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
+dotnet_naming_symbols.public_constant_fields.required_modifiers = const
+
+dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
+dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
+
+dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
+dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
+
+dotnet_naming_symbols.local_functions.applicable_kinds = local_function
+dotnet_naming_symbols.local_functions.applicable_accessibilities = *
+dotnet_naming_symbols.local_functions.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascalcase.required_prefix =
+dotnet_naming_style.pascalcase.required_suffix =
+dotnet_naming_style.pascalcase.word_separator =
+dotnet_naming_style.pascalcase.capitalization = pascal_case
+
+dotnet_naming_style.ipascalcase.required_prefix = I
+dotnet_naming_style.ipascalcase.required_suffix =
+dotnet_naming_style.ipascalcase.word_separator =
+dotnet_naming_style.ipascalcase.capitalization = pascal_case
+
+dotnet_naming_style.tpascalcase.required_prefix = T
+dotnet_naming_style.tpascalcase.required_suffix =
+dotnet_naming_style.tpascalcase.word_separator =
+dotnet_naming_style.tpascalcase.capitalization = pascal_case
+
+dotnet_naming_style._camelcase.required_prefix = _
+dotnet_naming_style._camelcase.required_suffix =
+dotnet_naming_style._camelcase.word_separator =
+dotnet_naming_style._camelcase.capitalization = camel_case
+
+dotnet_naming_style.camelcase.required_prefix =
+dotnet_naming_style.camelcase.required_suffix =
+dotnet_naming_style.camelcase.word_separator =
+dotnet_naming_style.camelcase.capitalization = camel_case
+
+dotnet_naming_style.s_camelcase.required_prefix = s_
+dotnet_naming_style.s_camelcase.required_suffix =
+dotnet_naming_style.s_camelcase.word_separator =
+dotnet_naming_style.s_camelcase.capitalization = camel_case
+
diff --git a/BMapBindings/BMapSharp/.gitignore b/BMapBindings/BMapSharp/.gitignore
new file mode 100644
index 0000000..8a30d25
--- /dev/null
+++ b/BMapBindings/BMapSharp/.gitignore
@@ -0,0 +1,398 @@
+## 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/main/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# 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
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# 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
diff --git a/BMapBindings/BMapSharp/.gitkeep b/BMapBindings/BMapSharp/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/BMapBindings/BMapSharp/BMap.cs b/BMapBindings/BMapSharp/BMap.cs
new file mode 100644
index 0000000..48ed6c0
--- /dev/null
+++ b/BMapBindings/BMapSharp/BMap.cs
@@ -0,0 +1,8 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace BMapSharp {
+
+
+
+}
diff --git a/BMapBindings/BMapSharp/BMapSharp.csproj b/BMapBindings/BMapSharp/BMapSharp.csproj
new file mode 100644
index 0000000..0156dab
--- /dev/null
+++ b/BMapBindings/BMapSharp/BMapSharp.csproj
@@ -0,0 +1,13 @@
+
+ * This is C# specific function. + * + * @param canUnsigned The parameter stored in Enum_t that indicate whether this + * enum can use unsigned int as its underlying type. + * @return The string form of its underlying type. + */ + private static String getEnumUnderlyingType(boolean canUnsigned) { + return canUnsigned ? "uint" : "int"; + } + + /** + * Internal real enum declaration writer. + * + * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing. + * @throws Exception + */ + private static void internalWriteEnums(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog) + throws Exception { + IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.CSharp); + for (EnumsHelper.Enum_t enum_t : prog.mEnums) { + // write enum comment + indent.briefComment(enum_t.mEnumComment); + + // write enum start + // write flasg attribute if it is + if (enum_t.mUseFlags) { + indent.puts("[Flags]"); + } + indent.printf("public enum %s : %s {", enum_t.mEnumName, getEnumUnderlyingType(enum_t.mCanUnsigned)); + indent.inc(); + + // write enum entries + for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) { + // write entry self + if (enumEntry_t.mEntryValue == null) { + indent.printf("%s,", enumEntry_t.mEntryName); + } else { + indent.printf("%s = %s,", enumEntry_t.mEntryName, enumEntry_t.mEntryValue); + } + + // write entry comment after member + indent.afterMemberComment(enumEntry_t.mEntryComment); + } + + // write enum tail + indent.dec(); + indent.puts("}"); + } + } + + /** + * Write an enum declaration collection into given file. + *
+ * Actually this is a wrapper of internal enum declaration collection writer. + * + * @param filename The name of written file. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for + * writing. + * @throws Exception + */ + public static void writeEnums(String filename, EnumsHelper.EnumCollection_t prog) throws Exception { + // open file and write + OutputStreamWriter fs = CommonHelper.openOutputFile(filename); + internalWriteEnums(fs, prog); + fs.close(); + } + + /** + * Write a single enum declaration into given file. + *
+ * Actually this is a wrapper of internal enum declaration collection writer. + * + * @param filename The name of written file. + * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing. + * @throws Exception + */ + public static void writeEnum(String filename, EnumsHelper.Enum_t _enum) throws Exception { + // create collection from single enum + EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t(); + col.mEnums.add(_enum); + // open file and write + OutputStreamWriter fs = CommonHelper.openOutputFile(filename); + internalWriteEnums(fs, col); + fs.close(); + } + + // =========== C# Enum Accessible Value Writer =========== + + /** + * Internal real enum accessible value writer. + * + * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing. + * @throws Exception + */ + private static void internalWriteAccVals(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog) + throws Exception { + IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.CSharp); + // write enum collections + for (EnumsHelper.Enum_t enum_t : prog.mEnums) { + // write enum desc header + indent.printf( + "public static readonly System.Collections.Generic.Dictionary<%s, string> %s = new System.Collections.Generic.Dictionary<%s, string>() {", + enum_t.mEnumName, enum_t.mEnumName, enum_t.mEnumName); + indent.inc(); + + // write enum desc entries + for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) { + indent.printf("{ %s.%s, \"%s\" },", enum_t.mEnumName, enumEntry_t.mEntryName, enumEntry_t.mEntryName); + } + + // write enum tail + indent.dec(); + indent.puts("};"); + } + } + + /** + * Write an enum accessible value collection into given file. + *
+ * Actually this is a wrapper of internal enum accessible value collection + * writer. + * + * @param filename The name of written file. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for + * writing. + * @throws Exception + */ + public static void writeAccVals(String filename, EnumsHelper.EnumCollection_t prog) throws Exception { + // open file and write + OutputStreamWriter fs = CommonHelper.openOutputFile(filename); + internalWriteAccVals(fs, prog); + fs.close(); + } + + /** + * Write a single enum accessible value into given file. + *
+ * Actually this is a wrapper of internal enum accessible value collection + * writer. + * + * @param filename The name of written file. + * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing. + * @throws Exception + */ + public static void writeAccVal(String filename, EnumsHelper.Enum_t _enum) throws Exception { + // create a collection with single enum. + EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t(); + col.mEnums.add(_enum); + // open file and write + OutputStreamWriter fs = CommonHelper.openOutputFile(filename); + internalWriteAccVals(fs, col); + fs.close(); + } +} diff --git a/CodeGen/EnumsMigration/ClassidWriter.java b/CodeGen/EnumsMigration/ClassidWriter.java deleted file mode 100644 index a632588..0000000 --- a/CodeGen/EnumsMigration/ClassidWriter.java +++ /dev/null @@ -1,28 +0,0 @@ -import java.io.OutputStreamWriter; -import java.util.stream.Collectors; - -/** - * The nameof values writer for CK_CLASSID. - */ -public class ClassidWriter { - - public static void writeAccVal(String filename, EnumsHelper.Enum_t classids) throws Exception { - OutputStreamWriter writer = CommonHelper.openOutputFile(filename); - IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.CPP); - - indent.puts("const CkClassidReflectionArray CK_CLASSID {"); - indent.inc(); - for (EnumsHelper.EnumEntry_t entry : classids.mEntries) { - EnumsHelper.EnumEntryWithHierarchy_t specialized = (EnumsHelper.EnumEntryWithHierarchy_t) entry; - - String hierarchy = specialized.mHierarchy.stream().map(value -> value.mEntryName) - .collect(Collectors.joining("\", \"")); - indent.printf("{ LibCmo::CK2::CK_CLASSID::%s, { { \"%s\" } } },", entry.mEntryName, hierarchy); - } - indent.dec(); - indent.puts("};"); - - writer.close(); - } - -} diff --git a/CodeGen/EnumsMigration/CommonHelper.java b/CodeGen/EnumsMigration/CommonHelper.java index 49b75e8..fd6dc4f 100644 --- a/CodeGen/EnumsMigration/CommonHelper.java +++ b/CodeGen/EnumsMigration/CommonHelper.java @@ -4,7 +4,6 @@ import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.antlr.v4.runtime.*; @@ -110,17 +109,6 @@ public class CommonHelper { return numstr.replaceFirst("[ulUL]+$", ""); } - /** - * Get underlying type of enum. - * - * @param canUnsigned The parameter stored in Enum_t that indiccate whether this - * enum can use unsigned int as its underlying type. - * @return The string form of its underlying type. - */ - public static String getEnumUnderlyingType(boolean canUnsigned) { - return canUnsigned ? "CKDWORD" : "CKINT"; - } - // =========== Parts =========== enum CKParts { @@ -128,7 +116,7 @@ public class CommonHelper { } enum LangType { - CPP, Python + Cpp, Python, CSharp } public static String getCKPartsNamespace(CKParts parts) { diff --git a/CodeGen/EnumsMigration/CppWriter.java b/CodeGen/EnumsMigration/CppWriter.java new file mode 100644 index 0000000..23bc945 --- /dev/null +++ b/CodeGen/EnumsMigration/CppWriter.java @@ -0,0 +1,273 @@ +import java.io.OutputStreamWriter; +import java.util.stream.Collectors; + +/** + * Write enum declarations and accessible value into C++ format. + */ +public class CppWriter { + + // =========== C++ Enum Declaration Writer =========== + + /** + * Get corredponding C++ underlying type of given enum. + *
+ * This is C++ specific function. + * + * @param canUnsigned The parameter stored in Enum_t that indicate whether this + * enum can use unsigned int as its underlying type. + * @return The string form of its underlying type. + */ + private static String getEnumUnderlyingType(boolean canUnsigned) { + return canUnsigned ? "CKDWORD" : "CKINT"; + } + + /** + * Internal real enum declarations writer. + * + * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing. + * @throws Exception + */ + private static void internalWriteEnums(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog) + throws Exception { + IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Cpp); + for (EnumsHelper.Enum_t enum_t : prog.mEnums) { + // write enum comment + indent.briefComment(enum_t.mEnumComment); + + // write enum start + indent.printf("enum class %s : %s {", enum_t.mEnumName, getEnumUnderlyingType(enum_t.mCanUnsigned)); + indent.inc(); + + // write enum entries + for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) { + // write entry self + if (enumEntry_t.mEntryValue == null) { + indent.printf("%s,", enumEntry_t.mEntryName); + } else { + indent.printf("%s = %s,", enumEntry_t.mEntryName, enumEntry_t.mEntryValue); + } + + // write entry comment after member + indent.afterMemberComment(enumEntry_t.mEntryComment); + } + + // write enum tail + indent.dec(); + indent.puts("};"); + } + } + + /** + * Write an enum collection into given file. + *
+ * Actually this is a wrapper of internal enum collection writer. + * + * @param filename The name of written file. + * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for + * writing. + * @throws Exception + */ + public static void writeEnums(String filename, EnumsHelper.EnumCollection_t prog) throws Exception { + // open file and write + OutputStreamWriter fs = CommonHelper.openOutputFile(filename); + internalWriteEnums(fs, prog); + fs.close(); + } + + /** + * Write a single enum into given file. + *
+ * Actually this is a wrapper of internal enum collection writer.
+ *
+ * @param filename The name of written file.
+ * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing.
+ * @throws Exception
+ */
+ public static void writeEnum(String filename, EnumsHelper.Enum_t _enum) throws Exception {
+ // create an collection from single enum declaration
+ // for suit the argument requirement of real writer.
+ EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t();
+ col.mEnums.add(_enum);
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteEnums(fs, col);
+ fs.close();
+ }
+
+ // =========== C++ Enum Accessible Value Writer ===========
+
+ /**
+ * Internal real enum collection accessible value writer.
+ *
+ * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing.
+ * @param parts The part of these enum declarations. It will indicate the
+ * namespace where find given enum collection.
+ * @throws Exception
+ */
+ private static void internalWriteAccVals(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog,
+ CommonHelper.CKParts parts) throws Exception {
+ IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Cpp);
+
+ // write type defination (just to let user know what the type is)
+ indent.puts("// struct GeneralReflection { const char* mName; };");
+ indent.puts("// template
+ * Actually this is a wrapper of internal enum collection accessible value
+ * writer.
+ *
+ * @param filename The name of written file.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for
+ * writing.
+ * @param parts The part of these enum declarations.
+ * @throws Exception
+ */
+ public static void writeAccVals(String filename, EnumsHelper.EnumCollection_t prog, CommonHelper.CKParts parts)
+ throws Exception {
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteAccVals(fs, prog, parts);
+ fs.close();
+ }
+
+ /**
+ * Write a single enum accessible value into given file.
+ *
+ * Actually this is a wrapper of internal enum collection accessible value
+ * writer.
+ *
+ * @param filename The name of written file.
+ * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing.
+ * @param parts The part of these enum declarations.
+ * @throws Exception
+ */
+ public static void writeAccVal(String filename, EnumsHelper.Enum_t _enum, CommonHelper.CKParts parts)
+ throws Exception {
+ // create a enum collection to fulfill the requirement of internal writer.
+ EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t();
+ col.mEnums.add(_enum);
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteAccVals(fs, col, parts);
+ fs.close();
+ }
+
+ // =========== Specialized C++ Enum Accessible Value Writer ===========
+ // Only accessible value part of CERROR and CK_CLASSID need to be specialized.
+ // The enum self do not need special treat. Just write them normally.
+
+ /**
+ * Specialized CKERROR accessible value writer.
+ *
+ * The declaration of CKERROR do not need special treat. It is okey to use
+ * common writer.
+ *
+ * @param filename The name of written file.
+ * @param errors The {@linkplain EnumsHelper.Enum_t} instance storing CKERROR.
+ * @throws Exception
+ */
+ public static void writeCkErrorAccVal(String filename, EnumsHelper.Enum_t errors) throws Exception {
+ OutputStreamWriter writer = CommonHelper.openOutputFile(filename);
+ IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Cpp);
+
+ // write type defination (just to let user know what the type is)
+ indent.puts("// struct CkErrorReflection { const char* mName; const char* mDescription; };");
+ indent.puts("// using CkErrorReflectionArray = std::vector
+ * The declaration of CK_CLASSID do not need special treat. It is okey to use
+ * common writer.
+ *
+ * @param filename The name of written file.
+ * @param classids The {@linkplain EnumsHelper.Enum_t} instance storing
+ * CK_CLASSID.
+ * @throws Exception
+ */
+ public static void writeCkClassidAccVal(String filename, EnumsHelper.Enum_t classids) throws Exception {
+ OutputStreamWriter writer = CommonHelper.openOutputFile(filename);
+ IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Cpp);
+
+ // write type defination (just to let user know what the type is)
+ indent.puts("// struct CkClassidReflection { std::vector
+ * This function is the most commonly used function for extracting enums.
+ *
+ * This function is used for a file which only contain enum declarations. This
+ * is not suit for extracting CKERROR and CK_CLASSID. For these declarations,
+ * please use their specialized extractor as described following.
+ *
+ * @param infile The file for reading.
+ * @return An {@linkplain EnumsHelper.EnumCollection_t} instance.
+ * @throws Exception
+ */
private static EnumsHelper.EnumCollection_t getEnumsCollection(String infile) throws Exception {
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
CKGeneralLexer lexer = new CKGeneralLexer(pair.mAntlrStream);
@@ -20,6 +31,21 @@ public class MainRunner {
return worker.getEnums();
}
+ /**
+ * Extract a series of "#define" syntax as an enum.
+ *
+ * This function will assume that given file only contain C++ "#define" syntax.
+ * After reading it, it will re-organize it as an enum and return. This only is
+ * used by CKERROR now. But it suit for more scenarios if there are something
+ * like CKERROR in future.
+ *
+ * @param infile The file for reading.
+ * @param assignedEnumName The desired name of organized enum instance.
+ * Contemporary this field should always be "CKERROR"
+ * because no one else is using it.
+ * @return An {@linkplain EnumsHelper.Enum_t} instance.
+ * @throws Exception
+ */
private static EnumsHelper.Enum_t organiseDefines(String infile, String assignedEnumName) throws Exception {
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
CKGeneralLexer lexer = new CKGeneralLexer(pair.mAntlrStream);
@@ -38,6 +64,22 @@ public class MainRunner {
return result;
}
+ /**
+ * Extract a series of macro define as an enum, considering its indent to build
+ * hierarchy.
+ *
+ * This is specialized enum extractor of CK_CLASSID. The given file should use a
+ * series "#define" syntax to describe enum, and use Tab as the indent before
+ * each "#define" syntax to indicate its hierarchy.
+ *
+ * @param infile The file for reading.
+ * @return An {@linkplain EnumsHelper.Enum_t} instance. Actually it is an
+ * instance to {@linkplain EnumsHelper.Enum_t} whose entries is
+ * {@linkplain EnumsHelper.EnumEntryWithHierarchy_t}, the child class of
+ * {@linkplain EnumsHelper.EnumEntry_t} (the entry type of common
+ * {@linkplain EnumsHelper.Enum_t}) with extra hierarchy infos.
+ * @throws Exception
+ */
private static EnumsHelper.Enum_t organiseClassid(String infile) throws Exception {
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
CKGeneralLexer lexer = new CKGeneralLexer(pair.mAntlrStream);
@@ -59,57 +101,74 @@ public class MainRunner {
public static void main(String[] args) throws Exception {
// =========== CKERROR ===========
- EnumsHelper.Enum_t ckerror = organiseDefines("src/CKError.txt", "CKERROR");
- GeneralWriter.writeEnum("dest/CKError.hpp", ckerror);
- GeneralWriter.writePyEnum("dest/CKError.py", ckerror);
- ErrorsWriter.writeAccVal("dest/CKError.AccVal.hpp", ckerror);
- GeneralWriter.writePyAccVal("dest/CKError.AccVal.py", ckerror);
+ EnumsHelper.Enum_t ckerror = organiseDefines("src/CKERROR.txt", "CKERROR");
+ CppWriter.writeEnum("dest/CKERROR.hpp", ckerror);
+ PythonWriter.writeEnum("dest/CKERROR.py", ckerror);
+ CSharpWriter.writeEnum("dest/CKERROR.cs", ckerror);
+ CppWriter.writeCkErrorAccVal("dest/CKERROR.AccVal.hpp", ckerror);
+ PythonWriter.writeAccVal("dest/CKERROR.AccVal.py", ckerror);
+ CSharpWriter.writeAccVal("dest/CKERROR.AccVal.cs", ckerror);
// =========== CK_CLASSID ===========
EnumsHelper.Enum_t classid = organiseClassid("src/CK_CLASSID.txt");
- GeneralWriter.writeEnum("dest/CK_CLASSID.hpp", classid);
- GeneralWriter.writePyEnum("dest/CK_CLASSID.py", classid);
- ClassidWriter.writeAccVal("dest/CK_CLASSID.AccVal.hpp", classid);
- GeneralWriter.writePyAccVal("dest/CK_CLASSID.AccVal.py", classid);
+ CppWriter.writeEnum("dest/CK_CLASSID.hpp", classid);
+ PythonWriter.writeEnum("dest/CK_CLASSID.py", classid);
+ CSharpWriter.writeEnum("dest/CK_CLASSID.cs", classid);
+ CppWriter.writeCkClassidAccVal("dest/CK_CLASSID.AccVal.hpp", classid);
+ PythonWriter.writeAccVal("dest/CK_CLASSID.AccVal.py", classid);
// =========== Define2 ===========
- // Define2 do not need values.
+ // Define2 do not need annotation output.
+ // Because they are CKStateChunk used value which are not exposed to outside.
EnumsHelper.EnumCollection_t def2 = getEnumsCollection("src/Defines2.txt");
- GeneralWriter.writeEnums("dest/CK_CLASSID.hpp", def2);
- GeneralWriter.writePyEnums("dest/CK_CLASSID.py", def2);
+ CppWriter.writeEnums("dest/Defines2.hpp", def2);
+ PythonWriter.writeEnums("dest/Defines2.py", def2);
+ CSharpWriter.writeEnums("dest/Defines2.cs", def2);
// =========== Combined enums ===========
EnumsHelper.EnumCollection_t ck2Enums = getEnumsCollection("src/CKEnums.txt"),
vxEnums = getEnumsCollection("src/VxEnums.txt");
- GeneralWriter.writeEnums("dest/CKEnums.hpp", ck2Enums);
- GeneralWriter.writePyEnums("dest/CKEnums.py", ck2Enums);
- GeneralWriter.writeAccVals("dest/CKEnums.AccVal.hpp", ck2Enums, CommonHelper.CKParts.CK2);
- GeneralWriter.writePyAccVals("dest/CKEnums.AccVal.py", ck2Enums);
- GeneralWriter.writeEnums("dest/VxEnums.hpp", vxEnums);
- GeneralWriter.writePyEnums("dest/VxEnums.py", vxEnums);
- GeneralWriter.writeAccVals("dest/VxEnums.AccVal.hpp", vxEnums, CommonHelper.CKParts.VxMath);
- GeneralWriter.writePyAccVals("dest/VxEnums.AccVal.py", vxEnums);
+
+ CppWriter.writeEnums("dest/CKEnums.hpp", ck2Enums);
+ PythonWriter.writeEnums("dest/CKEnums.py", ck2Enums);
+ CSharpWriter.writeEnums("dest/CKEnums.cs", ck2Enums);
+ CppWriter.writeAccVals("dest/CKEnums.AccVal.hpp", ck2Enums, CommonHelper.CKParts.CK2);
+ PythonWriter.writeAccVals("dest/CKEnums.AccVal.py", ck2Enums);
+ CSharpWriter.writeAccVals("dest/CKEnums.AccVal.cs", ck2Enums);
+
+ CppWriter.writeEnums("dest/VxEnums.hpp", vxEnums);
+ PythonWriter.writeEnums("dest/VxEnums.py", vxEnums);
+ CSharpWriter.writeEnums("dest/VxEnums.cs", vxEnums);
+ CppWriter.writeAccVals("dest/VxEnums.AccVal.hpp", vxEnums, CommonHelper.CKParts.VxMath);
+ PythonWriter.writeAccVals("dest/VxEnums.AccVal.py", vxEnums);
+ CSharpWriter.writeAccVals("dest/VxEnums.AccVal.cs", vxEnums);
// =========== Single enums ===========
EnumsHelper.Enum_t single;
single = organiseDefines("src/CK_STATECHUNK_CHUNKVERSION.txt", "CK_STATECHUNK_CHUNKVERSION");
- GeneralWriter.writeEnum("dest/CK_STATECHUNK_CHUNKVERSION.hpp", single);
- GeneralWriter.writePyEnum("dest/CK_STATECHUNK_CHUNKVERSION.py", single);
- GeneralWriter.writeAccVal("dest/CK_STATECHUNK_CHUNKVERSION.AccVal.hpp", single, CommonHelper.CKParts.CK2);
- GeneralWriter.writePyAccVal("dest/CK_STATECHUNK_CHUNKVERSION.AccVal.py", single);
+ CppWriter.writeEnum("dest/CK_STATECHUNK_CHUNKVERSION.hpp", single);
+ PythonWriter.writeEnum("dest/CK_STATECHUNK_CHUNKVERSION.py", single);
+ CSharpWriter.writeEnum("dest/CK_STATECHUNK_CHUNKVERSION.cs", single);
+ CppWriter.writeAccVal("dest/CK_STATECHUNK_CHUNKVERSION.AccVal.hpp", single, CommonHelper.CKParts.CK2);
+ PythonWriter.writeAccVal("dest/CK_STATECHUNK_CHUNKVERSION.AccVal.py", single);
+ CSharpWriter.writeAccVal("dest/CK_STATECHUNK_CHUNKVERSION.AccVal.cs", single);
single = organiseDefines("src/CK_STATECHUNK_DATAVERSION.txt", "CK_STATECHUNK_DATAVERSION");
- GeneralWriter.writeEnum("dest/CK_STATECHUNK_DATAVERSION.hpp", single);
- GeneralWriter.writePyEnum("dest/CK_STATECHUNK_DATAVERSION.py", single);
- GeneralWriter.writeAccVal("dest/CK_STATECHUNK_DATAVERSION.AccVal.hpp", single, CommonHelper.CKParts.CK2);
- GeneralWriter.writePyAccVal("dest/CK_STATECHUNK_DATAVERSION.AccVal.py", single);
+ CppWriter.writeEnum("dest/CK_STATECHUNK_DATAVERSION.hpp", single);
+ PythonWriter.writeEnum("dest/CK_STATECHUNK_DATAVERSION.py", single);
+ CSharpWriter.writeEnum("dest/CK_STATECHUNK_DATAVERSION.cs", single);
+ CppWriter.writeAccVal("dest/CK_STATECHUNK_DATAVERSION.AccVal.hpp", single, CommonHelper.CKParts.CK2);
+ PythonWriter.writeAccVal("dest/CK_STATECHUNK_DATAVERSION.AccVal.py", single);
+ CSharpWriter.writeAccVal("dest/CK_STATECHUNK_DATAVERSION.AccVal.cs", single);
single = organiseDefines("src/CK_BITMAPDATA_FLAGS.txt", "CK_BITMAPDATA_FLAGS");
- GeneralWriter.writeEnum("dest/CK_BITMAPDATA_FLAGS.hpp", single);
- GeneralWriter.writePyEnum("dest/CK_BITMAPDATA_FLAGS.py", single);
- GeneralWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.hpp", single, CommonHelper.CKParts.CK2);
- GeneralWriter.writePyAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.py", single);
+ CppWriter.writeEnum("dest/CK_BITMAPDATA_FLAGS.hpp", single);
+ PythonWriter.writeEnum("dest/CK_BITMAPDATA_FLAGS.py", single);
+ CSharpWriter.writeEnum("dest/CK_BITMAPDATA_FLAGS.cs", single);
+ CppWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.hpp", single, CommonHelper.CKParts.CK2);
+ PythonWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.py", single);
+ CSharpWriter.writeAccVal("dest/CK_BITMAPDATA_FLAGS.AccVal.cs", single);
// print message.
System.out.println("DONE!");
diff --git a/CodeGen/EnumsMigration/PythonWriter.java b/CodeGen/EnumsMigration/PythonWriter.java
new file mode 100644
index 0000000..3930b23
--- /dev/null
+++ b/CodeGen/EnumsMigration/PythonWriter.java
@@ -0,0 +1,185 @@
+import java.io.OutputStreamWriter;
+import java.util.Locale;
+
+/**
+ * Write enum declarations and accessible value into Python format.
+ */
+public class PythonWriter {
+
+ // =========== Python Enum Declaration Writer ===========
+
+ /**
+ * Internal real enum declaration writer.
+ *
+ * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing.
+ * @throws Exception
+ */
+ private static void internalWriteEnums(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog)
+ throws Exception {
+ IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Python);
+ for (EnumsHelper.Enum_t enum_t : prog.mEnums) {
+ // write enum start
+ indent.printf("class %s(enum.IntEnum):", enum_t.mEnumName);
+ indent.inc();
+
+ // write enum comment
+ indent.briefComment(enum_t.mEnumComment);
+
+ // write enum entries
+ for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) {
+ // write entry self
+ if (enumEntry_t.mEntryValue == null) {
+ indent.printf("%s = auto()", enumEntry_t.mEntryName);
+ } else {
+ indent.printf("%s = %s", enumEntry_t.mEntryName,
+ CommonHelper.convertToPythonNumber(enumEntry_t.mEntryValue));
+ }
+
+ // write entry comment after member
+ indent.afterMemberComment(enumEntry_t.mEntryComment);
+ }
+
+ // enum tail
+ indent.dec();
+ }
+ }
+
+ /**
+ * Write an enum declaration collection into given file.
+ *
+ * Actually this is a wrapper of internal enum declaration collection writer.
+ *
+ * @param filename The name of written file.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for
+ * writing.
+ * @throws Exception
+ */
+ public static void writeEnums(String filename, EnumsHelper.EnumCollection_t prog) throws Exception {
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteEnums(fs, prog);
+ fs.close();
+ }
+
+ /**
+ * Write a single enum declaration into given file.
+ *
+ * Actually this is a wrapper of internal enum declaration collection writer.
+ *
+ * @param filename The name of written file.
+ * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing.
+ * @throws Exception
+ */
+ public static void writeEnum(String filename, EnumsHelper.Enum_t _enum) throws Exception {
+ // create collection from single enum
+ EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t();
+ col.mEnums.add(_enum);
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteEnums(fs, col);
+ fs.close();
+ }
+
+ // =========== Python Enum Accessible Value Writer ===========
+
+ /**
+ * Try generate human readable name from enum entry name.
+ *
+ * This function is only served for Python code generation.
+ *
+ * As you noticed, almost entries of CK enums are fully capital and splitted by
+ * underline. This is really not good for human reading, especially those who
+ * are not programmer. So this function will try give these programmer-oriented
+ * entry name a human readable name as its display name. However, this extract
+ * method is not perfect. It simply do some split and replacement so the
+ * generated content may still not good for reader.
+ *
+ * @param entry_name The name of enum entry
+ * @return A human readable entry name. No guaranteen that return value is must
+ * human readable.
+ */
+ private static String extractHumanReadableEntryName(String entry_name) {
+ // remove first part (any content before underline '_')
+ entry_name = entry_name.replaceFirst("^[a-zA-Z0-9]+_", "");
+
+ // lower all chars except first char
+ if (entry_name.length() < 1)
+ return entry_name;
+ else
+ return entry_name.substring(0, 1) + entry_name.substring(1).toLowerCase(Locale.ROOT);
+ }
+
+ /**
+ * Internal real enum accessible value writer.
+ *
+ * @param writer {@linkplain java.io.OutputStreamWriter} instance for writing.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for writing.
+ * @throws Exception
+ */
+ private static void internalWriteAccVals(OutputStreamWriter writer, EnumsHelper.EnumCollection_t prog)
+ throws Exception {
+ IndentHelper indent = new IndentHelper(writer, CommonHelper.LangType.Python);
+
+ // write implements
+ for (EnumsHelper.Enum_t enum_t : prog.mEnums) {
+ // write enum desc header
+ indent.printf("g_Annotation_%s: dict[int, EnumAnnotation] = {", enum_t.mEnumName);
+ indent.inc();
+
+ // write enum desc entries
+ for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) {
+ String comment = "";
+ if (enumEntry_t.mEntryComment != null) {
+ comment = CommonHelper.escapeString(enumEntry_t.mEntryComment);
+ }
+
+ indent.printf("%s.%s.value: EnumAnnotation(\"%s\", \"%s\"),", enum_t.mEnumName, enumEntry_t.mEntryName,
+ extractHumanReadableEntryName(enumEntry_t.mEntryName), comment);
+ }
+
+ // write enum tail
+ indent.dec();
+ indent.puts("}");
+ }
+ }
+
+ /**
+ * Write an enum accessible value collection into given file.
+ *
+ * Actually this is a wrapper of internal enum accessible value collection
+ * writer.
+ *
+ * @param filename The name of written file.
+ * @param prog {@linkplain EnumsHelper.EnumCollection_t} instance for
+ * writing.
+ * @throws Exception
+ */
+ public static void writeAccVals(String filename, EnumsHelper.EnumCollection_t prog) throws Exception {
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteAccVals(fs, prog);
+ fs.close();
+ }
+
+ /**
+ * Write a single enum accessible value into given file.
+ *
+ * Actually this is a wrapper of internal enum accessible value collection
+ * writer.
+ *
+ * @param filename The name of written file.
+ * @param _enum {@linkplain EnumsHelper.Enum_t} instance for writing.
+ * @throws Exception
+ */
+ public static void writeAccVal(String filename, EnumsHelper.Enum_t _enum) throws Exception {
+ // create a collection with single enum.
+ EnumsHelper.EnumCollection_t col = new EnumsHelper.EnumCollection_t();
+ col.mEnums.add(_enum);
+ // open file and write
+ OutputStreamWriter fs = CommonHelper.openOutputFile(filename);
+ internalWriteAccVals(fs, col);
+ fs.close();
+ }
+
+}
diff --git a/CodeGen/EnumsMigration/README.md b/CodeGen/EnumsMigration/README.md
index 916a819..b5852e2 100644
--- a/CodeGen/EnumsMigration/README.md
+++ b/CodeGen/EnumsMigration/README.md
@@ -1,6 +1,10 @@
-# Code Gen
+# Enums Migration
-A helper program to generate some definations.
+A helper program to migrate existing Virtools enum declarations into other formats.
+
+Original Virtools SDK have various enum declarations. All of them are defined as C format and their formation are not uniform. This sub-project will use laxer and parser to recognize these diverse declarations, extract them as a series of uniform Java data struct and output them as C++ code (as C++ enum class syntax for LibCmo using), Python code (for PyBMap using), and C# code (for BMapSharp using).
+
+The steps processing existing enum declaration is called migration as this sub-project name told.
```
antlr4 CKGeneralLexer.g4
diff --git a/CodeGen/VectorGen/README.md b/CodeGen/VectorGen/README.md
new file mode 100644
index 0000000..2c03b04
--- /dev/null
+++ b/CodeGen/VectorGen/README.md
@@ -0,0 +1,3 @@
+# Vector Generator
+
+Vector types (LibCmo::Vector3 and etc) and Vector-like types (LibCmo::Color and etc) nearly have similar declaration except slight differences (basically is the count of factors). Manually writing these declarations is boring and easy to cause potential invisible bugs. So we use a Python script to generate these declarations batchly to prevent any defects indroduced above.