• Advertisement

Bregma

GDNet+ Basic
  • Content count

    2998
  • Joined

  • Last visited

  1. initialize std::thread

    Unless of course the compiler decides to reorder the instructions in your code, or the CPU is superscalar and performs out-of-order and/or speculative execution, and you end up using the results of your interlocked add before actually calling that instruction: a locked processor instruction does not affect that but a fence does. Then again, you're using this in a multi-threaded application, so you're going to get pre-empted right after your InterlockAdd and the value gets changed by the other thread after you've obtained it, and you're left scratching your head why things don't work, sometimes, maybe.
  2. sys/socket.h and std::thread (C__)

    listen() is a system call: it will block the thread briefly while it switches to the kernel and performs some setup operations. It gets called once (per server socket, so generally once per application) during startup, and is fairly resource-lean and fast. You call accept() to wait for connection attempts on a socket that you have previously called listen() on. The accept() call is also a system call (requires a switch to kernel mode to perform its operations, which means it steps out of the ready-thread queue and go on the IO-wait queue), and whether it performs a blocking wait on the socket or not depends on if the socket is in blocking mode or not.
  3. sys/socket.h and std::thread (C__)

    Well, yes, you could use blocking sockets and have a thread listen on the socket, accepting client connections as they come, and go back to blocking on the accept call. That's all it would do. It's a very sensible way to program sockets and easy to reason about. You could also use non-blocking sockets and use a multiplexor like select/poll/epoll/kqueue to combine all of your socket waits onto a single thread, and dispatch them via callbacks to a worker thread pool. Again, not too difficult to reason about, but targeted towards a POSIX I/O model rather than a Windows I/O model. If you're using an Windows-based system, you could use IOCP and overlapped I/O to handle everything, including dispatching commands to a thread queue if you really want.
  4. Python Interest in Python

    Yes. Python is one of the main languages that runs the internet. It is widely support. It is worthwhile to be familiar with and a joy to use to program in. The Python standard library has support for RDBMs and key-value databases. I can't recommend an IDE (because I don't recommend using an IDE) but the one that ships with Python itself is IDLE.
  5. The mechanism they introducd into C++11 to do exactly this was the template parameter pack (AKA variadic templates). Prior to that, you could use Alexandrescu's typelists or something similar. It's pretty much an academic exercise: processing a regex at compile time gives you the benefit of incredible and error-time complexity at the cost of massive code bloat. But it's nevertheless an interesting academic exercise, so carry on.
  6. Pretty much, yeah.
  7. You might consider shipping your assets using a virtual file system. There are readily available ones out there. There is nothing unprofessional about shipping your assets with your game. I've played a number of AAA games that do that.
  8. 4K is 3840 × 2160 pixels. A 24 inch monitor running at 4K is great. Two is even better. You might want to consider the most common aspect ratio of displays these days is 16:9 because that's what most TV broadcasts are, so your display media (TVs, computers, tablets, phones) tend to be made to fit that. That means 1080p and now at twice the dot-pitch, 2160p AKA 4K. Gone are the days when you'd have an old bottle monitor showing 1024x768 with 96 PPI standing in for 72.27 points over a smaller value of an inch. I think it's been over a decade since I've used one of those.
  9. I saw nothing in the original question or the OP's follow-ups saying they were looking for some kind of type ID or RTTI functionality, so all these responses saying "don't do RTTI" are a little off the mark. My understanding was they were asking for a good way to do strong ID typing because just using an int is a good way to avoid using the languages built-in mechanisms to distinguish between values of unrelated types. As I understood it, the question was not about class type IDs, but about object ID types. Not "number 3 is a door" but "door number three". The original problem was that door number 3 and goat number 3 are unrelated even though they're both number 3, and OP wanted the code to reflect that concept to prevent him from accidentally opening a goat to see if he won a car. Or something.
  10. C++ comparing 2 floats

    Is your logic backwards? You have a "boolean" you set to "true" (in C++ we actually have types and constants for that, using them can make it easier to reason about logic). You iterate through a list of values comparing them to your input value, and if at least one of the values matches, you set the "boolean" to "false" to indicate f is in the list. If that "boolean" named fexists is still "true" by the end of the loop, it indicates f does not exist. I realize it doesn't answer you question, but...
  11. Just one more suggestion. If you're using a compiler that supports the current C++ standard (and is not limited to an old superseded version of the language) you can just use a fixed enum type as your index type. #include <cstdint> enum AnimalId: std::uint32_t; enum TreeId: std::uint32_t; void f(AnimalId) { } int main() { AnimalId aid{1000}; TreeId tid{42}; // tid = aid; -- will fail to compile because the types are different f(aid); // -- OK // f(tid); -- will fail to compile because there is no valid conversion }
  12. C++ Making an UI in c++

    What does a plastic shiny wrapper around the real tools have to do with human memory, and why do you think it would speed up a team to have all that fluff and facepaint to wade through to do real work?
  13. Are there differences in terms of the efficiency of generated code? Probably not. Are there differences in terms of meaning? Definitely. You inherit to be reused. Unless you plan on using your Ids through a pointer or reference to their common base class (and it's not clear why you'd ever want to do that, since weak typing was the root of your troubles to start with), you should stay away from using inheritance and stick with the type alias. Note that instead of using struct AnimalIdTag{} you could also use an enumeration or strongly-typed enumeration (an enum or an enum class) or set of constexpr constants and a non-type template parameter. Again, it won't make any difference in terms of code efficiency, but it might be better in terms of code clarity. enum class ObjectType { Animal, Tree, }; template<ObjectType T, typename ValueType = std::uint32_t> struct IdType { ValueType value; // member functions as desired }; using AnimalId = IdType<ObjectType::Animal>;
  14. I'm afraid I can't even. Could you possibly try rephrasing what you just typed? By the way, your betweenorequal() could be simplified. #include <algorithm> template <class type, class type2> bool betweenorequal(type2 x1, type2 x2, type x0) { return std::min(x1, x2) <= x0 && x0 <= std::max(x1, x2); }
  15. C++ buffer or vector issue

    Well, I'd assume the bug is that you're changing the loop index "it" inside the loop. Can you really reason correctly about the loop invariant if the loop invariant changes in the middle of the loop? You can see the effects of calling std::vector::erase here. Pay special attention to the bit that says Invalidates iterators and references at or after the point of the erase, including the end() iterator.
  • Advertisement