Re: Anti-Jammer-Thread
Verfasst: 15.11.2012, 17:22
Es nutzt Assimp :-)
Die deutsche Spieleentwickler-Community (seit 1999).
https://zfx.info/
Code: Alles auswählen
#ifdef __MEMORY_MANAGER
#define DEFINITION_ALLOCATE(...) \
{ \
Ftype* p = reinterpret_cast<Ftype*>(MALLOC(sizeof(Ftype))); \
new(p) Ftype(__VA_ARGS__); \
return p; \
}
#define DEFINITION_ALLOCATE_ARRAY(count, ...) \
{ \
size_t* pRaw = reinterpret_cast<size_t*>(MALLOC(sizeof(Ftype)*count+sizeof(size_t))); \
*pRaw = count; \
Ftype* p = reinterpret_cast<Ftype*>(pRaw+1); \
for(size_t i=0; i<count; ++i) \
new(p+i) Ftype(__VA_ARGS__); \
return p; \
}
template<typename Ftype > Ftype* allocate(void) DEFINITION_ALLOCATE()
template<typename Ftype, typename P1> Ftype* allocate(P1 p1) DEFINITION_ALLOCATE(p1)
template<typename Ftype, typename P1, typename P2> Ftype* allocate(P1 p1, P2 p2) DEFINITION_ALLOCATE(p1, p2)
template<typename Ftype, typename P1, typename P2, typename P3> Ftype* allocate(P1 p1, P2 p2, P3 p3) DEFINITION_ALLOCATE(p1, p2, p3)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4) DEFINITION_ALLOCATE(p1, p2, p3, p4)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8, p9)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
template<typename Ftype > Ftype* allocateArray(size_t count) DEFINITION_ALLOCATE_ARRAY(count)
template<typename Ftype, typename P1> Ftype* allocateArray(size_t count, P1 p1) DEFINITION_ALLOCATE_ARRAY(count, p1)
template<typename Ftype, typename P1, typename P2> Ftype* allocateArray(size_t count, P1 p1, P2 p2) DEFINITION_ALLOCATE_ARRAY(count, p1, p2)
template<typename Ftype, typename P1, typename P2, typename P3> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8, p9)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
template<typename Ftype>
void deallocate(const Ftype* p)
{
if(!p)
return;
p->~Ftype();
FREE(const_cast<Ftype*>(p));
}
template<typename Ftype>
void deallocateArray(const Ftype* p)
{
if(!p)
return;
size_t* pRaw = (reinterpret_cast<size_t*>(const_cast<Ftype*>(p))-1);
for(size_t i=*pRaw; i-->0;)
p[i].~Ftype();
FREE(pRaw);
}
#endif
Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
Nein, hier müsste er die Exception in keinem Fall behandeln (er nutzt den Standard-new-Operator nicht mal, aber selbst wenn). Relevant ist hier, ob Konstruktoren Exceptions werfen können. In diesem Fall müsste der Speicher bei Exception nach Zerstörung aller bereits erfolgreich konstruierten Objekte wieder manuell freigegeben werden.eXile hat geschrieben:Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
Stimmt, das ist ja Placement-new, und das ist nothrow.CodingCat hat geschrieben:Nein, hier müsste er die Exception in keinem Fall behandeln (er nutzt den Standard-new-Operator nicht mal, aber selbst wenn).
Auch da hast du recht. Man man man; ich hätte einfach obigen Post nicht schreiben sollen. :oops:CodingCat hat geschrieben:Relevant ist hier, ob Konstruktoren Exceptions werfen können. In diesem Fall müsste der Speicher bei Exception nach Zerstörung aller bereits erfolgreich konstruierten Objekte wieder manuell freigegeben werden.
Stimmt, da muss ich noch konstante Referenzen draus machen. Danke für den Hinweis. Komplett vergessen.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln. Davon abgesehen solltest du dir darüber im Klaren sein, dass all deine Konstruktorargumente rein semantisch kopiert werden. Tatsächlich kann der Compiler unter bestimmten Voraussetzungen Copy Elision durchführen, mit Sicherheit keine Kopien bekommst du jedoch nur mit const P1 &p1 ....
Code: Alles auswählen
template <class Type, class Owner>
class handle
{
friend Owner;
public:
/// Type of the value stored.
typedef Type value_type;
/// Type of the owner.
typedef Owner owner_type;
protected:
/// Value stored.
value_type value;
/// Constructs a handle from the given value.
explicit handle(const value_type &value)
: value(value) { }
/// Gets the value stored by this handle.
const value_type& get() const { return this->value; }
/// Gets the value stored by this handle.
operator value_type() const { return this->value; }
};
Code: Alles auswählen
class Foo
{
void method(...) __restrict { ... }
};
Krishty hat geschrieben:Eine Ergänzung zu __restrict auf Seite 76: Bei Visual C++ hat es keine Auswirkung mehr, weil LTCG Aliasing mittlerweile sehr gut ausschließen kann; selber dekorieren lohnt nicht mehr.
Auf x64 im Release kompilieren oder nie geschehen.Krishty hat geschrieben:Der Grund, dass ich nie einen Unterschied sehe, ist also x64.
Abstimmen Kinners! Abstimmen!EnC Survey hat geschrieben:64-bit Native EnC: (Currently Native EnC is only supported on x86-32 bit platform, this choice is about extending support for Native EnC to x64)
Echt lustige Sachen in dem Survey. Die meisten Fragen suggerieren, dass sie längst wissen, was wir wollen (z.B. IntelliSense während des Debuggens); aber uns nochmal extra durch die Ringe hüpfen lassen, damit sie harte Zahlen dafür vorlegen können.Currently you cannot debug files with more than 64K lines. We cannot set breakpoints on line numbers greater than that.
Krishty hat geschrieben:Auf dem Papier hört sich mein Leben echt jämmerlich an … aber dann lese ich sowas:Currently you cannot debug files with more than 64K lines. We cannot set breakpoints on line numbers greater than that.
Genau das habe ich mir auch gedacht, als ich das gelesen habe. Ich sehe es schon kommen: In Visual Studio 2014 gibt es Edit and Continue, dann steht da so ein fettes Sternchen daneben und da drunter steht etwas in der Art wie: Sie dürfen nur Kommentare und Leerzeichen einfügen. Viel Spaß!Krishty hat geschrieben:Einige Features sind auch einfach lächerlich. Wie wichtig ist mir, dass ich meinen Quelltext in EnC kommentieren kann? Seid ihr völlig bescheuert?! Wenn sich die Semantik nicht ändert, hat das intrinsisch zu funktionieren. Wie kaputt muss eine Implementierung sein, dass das nicht geht?!
Code: Alles auswählen
// Vorher
entities.get<reflected>()[idx]...
entities.get<transformation>()[idx]...
// Nachher
entities(reflected)[idx]...
entities(transformation)[idx]...
// Wie?
enum registry_tag { registry };
enum reflected_tag { reflected };
enum transformation_tag { transformation };
...
typedef multi_vector_t<>::make<
Registry, registry_tag,
Entity*, reflected_tag,
Transformation, transformation_tag,
...
>::type entities_t;
// In multi_vector
using Base::operator (); // Rekursive Dekomposition mittels private-Vererbungshierarchie
vector_type& operator ()(Tag) { return v; } // Füge Overloads für Tag der aktuellen Hierarchieebene hinzu
const vector_type& operator ()(Tag) const { return v; }
Bezieht sich das jetzt nur auf die Lesbarkeit der Fehlermeldung, oder werden dadurch tatsächlich weitere Fehlerfälle erkannt? Ich kann mir nämlich gerade kein Beispiel denken, in dem das mehr Fehlerfälle erkennt als in der Template-Variante.CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
Ja, das bezieht sich natürlich auf die Fehlermeldung. In Bezug auf Korrektheit gibt es keine Unterschiede. Der große Unterschied ist, dass Spezialisierungen nicht einfach so über Klassengrenzen hinweg funktionieren, weshalb im Falle von Spezialisierungen unzählige "rekursive" Hilfsaufrufe notwendig werden, was sich im Fehlerfall am Ende in kilometerlangen Template-Instanziierungs-Traces äußert. Damit verbunden wäre im Übrigen auch großes Chaos beim Debuggen, sofern man den Debugger nicht dazu angewiesen bekommt, entsprechende Hilfsaufrufe zu überspringen. Mit Overload Resolution und Namensimport mittels using hat man hingegen überall nur einen einfachen Funktionsaufruf, was die Sache enorm verbessert, bezüglich Debug-Code-Generierung, Debugger-Tauglichkeit und Compiler-Fehlerverhalten. Sogar IntelliSense liefert dann brauchbare Information.eXile hat geschrieben:Bezieht sich das jetzt nur auf die Lesbarkeit der Fehlermeldung, oder werden dadurch tatsächlich weitere Fehlerfälle erkannt? Ich kann mir nämlich gerade kein Beispiel denken, in dem das mehr Fehlerfälle erkennt als in der Template-Variante.CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
Code: Alles auswählen
struct RAIIFoo
{
Resource resource;
// Normaler RAII-Code
RAIIFoo(...)
: resource(...) {}
~RAIIFoo()
{
if (resource != invalid)
free(resource);
}
// Container erfordern Default Construction und Copy Construction
RAIIFoo()
: resource(invalid) {}
RAIIFoo(const RAIIFoo &right)
: resource(invalid)
{
// Stelle sicher, dass keine initialisierten Objekte kopiert und so
// Ressourcen durch mehrere Objekte gleichzeitig verwaltet werden
assert(right.resource == invalid);
}
void swap(RAIIFoo &right)
{
std::swap(resource, right.resource);
}
};
std::list<RAIIFoo> list;
// Konstruiere RAII-Objekt
RAIIFoo foo(...);
// Verschiebe per Swap in Liste
list.push_back(RAIIFoo());
list.back().swap(foo);
Code: Alles auswählen
struct RAIIFoo
{
Resource resource;
RAIIFoo(...)
: resource(...) {}
RAIIFoo(RAIIFoo &&right)
: resource(right.resource)
{
right.resource = invalid;
}
~RAIIFoo()
{
if (resource != invalid)
free(resource);
}
};
std::list<RAIIFoo> list;
// Konstruiere RAII-Objekt "in" Liste
list.push_back(RAIIFoo(...));
// ... oder konstruiere erste und verschiebe dann
RAIIFoo foo(...);
list.push_back(std::move(foo));
// Achtung: foo genau wie nach swap ab hier ungültig