Skip to content

Commit

Permalink
Fix #540: bad_any_cast in Binding.cpp with GCC...
Browse files Browse the repository at this point in the history
Last critical adjustments to have it compile with GCC (on Windows)

+ Someaht more flexible run scripts
  • Loading branch information
xparq committed Feb 19, 2024
1 parent e04e867 commit c28c373
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 23 deletions.
4 changes: 2 additions & 2 deletions run-latest.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ if not defined oon_use_exe (
) else (
set exe=...NONE...

if exist "%SZ_RUN_DIR%/%oon_use_exe.exe%" set exe=%oon_use_exe%.exe
if exist "%SZ_RUN_DIR%/%oon_use_exe.cmd%" set exe=%oon_use_exe%.cmd
if exist "%SZ_RUN_DIR%/%oon_use_exe%.exe" set exe=%oon_use_exe%.exe
if exist "%SZ_RUN_DIR%/%oon_use_exe%.cmd" set exe=%oon_use_exe%.cmd
if exist "%SZ_RUN_DIR%/%oon_use_exe%" set exe=%oon_use_exe%

if exist "%SZ_RUN_DIR%/!exe!" goto :run
Expand Down
32 changes: 32 additions & 0 deletions run.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
::!! Even the %1 %2 %3 %4 %5 %6 %7 %8 %9 hack (instead of shift and %*)
::!! fails with name=value args: the = gets replaced with space! :-ooo
::!! So... This is not not very useful with args on the cmdline. :-/

@echo off
setlocal enabledelayedexpansion


if _%1_ == __ (
echo Usage: %~n0 exename [args...]
goto :eof
)

set use_exe=%1

call %~dp0tooling\_setenv.cmd

set exe=...NONE...

if exist "%SZ_RUN_DIR%/%use_exe%.exe" set exe=%use_exe%.exe
if exist "%SZ_RUN_DIR%/%use_exe%.cmd" set exe=%use_exe%.cmd
if exist "%SZ_RUN_DIR%/%use_exe%" set exe=%use_exe%

if exist "%SZ_RUN_DIR%/!exe!" goto :run

echo - ERROR: No %use_exe% or %use_exe%.exe or %use_exe%.cmd in %SZ_RUN_DIR%^^!
goto :eof


:run
echo Launching: %exe% --cfg=test/default.cfg %2 %3 %4 %5 %6 %7 %8 %9
"%SZ_RUN_DIR%\%exe%" --cfg=test/default.cfg %2 %3 %4 %5 %6 %7 %8 %9
7 changes: 5 additions & 2 deletions src/Engine/SimAppConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,12 @@ cerr << "- NOTE: --interact overrides cfg/sim/global_interactions.\n";
if (args["exit-on-finish"]) exit_on_finish = (args("exit-on-finish") != "off");
if (args["exit_on_finish"]) exit_on_finish = (args("exit_on_finish") != "off"); //!! Sigh, the dup...
background_music = sz::prefix_if_rel(asset_dir, background_music);
#ifdef DEBUG
window_title += " (DEBUG build)";

window_title += " ("; window_title += args.exename();
#ifdef DEBUG
window_title += ", DEBUG build";
#endif
window_title += ")";

cerr << "DBG> current dir: " << sz::getcwd() << '\n';
cerr << "DBG> exe dir: " << exe_dir << '\n';
Expand Down
39 changes: 23 additions & 16 deletions src/UI/Binding.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef _DMN78405B0T873YBV24C467I_
#ifndef _DMN78405B0T873YBV24C467I_
#define _DMN78405B0T873YBV24C467I_

#include <typeinfo>
#include <type_traits> // remove_const
#include <type_traits>
#include <any>
#include <functional>
#include <utility> // inplace_type_t
Expand Down Expand Up @@ -30,25 +30,26 @@ class Binding
using STRING_FUNCTOR = std::function<std::string()>; //! not a raw fn pointer (not a ptr at all), but a (stateful?) function object, so not convertible to/from void*!
//!NOTE: "stateless" lambdas will (or just could?) also get auto-converted to plain old functions!

//--------------------------------------------------------------------
// Convenience ctors for string literals...
Binding(const char* literal);
//--------------------------------------

// Add any other pointer-type binding...
// Helpers to avoid including the monstrosity of <type_traits> just for std::remove_const:
//!! private: template <class T> struct _nonstd_remove_const { typedef T type; };
//!! private: template <class T> struct _nonstd_remove_const<const T> { typedef T type; };
public:
template <typename T> Binding(T* var, const char* type_name = nullptr) :
//!! _data_ptr(const_cast<typename _nonstd_remove_const<T>::type*>(var)),
_data_ptr((std::remove_const<T>*)(var)),
_type(type_name ? type_name : typeid(std::remove_const_t<T>).name())
{}
Binding(const char* literal);

// These can't be part of the template, as stateless ("captureless") lambdas wouldn't match without casting!
//!!?? [What did I mean? Lambdas with empty [] do match? :-o Is the standard?]
Binding(STRING_FN_PTR f);
Binding(CHARPTR_FN_PTR f);

// Add any other pointer-type binding...
template <typename T>
requires (!std::convertible_to<T, std::function<std::string()>>)
Binding(T* var, const char* type_name = nullptr) :
_data_ptr(const_cast<typename std::remove_const_t<T>*>(var)), //!! Does this really need to be this f* ridiculous in C++?
_type(type_name ? type_name : typeid(std::remove_const_t<T>).name())
{}


// Catch-all lambda matcher (needs no cast for lambdas, but we know kinda nothing here...)
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!! IOW, this actually matches EVERYTHING, not just functors!
Expand All @@ -64,6 +65,14 @@ class Binding
//std::cerr << "- unknown type -- hopefully a lambda! :) -- catched...\n";
}

/*!! GCC bug 85282 prevents these from being declared right here:
template <> Binding(std::string value) : _data_ptr(std::in_place_type<std::string>, value), _type(string_literal_name) {}
template <> Binding(int value) : _data_ptr(std::in_place_type<int>, value), _type(int_literal_name) {}
template <> Binding(float value) : _data_ptr(std::in_place_type<float>, value), _type(float_literal_name) {}
template <> Binding(double value) : _data_ptr(std::in_place_type<double>, value), _type(double_literal_name) {}
!!*/
//--------------------------------------------------------------------

// "promptless watcher" call form (a bit too vague tho, but would "mostly work"...):
// template <typename T> auto add(T* var) { return add("", var); }

Expand Down Expand Up @@ -149,14 +158,12 @@ Please choose the Technical Support command on the Visual C++ Help menu, or open

}; // class Binding


//! (GCC didn't compile this inside the class, where it would be more in-context.)
//! GCC won't compile these inside the class due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282:
template <> inline Binding::Binding(std::string value) : _data_ptr(std::in_place_type<std::string>, value), _type(string_literal_name) {}
template <> inline Binding::Binding(int value) : _data_ptr(std::in_place_type<int>, value), _type(int_literal_name) {}
template <> inline Binding::Binding(float value) : _data_ptr(std::in_place_type<float>, value), _type(float_literal_name) {}
template <> inline Binding::Binding(double value) : _data_ptr(std::in_place_type<double>, value), _type(double_literal_name) {}


}; // namespace UI

//!!?? Declaring it as friend was not enough this time. But why?
Expand Down
6 changes: 3 additions & 3 deletions src/UI/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ void HUD::add(int literal)
void HUD::add(Binding::STRING_FN_PTR f)
{
//cerr <<"---> HUD: ADDING "<< Binding::fptr_name <<": "<< (void*)f <<" -> "<< f() <<'\n';
_elements.emplace_back(std::in_place_type<Binding>, f, Binding::string_fn_ptr_name);
/*
_elements.emplace_back(f);
/*!! OLD:
//-------------------------------------------------------------
// Helpers to avoid including the monstrosity of <type_traits> just for std::remove_const:
private: template <class T> struct _nonstd_remove_const { typedef T type; };
Expand All @@ -60,7 +60,7 @@ void HUD::add(Binding::STRING_FN_PTR f)
//!!?? std::cerr << type_name << " -> " << (void*)any_cast<void*>(ptr) << " added." << endl;
// std::cerr << type_name << " added." << endl;
}
*/
!!*/
}


Expand Down

0 comments on commit c28c373

Please sign in to comment.