[q3map2] Unwind script stack in case of script loading error.
[xonotic/netradiant.git] / libs / stringio.h
index ff1a3a6..47772ee 100644 (file)
@@ -29,6 +29,7 @@
 #include "iscriplib.h"
 #include "string/string.h"
 #include "generic/callback.h"
+#include "property.h"
 
 inline float string_read_float( const char* string ){
        return static_cast<float>( atof( string ) );
@@ -219,7 +220,7 @@ inline bool string_parse_size( const char* string, std::size_t& i ){
 }
 
 
-#define RETURN_FALSE_IF_FAIL( expression ) if ( !expression ) {return false; }else
+#define RETURN_FALSE_IF_FAIL(expression) do { if (!(expression)) return false; } while (0)
 
 inline void Tokeniser_unexpectedError( Tokeniser& tokeniser, const char* token, const char* expected ){
        globalErrorStream() << Unsigned( tokeniser.getLine() ) << ":" << Unsigned( tokeniser.getColumn() ) << ": parse error at '" << ( token != 0 ? token : "#EOF" ) << "': expected '" << expected << "'\n";
@@ -287,183 +288,78 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& outputStream,
 }
 
 
-
-
-inline void CopiedString_importString( CopiedString& self, const char* string ){
-       self = string;
-}
-typedef ReferenceCaller1<CopiedString, const char*, CopiedString_importString> CopiedStringImportStringCaller;
-inline void CopiedString_exportString( const CopiedString& self, const StringImportCallback& importer ){
-       importer( self.c_str() );
-}
-typedef ConstReferenceCaller1<CopiedString, const StringImportCallback&, CopiedString_exportString> CopiedStringExportStringCaller;
-
-inline void Bool_importString( bool& self, const char* string ){
-       self = string_equal( string, "true" );
-}
-typedef ReferenceCaller1<bool, const char*, Bool_importString> BoolImportStringCaller;
-inline void Bool_exportString( const bool& self, const StringImportCallback& importer ){
-       importer( self ? "true" : "false" );
-}
-typedef ConstReferenceCaller1<bool, const StringImportCallback&, Bool_exportString> BoolExportStringCaller;
-
-inline void Int_importString( int& self, const char* string ){
-       if ( !string_parse_int( string, self ) ) {
-               self = 0;
-       }
-}
-typedef ReferenceCaller1<int, const char*, Int_importString> IntImportStringCaller;
-inline void Int_exportString( const int& self, const StringImportCallback& importer ){
-       char buffer[16];
-       sprintf( buffer, "%d", self );
-       importer( buffer );
-}
-typedef ConstReferenceCaller1<int, const StringImportCallback&, Int_exportString> IntExportStringCaller;
-
-inline void Size_importString( std::size_t& self, const char* string ){
-       int i;
-       if ( string_parse_int( string, i ) && i >= 0 ) {
-               self = i;
-       }
-       else
-       {
-               self = 0;
+template<>
+struct PropertyImpl<bool, const char *> {
+       static void Export(const bool &self, const Callback<void(const char *)> &returnz) {
+               returnz(self ? "true" : "false");
        }
-}
-typedef ReferenceCaller1<std::size_t, const char*, Size_importString> SizeImportStringCaller;
-inline void Size_exportString( const std::size_t& self, const StringImportCallback& importer ){
-       char buffer[16];
-       sprintf( buffer, "%u", Unsigned( self ) );
-       importer( buffer );
-}
-typedef ConstReferenceCaller1<std::size_t, const StringImportCallback&, Size_exportString> SizeExportStringCaller;
 
-inline void Float_importString( float& self, const char* string ){
-       if ( !string_parse_float( string, self ) ) {
-               self = 0;
-       }
-}
-typedef ReferenceCaller1<float, const char*, Float_importString> FloatImportStringCaller;
-inline void Float_exportString( const float& self, const StringImportCallback& importer ){
-       char buffer[16];
-       sprintf( buffer, "%g", self );
-       importer( buffer );
-}
-typedef ConstReferenceCaller1<float, const StringImportCallback&, Float_exportString> FloatExportStringCaller;
+    static void Import(bool &self, const char *value) {
+        self = string_equal(value, "true");
+    }
+};
 
-inline void Vector3_importString( Vector3& self, const char* string ){
-       if ( !string_parse_vector3( string, self ) ) {
-               self = Vector3( 0, 0, 0 );
+template<>
+struct PropertyImpl<int, const char *> {
+       static void Export(const int &self, const Callback<void(const char *)> &returnz) {
+               char buffer[16];
+               sprintf(buffer, "%d", self);
+               returnz(buffer);
        }
-}
-typedef ReferenceCaller1<Vector3, const char*, Vector3_importString> Vector3ImportStringCaller;
-inline void Vector3_exportString( const Vector3& self, const StringImportCallback& importer ){
-       char buffer[64];
-       sprintf( buffer, "%g %g %g", self[0], self[1], self[2] );
-       importer( buffer );
-}
-typedef ConstReferenceCaller1<Vector3, const StringImportCallback&, Vector3_exportString> Vector3ExportStringCaller;
-
 
-
-template<typename FirstArgument, typename Caller, typename FirstConversion>
-class ImportConvert1
-{
-public:
-static void thunk( void* environment, FirstArgument firstArgument ){
-       Caller::thunk( environment, FirstConversion( firstArgument ) );
-}
+    static void Import(int &self, const char *value) {
+        if (!string_parse_int(value, self)) {
+            self = 0;
+        }
+    }
 };
 
+template<>
+struct PropertyImpl<std::size_t, const char *> {
+       static void Export(const std::size_t &self, const Callback<void(const char *)> &returnz) {
+               char buffer[16];
+               sprintf(buffer, "%u", Unsigned(self));
+               returnz(buffer);
+       }
 
-class BoolFromString
-{
-bool m_value;
-public:
-BoolFromString( const char* string ){
-       Bool_importString( m_value, string );
-}
-operator bool() const
-{
-       return m_value;
-}
+    static void Import(std::size_t &self, const char *value) {
+        int i;
+        if (string_parse_int(value, i) && i >= 0) {
+            self = i;
+        } else {
+            self = 0;
+        }
+    }
 };
 
-inline void Bool_toString( const StringImportCallback& self, bool value ){
-       Bool_exportString( value, self );
-}
-typedef ConstReferenceCaller1<StringImportCallback, bool, Bool_toString> BoolToString;
-
-
-template<typename Caller>
-inline StringImportCallback makeBoolStringImportCallback( const Caller& caller ){
-       return StringImportCallback( caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type, Caller, BoolFromString>::thunk );
-}
-
-template<typename Caller>
-inline StringExportCallback makeBoolStringExportCallback( const Caller& caller ){
-       return StringExportCallback( caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type, Caller, BoolToString>::thunk );
-}
-
+template<>
+struct PropertyImpl<float, const char *> {
+       static void Export(const float &self, const Callback<void(const char *)> &returnz) {
+               char buffer[16];
+               sprintf(buffer, "%g", self);
+               returnz(buffer);
+       }
 
-class IntFromString
-{
-int m_value;
-public:
-IntFromString( const char* string ){
-       Int_importString( m_value, string );
-}
-operator int() const
-{
-       return m_value;
-}
+    static void Import(float &self, const char *value) {
+        if (!string_parse_float(value, self)) {
+            self = 0;
+        }
+    }
 };
 
-inline void Int_toString( const StringImportCallback& self, int value ){
-       Int_exportString( value, self );
-}
-typedef ConstReferenceCaller1<StringImportCallback, int, Int_toString> IntToString;
-
-
-template<typename Caller>
-inline StringImportCallback makeIntStringImportCallback( const Caller& caller ){
-       return StringImportCallback( caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type, Caller, IntFromString>::thunk );
-}
-
-template<typename Caller>
-inline StringExportCallback makeIntStringExportCallback( const Caller& caller ){
-       return StringExportCallback( caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type, Caller, IntToString>::thunk );
-}
-
-
+template<>
+struct PropertyImpl<Vector3, const char *> {
+       static void Export(const Vector3 &self, const Callback<void(const char *)> &returnz) {
+               char buffer[64];
+               sprintf(buffer, "%g %g %g", self[0], self[1], self[2]);
+               returnz(buffer);
+       }
 
-class SizeFromString
-{
-std::size_t m_value;
-public:
-SizeFromString( const char* string ){
-       Size_importString( m_value, string );
-}
-operator std::size_t() const
-{
-       return m_value;
-}
+    static void Import(Vector3 &self, const char *value) {
+        if (!string_parse_vector3(value, self)) {
+            self = Vector3(0, 0, 0);
+        }
+    }
 };
 
-inline void Size_toString( const StringImportCallback& self, std::size_t value ){
-       Size_exportString( value, self );
-}
-typedef ConstReferenceCaller1<StringImportCallback, std::size_t, Size_toString> SizeToString;
-
-
-template<typename Caller>
-inline StringImportCallback makeSizeStringImportCallback( const Caller& caller ){
-       return StringImportCallback( caller.getEnvironment(), ImportConvert1<StringImportCallback::first_argument_type, Caller, SizeFromString>::thunk );
-}
-
-template<typename Caller>
-inline StringExportCallback makeSizeStringExportCallback( const Caller& caller ){
-       return StringExportCallback( caller.getEnvironment(), ImportConvert1<StringExportCallback::first_argument_type, Caller, SizeToString>::thunk );
-}
-
 #endif