Jump to content
  • Advertisement

Ricky C.

  • Content Count

  • Joined

  • Last visited

Community Reputation

132 Neutral

About Ricky C.

  • Rank
  1. I'd been tracking a bug in our game engine when I suddenly realized that all my old tests had inverted. Has this method changed what it returns for non-zero values passed to the first parameter? I've not changed AS versions since my last test, so either I mis-observed or mis-documented, however unlikely. Whatever's the case there's something odd here - and none of it fits what I expect. Previously I was tracking that I was getting the line number of the executable line one previous to where I expected when passing a value of 1. Now I'm getting the line number of the executable line after what I expect. I'm using AS 2.23.1 currently. I do not rem I know, I do need to upgrade... Will likely catch it in 2.24.1 as working on a mess of other things at the moment - and 2.24.1 will likely contain the Xcode/Clang fixes I'm currently patching in manually. Here's what I'm doing in C++: std::string GetPreviousCallstackLine(const unsigned int& callstack_line_number) { asIScriptContext* ctx = asGetActiveContext(); std::string result; if (ctx != nullptr && callstack_line_number < ctx->GetCallstackSize()) { asIScriptFunction* func; const char* script_section; int line, column; func = ctx->GetFunction(callstack_line_number); line = ctx->GetLineNumber(callstack_line_number, &column, &script_section); result = std::string(script_section) + "(" + boost::lexical_cast<std::string>(line) + "):" + std::string(func->GetDeclaration()); } return result; } // ... over in registration ret = this->engine->SetDefaultNamespace("Engine::Debug"); assert(ret >= 0); ret = this->engine->RegisterGlobalFunction("string GetPreviousCallstackLine(const uint &in a = 1)", asFUNCTION(GetPreviousCallstackLine), asCALL_CDECL); assert(ret >= 0); // ... And my use in AS is as such: namespace UnitTest { // ... void EXPECT_TRUE (const bool&in a, string message = "") { if (!a) { Engine::LOG(Engine::LOG_PRIORITY::ERR, "EXPECT_TRUE failed in " + Engine::Debug::GetPreviousCallstackLine() + "! " + message); gTestStatus = false; } } // ... This I will line number with arbitrary numbers for our reference: 100: EXPECT_TRUE(true); 101: 102: EXPECT_TRUE(false); 103: // Just another blank line 104: EXPECT_TRUE(true); 105: 107: EXPECT_TRUE(false); I expect to have a message in my logger stating a line number of 102 for the first invalid test. In the past I instead got line 100, line 101 being skipped because it is blank. Currently I get line 104. Now, this is a trivial example, but it demonstrates what I've observed from the output of many variations. EXPECT_EQ, EXPECT_NE, and many other such functions all exhibit the same behavior, and it matter not what the previous or next executable line is: they could be a simple 0 + 0 and the system would show the same oddity. Of course if I set the passed value to 0, the reported line is the line where Engine::Debug::GetPreviousCallstackLine() is called - as expected. If I set it to 2 it currently reports the line of execution one step even further in the future - though I thought the past would be a lot more defined. -- EDIT -- GetPreviousCallstackLine(const uint &in a = 1) was GetPreviousCallstackLine(const uint &in a = 2) The actual value used in my tests was 1, the 2 was spurious, coming from me exploring the system.
  2. I'm not 100% about the underlying cause. I did note that the std::basic_string::empty() method was marked for inlining, and I hypothesized off that. Beyond there.... All I'm 100% certain of is that providing wrapper functions cleared out the error. Someone with a far more extensive knowledge of the subject could dig deeper.
  3. I (finally) got our entire engine to compile - see more about the epic saga in my blog post Adventures in compiling for Mac OSX. However to do so, I had to patch one add-on. Turns out that under clang/LLVM, when using the libc++ standard library, the operator+= and empty() methods of std::basic_string are inlined. This causes the linker to be unable to find the declarations the add-on is attempting to register - they don't exist. After digging around, I was able to create the attached patch. This has allowed for compilation on my systems: OSX 10.7 and 10.8 using XCode 4.3 and 4.4 respectively. I have not yet tested execution, as there's still many yards of code for me to write to get there.
  4. Ricky C.

    OSX, Clang++, and getcwd

    I've been working on getting the NLS Engine compiling and running under Mac OSX. After upgrading to Xcode 4.3, and configuring the project to use clang++ 3.1 as I found that Apple still hasn't upgraded g++ past 4.2, and we need the C++11 support, I found that there was a little problem hiding in the scriptbuilder add-on. Everything was going well until scriptbuilder.cpp threw a compilation error: down on line 866 it complained that getcwd was an undeclared identifier. The fix was to just make sure that unistd.h was #included: @@ -11,5 +11,5 #endif -#if defined(AS_MARMALADE) +#if defined(AS_MARMALADE) || defined(__APPLE__) #include <unistd.h> #endif
  5. Ricky C.

    C99 Hexfloats

    Very true! I was so caught up in the workaround, and in thinking about it as shorthand for pow(2, N), that I missed that. Thanks!
  6. Ricky C.

    C99 Hexfloats

    Back in August paphi made a couple of suggestions, including one I just attempted to use - and then went looking in the docs, WIP, and unplanned items, when it only almost worked. That suggestion was C99 hexfloats. These are one of the nicest ways to encode a floating point literal that is not really accurately expressible in decimal. Andreas, approximately when (a version; patches welcome as I don't have time; I don't want in the language) would this be potentially available? What I got when I attempted was rather interesting however, and could be perceived as a bug: float x = 0x219AEFp-24; // X gets the value 2202351.0f, which is hex 0x219AEF. The data from the p to the ; was ignored! I worked around it by simply doing the conversion myself: float x = float(0x219AEF) / (2 << 23); // Don't forget to decrement the exponent when converting!
  7. I'm not sure about _Vicious_'s fix, but I expect so. It sounds the same. I know it's fresh. The inclusion of namespaces is why I upgraded AS in our engine - it was of more worth to me than most of the bug fixes. Understandable about the searching - so long as that is documented. http://www.angelcode.com/angelscript/sdk/docs/manual/doc_global.html#doc_global_namespace doesn't currently mention this situation, leading to the expectation of C++-esque functionality. I'd recommend, and I know I'm not in a place to say anything about your project's direction, that in the current situation blocking access to the objects in the global scope (2.23.1's current functionality) by default, but then allowing access through the explicit use of the global scope resolution operation "::MyFunction()" would make the system self-consistent. The global scope operator is documented here for our convenience: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html#scope Thank you very much for an amazing tool.
  8. Just saw "Accessing entitites in global scope from a function in a namespace didn't work (Thanks _Vicious_)" d'oh...
  9. Pretty clear with code: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void GlobalFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ namespace MyNamespace { void NamespacedFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); GlobalFunction(); // No matching signatures to 'GlobalFunction()' ::GlobalFunction(); // No matching signatures to '::GlobalFunction()' } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { GlobalFunction(); MyNamespace::NamespacedFunction(); } I first noted this problem when attempting to use sqrt (from the scriptmath addon) from within a namespaced function. I worked around it by registering scriptmath inside a "Math" namespace, but that's hardly ideal. To me all functions in a parent namespace, unless masked by another function in a closer relation, such as the same namespace, should be accessible in all children namespaces. If a function is masked, it should be accessible with the right use of scope resolution. Which leads me to: the global scope operator doesn't play with namespaces. This could make situations like the below rather interesting... void MyFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } namespace MyNamespace { void MyFunction() { Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called."); } void NamespacedFunction() { MyFunction(); // Which function is this referencing? I assume it's the one in the current namespace! ::MyFunction(); // Which implies that this should be the syntax to access the one in the global namespace... } } I understand the global scope operator is currently designed to access global variables, as in: // From http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html int value; void function() { int value; // local variable overloads the global variable ::value = value; // use scope resolution operator to refer to the global variable } However, as it is also the namespace resolution operator I was expecting it to work for accessing the global namespace as well...
  10. Ricky C.

    Enum collision across namespaces

    Thanks Andreas! I've not tested, but it might be good to verify that typedefs get namespaced as well. Currently they are of limited use, but hopefully...
  11. Ricky C.

    Enum collision across namespaces

    I've never been a fan of C++'s preference to slam enum values into the global namespace, thus I use namespaces in my C++ code to limit that progression. So it was with delight that I upgraded my AS as soon as I found out that namespaces had come. However I just found a problem. Here's some C++-based pseudocode giving an example of what I do: // Create a namespaced enumeration namespace MY_ENUM { enum TYPE { VALUE_A, VALUE_B, } } // And another namespace ANOTHER_ENUM { enum TYPE { VALUE_A, VALUE_B, } } // Example usage of the types ANOTHER_ENUM::TYPE MyFunction(MY_ENUM::TYPE); // Example usage of the values if (MyFunction(MY_ENUM::VALUE_B) == ANOTHER_ENUM::VALUE_A) { ... } Now, to do the same thing in AS when I'm registering my interface: asIScriptEngine* as_engine = ....; // Go get the current pointer. int ret = 0; ret = as_engine->SetDefaultNamespace("MY_ENUM"); assert(ret >= 0); ret = as_engine->RegisterEnum("TYPE"); assert(ret >= 0); ret = as_engine->RegisterEnumValue("TYPE", "VALUE_A", 0); assert(ret >= 0); ret = as_engine->RegisterEnumValue("TYPE", "VALUE_B", 0); assert(ret >= 0); ret = as_engine->SetDefaultNamespace("ANOTHER_ENUM"); assert(ret >= 0); ret = as_engine->RegisterEnum("TYPE"); assert(ret >= 0); ret = as_engine->RegisterEnumValue("TYPE", "VALUE_A", 0); assert(ret >= 0); ret = as_engine->RegisterEnumValue("TYPE", "VALUE_B", 0); assert(ret >= 0); // Clean up the namespace ret = as_engine->SetDefaultNamespace(""); assert(ret >= 0); What was my surprise when the second RegisterEnum("TYPE") caused the assert to fail and the following message to be placed in my AS log: Failed in call to function 'RegisterEnum' with 'TYPE' Since both example enums are supposed to be in separate namespaces, they shouldn't have any collisions... Global properties and functions have no such issue: float e = 2.71828183f; float p = 3.14159265f; ret = as_engine->SetDefaultNamespace("WONDER"); assert(ret >= 0); ret = as_engine->RegisterGlobalProperty("float Flubber", &e); assert(ret >= 0); ret = as_engine->RegisterGlobalFunction("void function()", asFUNCTION(funcA), asCALL_CDECL); assert(ret >= 0); ret = as_engine->SetDefaultNamespace("AMUSEMENT"); assert(ret >= 0); ret = as_engine->RegisterGlobalProperty("float Flubber", &p); assert(ret >= 0); ret = as_engine->RegisterGlobalFunction("void function()", asFUNCTION(funcB), asCALL_CDECL); assert(ret >= 0); -- After hacking my registration to get it operable I found myself playing hide-and-seek with my enum values. For some reason I found my enum value hiding at MY_ENUM::TYPE::VALUE_A instead of where I expected, based on how C++ operates, at MY_ENUM::VALUE_A. This is a good thing, and quite a nice change, but it's almost entirely unlike C++.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!