As latest SDL was found to be non-threadsafe in practice, removed the StaticMutex and the OBJECTTYPESTATIC constructs which were added to support multi-context use within a single process.
Fixed single SDL memory leak on exit.
This commit is contained in:
Родитель
e1a05e621c
Коммит
ad7b7451b4
|
@ -346,8 +346,6 @@ Urho3D uses the following conventions and principles:
|
|||
|
||||
- Feeding illegal data to public API functions, such as out of bounds indices or null pointers, should not cause crashes or corruption. Instead errors are logged as appropriate.
|
||||
|
||||
- For threading and multi-instance safety, no mutable static data (including singletons) or function-static data is allowed.
|
||||
|
||||
- Third party libraries are included as source code for the build process. They are however hidden from the public API as completely as possible.
|
||||
|
||||
For more details related to the C++ coding style, see also \ref CodingConventions "Coding conventions".
|
||||
|
|
|
@ -29,8 +29,6 @@ Classes that derive from Object contain type-identification, they can be created
|
|||
|
||||
The definition of an Object subclass must contain the OBJECT(className) macro. Type identification is available both as text (GetTypeName() or GetTypeNameStatic()) and as a 16-bit hash of the type name (GetType() or GetTypeStatic()).
|
||||
|
||||
In addition the OBJECTTYPESTATIC(className) macro must appear in a .cpp file to actually define the type identification data. The reason for this instead of defining the data directly inside the OBJECT macro as function-static data is thread safety: function-static data is initialized on the first use, and if the first call to an object's GetTypeStatic() or GetTypeNameStatic() happened on several threads simultaneously, the results would be undefined.
|
||||
|
||||
To register an object factory for a specific type, call the \ref Context::RegisterFactory "RegisterFactory()" template function on Context. You can get its pointer from any Object either via the \ref Object::context_ "context_" member variable, or by calling \ref Object::GetContext "GetContext()". An example:
|
||||
|
||||
\code
|
||||
|
|
|
@ -47,8 +47,6 @@ static const int MAX_MIXRATE = 48000;
|
|||
|
||||
static void SDLAudioCallback(void *userdata, Uint8 *stream, int len);
|
||||
|
||||
OBJECTTYPESTATIC(Audio);
|
||||
|
||||
Audio::Audio(Context* context) :
|
||||
Object(context),
|
||||
deviceID_(0),
|
||||
|
@ -99,23 +97,19 @@ bool Audio::SetMode(int bufferLengthMSec, int mixRate, bool stereo, bool interpo
|
|||
desired.callback = SDLAudioCallback;
|
||||
desired.userdata = this;
|
||||
|
||||
deviceID_ = SDL_OpenAudioDevice(0, SDL_FALSE, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
if (!deviceID_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
deviceID_ = SDL_OpenAudioDevice(0, SDL_FALSE, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
if (!deviceID_)
|
||||
{
|
||||
LOGERROR("Could not initialize audio output");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obtained.format != AUDIO_S16SYS && obtained.format != AUDIO_S16LSB && obtained.format != AUDIO_S16MSB)
|
||||
{
|
||||
LOGERROR("Could not initialize audio output, 16-bit buffer format not supported");
|
||||
SDL_CloseAudioDevice(deviceID_);
|
||||
deviceID_ = 0;
|
||||
return false;
|
||||
}
|
||||
LOGERROR("Could not initialize audio output");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obtained.format != AUDIO_S16SYS && obtained.format != AUDIO_S16LSB && obtained.format != AUDIO_S16MSB)
|
||||
{
|
||||
LOGERROR("Could not initialize audio output, 16-bit buffer format not supported");
|
||||
SDL_CloseAudioDevice(deviceID_);
|
||||
deviceID_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
stereo_ = obtained.channels == 2;
|
||||
|
@ -270,8 +264,6 @@ void Audio::Release()
|
|||
|
||||
if (deviceID_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_CloseAudioDevice(deviceID_);
|
||||
deviceID_ = 0;
|
||||
clipBuffer_.Reset();
|
||||
|
|
|
@ -57,8 +57,6 @@ struct WavHeader
|
|||
|
||||
static const unsigned IP_SAFETY = 4;
|
||||
|
||||
OBJECTTYPESTATIC(Sound);
|
||||
|
||||
Sound::Sound(Context* context) :
|
||||
Resource(context),
|
||||
repeat_(0),
|
||||
|
|
|
@ -31,8 +31,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* AUDIO_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(SoundListener);
|
||||
|
||||
SoundListener::SoundListener(Context* context) :
|
||||
Component(context)
|
||||
{
|
||||
|
|
|
@ -103,8 +103,6 @@ static const float AUTOREMOVE_DELAY = 0.25f;
|
|||
|
||||
extern const char* AUDIO_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(SoundSource);
|
||||
|
||||
SoundSource::SoundSource(Context* context) :
|
||||
Component(context),
|
||||
soundType_(SOUND_EFFECT),
|
||||
|
|
|
@ -40,8 +40,6 @@ static const float MIN_ROLLOFF = 0.1f;
|
|||
|
||||
extern const char* AUDIO_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(SoundSource3D);
|
||||
|
||||
SoundSource3D::SoundSource3D(Context* context) :
|
||||
SoundSource(context),
|
||||
nearDistance_(DEFAULT_NEARDISTANCE),
|
||||
|
|
|
@ -242,18 +242,11 @@ private:
|
|||
};
|
||||
|
||||
#define OBJECT(typeName) \
|
||||
private: \
|
||||
static const ShortStringHash typeStatic; \
|
||||
static const String typeNameStatic; \
|
||||
public: \
|
||||
virtual ShortStringHash GetType() const { return GetTypeStatic(); } \
|
||||
virtual const String& GetTypeName() const { return GetTypeNameStatic(); } \
|
||||
static ShortStringHash GetTypeStatic() { return typeStatic; } \
|
||||
static const String& GetTypeNameStatic() { return typeNameStatic; } \
|
||||
|
||||
#define OBJECTTYPESTATIC(typeName) \
|
||||
const ShortStringHash typeName::typeStatic(#typeName); \
|
||||
const String typeName::typeNameStatic(#typeName); \
|
||||
static ShortStringHash GetTypeStatic() { static const ShortStringHash typeStatic(#typeName); return typeStatic; } \
|
||||
static const String& GetTypeNameStatic() { static const String typeNameStatic(#typeName); return typeNameStatic; } \
|
||||
|
||||
#define EVENT(eventID, eventName) static const StringHash eventID(#eventName); namespace eventName
|
||||
#define PARAM(paramID, paramName) static const ShortStringHash paramID(#paramName)
|
||||
|
|
|
@ -83,7 +83,6 @@ static bool consoleOpened = false;
|
|||
#endif
|
||||
static String currentLine;
|
||||
static Vector<String> arguments;
|
||||
static Mutex staticMutex;
|
||||
|
||||
#if defined(IOS)
|
||||
void GetCPUData(host_basic_info_data_t* data)
|
||||
|
@ -392,9 +391,4 @@ unsigned GetNumLogicalCPUs()
|
|||
#endif
|
||||
}
|
||||
|
||||
Mutex& GetStaticMutex()
|
||||
{
|
||||
return staticMutex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,7 +65,5 @@ String GetPlatform();
|
|||
unsigned GetNumPhysicalCPUs();
|
||||
/// Return the number of logical CPUs (different from physical if hyperthreading is used.)
|
||||
unsigned GetNumLogicalCPUs();
|
||||
/// Return the static library init/shutdown mutex.
|
||||
Mutex& GetStaticMutex();
|
||||
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@ namespace Urho3D
|
|||
static const int LINE_MAX_LENGTH = 256;
|
||||
static const int NAME_MAX_LENGTH = 30;
|
||||
|
||||
OBJECTTYPESTATIC(Profiler);
|
||||
|
||||
Profiler::Profiler(Context* context) :
|
||||
Object(context),
|
||||
current_(0),
|
||||
|
|
|
@ -43,8 +43,6 @@ namespace Urho3D
|
|||
bool HiresTimer::supported(false);
|
||||
long long HiresTimer::frequency(1000);
|
||||
|
||||
OBJECTTYPESTATIC(Time);
|
||||
|
||||
Time::Time(Context* context) :
|
||||
Object(context),
|
||||
frameNumber_(0),
|
||||
|
|
|
@ -62,8 +62,6 @@ private:
|
|||
unsigned index_;
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(WorkQueue);
|
||||
|
||||
WorkQueue::WorkQueue(Context* context) :
|
||||
Object(context),
|
||||
shutDown_(false),
|
||||
|
|
|
@ -44,8 +44,6 @@ namespace Urho3D
|
|||
static const int DEFAULT_CONSOLE_ROWS = 16;
|
||||
static const int DEFAULT_HISTORY_SIZE = 16;
|
||||
|
||||
OBJECTTYPESTATIC(Console);
|
||||
|
||||
Console::Console(Context* context) :
|
||||
Object(context),
|
||||
historyRows_(DEFAULT_HISTORY_SIZE),
|
||||
|
|
|
@ -52,8 +52,6 @@ static const char* shadowQualityTexts[] =
|
|||
"24bit High"
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(DebugHud);
|
||||
|
||||
DebugHud::DebugHud(Context* context) :
|
||||
Object(context),
|
||||
profilerMaxDepth_(M_MAX_UNSIGNED),
|
||||
|
|
|
@ -71,8 +71,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* logLevelPrefixes[];
|
||||
|
||||
OBJECTTYPESTATIC(Engine);
|
||||
|
||||
Engine::Engine(Context* context) :
|
||||
Object(context),
|
||||
timeStep_(0.0f),
|
||||
|
|
|
@ -56,8 +56,6 @@ static bool CompareAnimationOrder(const SharedPtr<AnimationState>& lhs, const Sh
|
|||
|
||||
static const unsigned MAX_ANIMATION_STATES = 256;
|
||||
|
||||
OBJECTTYPESTATIC(AnimatedModel);
|
||||
|
||||
AnimatedModel::AnimatedModel(Context* context) :
|
||||
StaticModel(context),
|
||||
animationLodFrameNumber_(0),
|
||||
|
|
|
@ -58,8 +58,6 @@ void AnimationTrack::GetKeyFrameIndex(float time, unsigned& index) const
|
|||
++index;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Animation);
|
||||
|
||||
Animation::Animation(Context* context) :
|
||||
Resource(context),
|
||||
length_(0.f)
|
||||
|
|
|
@ -48,8 +48,6 @@ static const float COMMAND_STAY_TIME = 0.25f;
|
|||
|
||||
extern const char* LOGIC_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(AnimationController);
|
||||
|
||||
AnimationController::AnimationController(Context* context) :
|
||||
Component(context)
|
||||
{
|
||||
|
|
|
@ -50,8 +50,6 @@ inline bool CompareBillboards(Billboard* lhs, Billboard* rhs)
|
|||
return lhs->sortDistance_ > rhs->sortDistance_;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(BillboardSet);
|
||||
|
||||
BillboardSet::BillboardSet(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
animationLodBias_(1.0f),
|
||||
|
|
|
@ -53,8 +53,6 @@ static const Matrix4 flipMatrix(
|
|||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
OBJECTTYPESTATIC(Camera);
|
||||
|
||||
Camera::Camera(Context* context) :
|
||||
Component(context),
|
||||
viewDirty_(true),
|
||||
|
|
|
@ -44,8 +44,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(CustomGeometry);
|
||||
|
||||
CustomGeometry::CustomGeometry(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
vertexBuffer_(new VertexBuffer(context)),
|
||||
|
|
|
@ -46,8 +46,6 @@ extern const char* SUBSYSTEM_CATEGORY;
|
|||
// Cap the amount of lines to prevent crash when eg. debug rendering large heightfields
|
||||
static const unsigned MAX_LINES = 1000000;
|
||||
|
||||
OBJECTTYPESTATIC(DebugRenderer);
|
||||
|
||||
DebugRenderer::DebugRenderer(Context* context) :
|
||||
Component(context)
|
||||
{
|
||||
|
|
|
@ -148,8 +148,6 @@ void Decal::CalculateBoundingBox()
|
|||
boundingBox_.Merge(vertices_[i].position_);
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(DecalSet);
|
||||
|
||||
DecalSet::DecalSet(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
geometry_(new Geometry(context)),
|
||||
|
|
|
@ -163,12 +163,8 @@ static unsigned GetD3DColor(const Color& color)
|
|||
return (((a) & 0xff) << 24) | (((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff);
|
||||
}
|
||||
|
||||
static unsigned numInstances = 0;
|
||||
|
||||
static unsigned depthStencilFormat = D3DFMT_D24S8;
|
||||
|
||||
OBJECTTYPESTATIC(Graphics);
|
||||
|
||||
Graphics::Graphics(Context* context) :
|
||||
Object(context),
|
||||
impl_(new GraphicsImpl()),
|
||||
|
@ -199,15 +195,8 @@ Graphics::Graphics(Context* context) :
|
|||
{
|
||||
SetTextureUnitMappings();
|
||||
|
||||
// If first instance in this process, initialize SDL under static mutex. Note that Graphics subsystem will also be in charge
|
||||
// of shutting down SDL as a whole, so it should be the last SDL-using subsystem (Audio and Input also use SDL) alive
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
if (!numInstances)
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
|
||||
++numInstances;
|
||||
}
|
||||
// Initialize SDL now. Graphics should be the first SDL-using subsystem to be created
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
|
||||
|
||||
// Register Graphics library object factories
|
||||
RegisterGraphicsLibrary(context_);
|
||||
|
@ -244,8 +233,6 @@ Graphics::~Graphics()
|
|||
}
|
||||
if (impl_->window_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_ShowCursor(SDL_TRUE);
|
||||
SDL_DestroyWindow(impl_->window_);
|
||||
impl_->window_ = 0;
|
||||
|
@ -254,14 +241,8 @@ Graphics::~Graphics()
|
|||
delete impl_;
|
||||
impl_ = 0;
|
||||
|
||||
// If last instance in this process, shut down SDL under static mutex
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
--numInstances;
|
||||
if (!numInstances)
|
||||
SDL_Quit();
|
||||
}
|
||||
// Shut down SDL now. Graphics should be the last SDL-using subsystem to be destroyed
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void Graphics::SetExternalWindow(void* window)
|
||||
|
@ -463,8 +444,6 @@ void Graphics::Close()
|
|||
{
|
||||
if (impl_->window_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_ShowCursor(SDL_TRUE);
|
||||
SDL_DestroyWindow(impl_->window_);
|
||||
impl_->window_ = 0;
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(IndexBuffer);
|
||||
|
||||
IndexBuffer::IndexBuffer(Context* context) :
|
||||
Object(context),
|
||||
GPUObject(GetSubsystem<Graphics>()),
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Shader);
|
||||
|
||||
Shader::Shader(Context* context) :
|
||||
Resource(context),
|
||||
sourceModifiedTime_(0)
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Texture2D);
|
||||
|
||||
Texture2D::Texture2D(Context* context) :
|
||||
Texture(context)
|
||||
{
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(TextureCube);
|
||||
|
||||
TextureCube::TextureCube(Context* context) :
|
||||
Texture(context),
|
||||
lockedLevel_(-1)
|
||||
|
|
|
@ -48,8 +48,6 @@ const unsigned VertexBuffer::elementSize[] =
|
|||
4 * sizeof(float) // Instancematrix3
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(VertexBuffer);
|
||||
|
||||
VertexBuffer::VertexBuffer(Context* context) :
|
||||
Object(context),
|
||||
GPUObject(GetSubsystem<Graphics>()),
|
||||
|
|
|
@ -54,8 +54,6 @@ SourceBatch::~SourceBatch()
|
|||
{
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Drawable);
|
||||
|
||||
Drawable::Drawable(Context* context, unsigned char drawableFlags) :
|
||||
Component(context),
|
||||
drawableFlags_(drawableFlags),
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Geometry);
|
||||
|
||||
Geometry::Geometry(Context* context) :
|
||||
Object(context),
|
||||
primitiveType_(TRIANGLE_LIST),
|
||||
|
|
|
@ -84,8 +84,6 @@ template<> LightType Variant::Get<LightType>() const
|
|||
return (LightType)GetInt();
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Light);
|
||||
|
||||
Light::Light(Context* context) :
|
||||
Drawable(context, DRAWABLE_LIGHT),
|
||||
lightType_(DEFAULT_LIGHTTYPE),
|
||||
|
|
|
@ -101,8 +101,6 @@ TechniqueEntry::~TechniqueEntry()
|
|||
{
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Material);
|
||||
|
||||
Material::Material(Context* context) :
|
||||
Resource(context),
|
||||
auxViewFrameNumber_(0),
|
||||
|
|
|
@ -59,8 +59,6 @@ unsigned LookupIndexBuffer(IndexBuffer* buffer, const Vector<SharedPtr<IndexBuff
|
|||
return 0;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Model);
|
||||
|
||||
Model::Model(Context* context) :
|
||||
Resource(context)
|
||||
{
|
||||
|
|
|
@ -39,8 +39,6 @@ static const unsigned CLIPMASK_Y_NEG = 0x8;
|
|||
static const unsigned CLIPMASK_Z_POS = 0x10;
|
||||
static const unsigned CLIPMASK_Z_NEG = 0x20;
|
||||
|
||||
OBJECTTYPESTATIC(OcclusionBuffer);
|
||||
|
||||
OcclusionBuffer::OcclusionBuffer(Context* context) :
|
||||
Object(context),
|
||||
buffer_(0),
|
||||
|
|
|
@ -330,8 +330,6 @@ void Octant::GetDrawablesOnlyInternal(RayOctreeQuery& query, PODVector<Drawable*
|
|||
}
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Octree);
|
||||
|
||||
Octree::Octree(Context* context) :
|
||||
Component(context),
|
||||
Octant(BoundingBox(-DEFAULT_OCTREE_SIZE, DEFAULT_OCTREE_SIZE), 0, 0, this),
|
||||
|
|
|
@ -139,10 +139,6 @@ static const unsigned glVertexAttrIndex[] =
|
|||
|
||||
static const unsigned MAX_FRAMEBUFFER_AGE = 2000;
|
||||
|
||||
static unsigned numInstances = 0;
|
||||
|
||||
OBJECTTYPESTATIC(Graphics);
|
||||
|
||||
bool CheckExtension(String& extensions, const String& name)
|
||||
{
|
||||
if (extensions.Empty())
|
||||
|
@ -182,15 +178,8 @@ Graphics::Graphics(Context* context_) :
|
|||
SetTextureUnitMappings();
|
||||
ResetCachedState();
|
||||
|
||||
// If first instance in this process, initialize SDL under static mutex. Note that Graphics subsystem will also be in charge
|
||||
// of shutting down SDL as a whole, so it should be the last SDL-using subsystem (Audio and Input also use SDL) alive
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
if (!numInstances)
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
|
||||
++numInstances;
|
||||
}
|
||||
// Initialize SDL now. Graphics should be the first SDL-using subsystem to be created
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
|
||||
|
||||
// Register Graphics library object factories
|
||||
RegisterGraphicsLibrary(context_);
|
||||
|
@ -203,14 +192,8 @@ Graphics::~Graphics()
|
|||
delete impl_;
|
||||
impl_ = 0;
|
||||
|
||||
// If last instance in this process, shut down SDL under static mutex
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
--numInstances;
|
||||
if (!numInstances)
|
||||
SDL_Quit();
|
||||
}
|
||||
// Shut down SDL now. Graphics should be the last SDL-using subsystem to be destroyed
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void Graphics::SetExternalWindow(void* window)
|
||||
|
@ -275,135 +258,130 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool resizable, b
|
|||
{
|
||||
// Close the existing window and OpenGL context, mark GPU objects as lost
|
||||
Release(false, true);
|
||||
|
||||
{
|
||||
// SDL window parameters are static, so need to operate under static lock
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
#ifdef IOS
|
||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
|
||||
|
||||
// On iOS window needs to be resizable to handle orientation changes properly
|
||||
resizable = true;
|
||||
#endif
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
#ifdef IOS
|
||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
|
||||
if (multiSample > 1)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multiSample);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
}
|
||||
|
||||
int x = fullscreen ? 0 : SDL_WINDOWPOS_UNDEFINED;
|
||||
int y = fullscreen ? 0 : SDL_WINDOWPOS_UNDEFINED;
|
||||
|
||||
// On iOS window needs to be resizable to handle orientation changes properly
|
||||
resizable = true;
|
||||
#endif
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
if (multiSample > 1)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multiSample);
|
||||
}
|
||||
unsigned flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
|
||||
if (fullscreen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
|
||||
if (resizable)
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!externalWindow_)
|
||||
impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), x, y, width, height, flags);
|
||||
else
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
if (!impl_->window_)
|
||||
impl_->window_ = SDL_CreateWindowFrom(externalWindow_, SDL_WINDOW_OPENGL);
|
||||
fullscreen = false;
|
||||
}
|
||||
|
||||
int x = fullscreen ? 0 : SDL_WINDOWPOS_UNDEFINED;
|
||||
int y = fullscreen ? 0 : SDL_WINDOWPOS_UNDEFINED;
|
||||
|
||||
unsigned flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
|
||||
if (fullscreen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
|
||||
if (resizable)
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
for (;;)
|
||||
if (impl_->window_)
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (!externalWindow_)
|
||||
impl_->window_ = SDL_CreateWindow(windowTitle_.CString(), x, y, width, height, flags);
|
||||
if (multiSample > 1)
|
||||
{
|
||||
// If failed with multisampling, retry first without
|
||||
multiSample = 1;
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!impl_->window_)
|
||||
impl_->window_ = SDL_CreateWindowFrom(externalWindow_, SDL_WINDOW_OPENGL);
|
||||
fullscreen = false;
|
||||
}
|
||||
|
||||
if (impl_->window_)
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (multiSample > 1)
|
||||
{
|
||||
// If failed with multisampling, retry first without
|
||||
multiSample = 1;
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR("Could not open window");
|
||||
return false;
|
||||
}
|
||||
LOGERROR("Could not open window");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create/restore context and GPU objects and set initial renderstate
|
||||
Restore();
|
||||
|
||||
if (!impl_->context_)
|
||||
{
|
||||
LOGERROR("Could not create OpenGL context");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If OpenGL extensions not yet initialized, initialize now
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
{
|
||||
LOGERROR("Cannot initialize OpenGL");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
{
|
||||
LOGERROR("OpenGL 2.0 is required");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_EXT_framebuffer_object || !GLEW_EXT_packed_depth_stencil)
|
||||
{
|
||||
LOGERROR("EXT_framebuffer_object and EXT_packed_depth_stencil OpenGL extensions are required");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
instancingSupport_ = GLEW_ARB_instanced_arrays != 0;
|
||||
dxtTextureSupport_ = GLEW_EXT_texture_compression_s3tc != 0;
|
||||
anisotropySupport_ = GLEW_EXT_texture_filter_anisotropic != 0;
|
||||
sRGBSupport_ = GLEW_EXT_texture_sRGB != 0;
|
||||
sRGBWriteSupport_ = GLEW_EXT_framebuffer_sRGB != 0;
|
||||
|
||||
// Set up instancing divisors if supported
|
||||
if (instancingSupport_)
|
||||
{
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX1, 1);
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX2, 1);
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX3, 1);
|
||||
}
|
||||
|
||||
#else
|
||||
dxtTextureSupport_ = CheckExtension(extensions, "EXT_texture_compression_dxt1");
|
||||
etcTextureSupport_ = CheckExtension(extensions, "OES_compressed_ETC1_RGB8_texture");
|
||||
pvrtcTextureSupport_ = CheckExtension(extensions, "IMG_texture_compression_pvrtc");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create/restore context and GPU objects and set initial renderstate
|
||||
Restore();
|
||||
|
||||
if (!impl_->context_)
|
||||
{
|
||||
LOGERROR("Could not create OpenGL context");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If OpenGL extensions not yet initialized, initialize now
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GLenum err = glewInit();
|
||||
if (GLEW_OK != err)
|
||||
{
|
||||
LOGERROR("Cannot initialize OpenGL");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_VERSION_2_0)
|
||||
{
|
||||
LOGERROR("OpenGL 2.0 is required");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_EXT_framebuffer_object || !GLEW_EXT_packed_depth_stencil)
|
||||
{
|
||||
LOGERROR("EXT_framebuffer_object and EXT_packed_depth_stencil OpenGL extensions are required");
|
||||
Release(true, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
instancingSupport_ = GLEW_ARB_instanced_arrays != 0;
|
||||
dxtTextureSupport_ = GLEW_EXT_texture_compression_s3tc != 0;
|
||||
anisotropySupport_ = GLEW_EXT_texture_filter_anisotropic != 0;
|
||||
sRGBSupport_ = GLEW_EXT_texture_sRGB != 0;
|
||||
sRGBWriteSupport_ = GLEW_EXT_framebuffer_sRGB != 0;
|
||||
|
||||
// Set up instancing divisors if supported
|
||||
if (instancingSupport_)
|
||||
{
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX1, 1);
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX2, 1);
|
||||
glVertexAttribDivisorARB(ELEMENT_INSTANCEMATRIX3, 1);
|
||||
}
|
||||
|
||||
#else
|
||||
dxtTextureSupport_ = CheckExtension(extensions, "EXT_texture_compression_dxt1");
|
||||
etcTextureSupport_ = CheckExtension(extensions, "OES_compressed_ETC1_RGB8_texture");
|
||||
pvrtcTextureSupport_ = CheckExtension(extensions, "IMG_texture_compression_pvrtc");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set vsync
|
||||
|
@ -2041,16 +2019,12 @@ void Graphics::Release(bool clearGPUObjects, bool closeWindow)
|
|||
if (!clearGPUObjects)
|
||||
LOGINFO("OpenGL context lost");
|
||||
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_GL_DeleteContext(impl_->context_);
|
||||
impl_->context_ = 0;
|
||||
}
|
||||
|
||||
if (closeWindow)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_ShowCursor(SDL_TRUE);
|
||||
|
||||
// Do not destroy external window except when shutting down
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(IndexBuffer);
|
||||
|
||||
IndexBuffer::IndexBuffer(Context* context) :
|
||||
Object(context),
|
||||
GPUObject(GetSubsystem<Graphics>()),
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Shader);
|
||||
|
||||
Shader::Shader(Context* context) :
|
||||
Resource(context),
|
||||
vsSourceCodeLength_(0),
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Texture2D);
|
||||
|
||||
Texture2D::Texture2D(Context* context) :
|
||||
Texture(context)
|
||||
{
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(TextureCube);
|
||||
|
||||
TextureCube::TextureCube(Context* context) :
|
||||
Texture(context)
|
||||
{
|
||||
|
|
|
@ -101,8 +101,6 @@ const unsigned VertexBuffer::elementNormalize[] =
|
|||
GL_FALSE // Instancematrix3
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(VertexBuffer);
|
||||
|
||||
VertexBuffer::VertexBuffer(Context* context) :
|
||||
Object(context),
|
||||
GPUObject(GetSubsystem<Graphics>()),
|
||||
|
|
|
@ -61,8 +61,6 @@ template<> EmitterType Variant::Get<EmitterType>() const
|
|||
return (EmitterType)GetInt();
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(ParticleEmitter);
|
||||
|
||||
ParticleEmitter::ParticleEmitter(Context* context) :
|
||||
BillboardSet(context),
|
||||
emitterType_(EMITTER_SPHERE),
|
||||
|
|
|
@ -253,8 +253,6 @@ static const char* lightPSVariations[] =
|
|||
static const unsigned INSTANCING_BUFFER_MASK = MASK_INSTANCEMATRIX1 | MASK_INSTANCEMATRIX2 | MASK_INSTANCEMATRIX3;
|
||||
static const unsigned MAX_BUFFER_AGE = 2000;
|
||||
|
||||
OBJECTTYPESTATIC(Renderer);
|
||||
|
||||
Renderer::Renderer(Context* context) :
|
||||
Object(context),
|
||||
defaultZone_(new Zone(context)),
|
||||
|
|
|
@ -34,8 +34,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Skybox);
|
||||
|
||||
Skybox::Skybox(Context* context) :
|
||||
StaticModel(context),
|
||||
customWorldTransform_(Matrix3x4::IDENTITY)
|
||||
|
|
|
@ -42,8 +42,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(StaticModel);
|
||||
|
||||
StaticModel::StaticModel(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
occlusionLodLevel_(M_MAX_UNSIGNED),
|
||||
|
|
|
@ -135,8 +135,6 @@ void Pass::MarkShadersLoaded(unsigned frameNumber)
|
|||
shadersLoadedFrameNumber_ = frameNumber;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Technique);
|
||||
|
||||
Technique::Technique(Context* context) :
|
||||
Resource(context),
|
||||
isSM3_(false)
|
||||
|
|
|
@ -46,8 +46,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Terrain);
|
||||
|
||||
static const Vector3 DEFAULT_SPACING(1.0f, 0.25f, 1.0f);
|
||||
static const unsigned MAX_LOD_LEVELS = 4;
|
||||
static const int DEFAULT_PATCH_SIZE = 32;
|
||||
|
|
|
@ -43,8 +43,6 @@ static const float LOD_CONSTANT = 1.0f / 150.0f;
|
|||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(TerrainPatch);
|
||||
|
||||
TerrainPatch::TerrainPatch(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
geometry_(new Geometry(context)),
|
||||
|
|
|
@ -251,8 +251,6 @@ void SortShadowQueueWork(const WorkItem* item, unsigned threadIndex)
|
|||
start->shadowSplits_[i].shadowBatches_.SortFrontToBack();
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(View);
|
||||
|
||||
View::View(Context* context) :
|
||||
Object(context),
|
||||
graphics_(GetSubsystem<Graphics>()),
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Viewport);
|
||||
|
||||
Viewport::Viewport(Context* context) :
|
||||
Object(context),
|
||||
rect_(IntRect::ZERO)
|
||||
|
|
|
@ -42,8 +42,6 @@ static const float DEFAULT_FOG_END = 1000.0f;
|
|||
|
||||
extern const char* SCENE_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Zone);
|
||||
|
||||
Zone::Zone(Context* context) :
|
||||
Drawable(context, DRAWABLE_ZONE),
|
||||
inverseWorldDirty_(true),
|
||||
|
|
|
@ -54,8 +54,6 @@ static const char* openMode[] =
|
|||
static const unsigned READ_BUFFER_SIZE = 1024;
|
||||
#endif
|
||||
|
||||
OBJECTTYPESTATIC(File);
|
||||
|
||||
File::File(Context* context) :
|
||||
Object(context),
|
||||
mode_(FILE_READ),
|
||||
|
|
|
@ -63,8 +63,6 @@ extern "C" const char* SDL_IOS_GetResourceDir();
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(FileSystem);
|
||||
|
||||
FileSystem::FileSystem(Context* context) :
|
||||
Object(context)
|
||||
{
|
||||
|
|
|
@ -46,8 +46,6 @@ namespace Urho3D
|
|||
|
||||
static const unsigned BUFFERSIZE = 4096;
|
||||
|
||||
OBJECTTYPESTATIC(FileWatcher);
|
||||
|
||||
FileWatcher::FileWatcher(Context* context) :
|
||||
Object(context),
|
||||
fileSystem_(GetSubsystem<FileSystem>()),
|
||||
|
|
|
@ -51,49 +51,26 @@ const char* logLevelPrefixes[] =
|
|||
"ERROR"
|
||||
};
|
||||
|
||||
SharedPtr<File> Log::logFile_;
|
||||
String Log::lastMessage_;
|
||||
#ifdef _DEBUG
|
||||
int Log::level_ = LOG_DEBUG;
|
||||
#else
|
||||
int Log::level_ = LOG_INFO;
|
||||
#endif
|
||||
bool Log::timeStamp_ = true;
|
||||
bool Log::inWrite_ = false;
|
||||
bool Log::quiet_ = false;
|
||||
|
||||
static PODVector<Log*> logInstances;
|
||||
|
||||
OBJECTTYPESTATIC(Log);
|
||||
static Log* logInstance = 0;
|
||||
|
||||
Log::Log(Context* context) :
|
||||
Object(context)
|
||||
Object(context),
|
||||
level_(LOG_INFO),
|
||||
timeStamp_(true),
|
||||
inWrite_(false),
|
||||
quiet_(false)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
#ifdef ANDROID
|
||||
// On Android we may have instances from a previous run
|
||||
logInstances.Clear();
|
||||
#endif
|
||||
logInstances.Push(this);
|
||||
logInstance = this;
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
logInstances.Remove(this);
|
||||
|
||||
// Close log file if was last instance
|
||||
if (logInstances.Empty())
|
||||
logFile_.Reset();
|
||||
logInstance = 0;
|
||||
}
|
||||
|
||||
void Log::Open(const String& fileName)
|
||||
{
|
||||
#if !defined(ANDROID) && !defined(IOS)
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
// Only the first log instance actually opens the file, the rest are routed to it
|
||||
if ((logFile_ && logFile_->IsOpen()) || fileName.Empty())
|
||||
return;
|
||||
|
||||
|
@ -125,114 +102,92 @@ void Log::SetQuiet(bool quiet)
|
|||
quiet_ = quiet;
|
||||
}
|
||||
|
||||
String Log::GetLastMessage() const
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
return lastMessage_;
|
||||
}
|
||||
|
||||
void Log::Write(int level, const String& message)
|
||||
{
|
||||
assert(level >= LOG_DEBUG && level < LOG_NONE);
|
||||
|
||||
// Do not log if message level excluded or if currently sending a log event
|
||||
if (level_ > level || inWrite_)
|
||||
if (!logInstance || logInstance->level_ > level || logInstance->inWrite_)
|
||||
return;
|
||||
|
||||
String formattedMessage = logLevelPrefixes[level];
|
||||
formattedMessage += ": " + message;
|
||||
logInstance->lastMessage_ = message;
|
||||
|
||||
if (logInstance->timeStamp_)
|
||||
formattedMessage = "[" + Time::GetTimeStamp() + "] " + formattedMessage;
|
||||
|
||||
#if defined(ANDROID)
|
||||
int androidLevel = ANDROID_LOG_DEBUG + level;
|
||||
__android_log_print(androidLevel, "Urho3D", "%s", message.CString());
|
||||
#elif defined(IOS)
|
||||
SDL_IOS_LogMessage(message.CString());
|
||||
#else
|
||||
if (logInstance->quiet_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
String formattedMessage = logLevelPrefixes[level];
|
||||
formattedMessage += ": " + message;
|
||||
lastMessage_ = message;
|
||||
|
||||
if (timeStamp_)
|
||||
formattedMessage = "[" + Time::GetTimeStamp() + "] " + formattedMessage;
|
||||
|
||||
#if defined(ANDROID)
|
||||
int androidLevel = ANDROID_LOG_DEBUG + level;
|
||||
__android_log_print(androidLevel, "Urho3D", "%s", message.CString());
|
||||
#elif defined(IOS)
|
||||
SDL_IOS_LogMessage(message.CString());
|
||||
#else
|
||||
if (quiet_)
|
||||
{
|
||||
// If in quiet mode, still print the error message to the standard error stream
|
||||
if (level == LOG_ERROR)
|
||||
PrintUnicodeLine(formattedMessage, true);
|
||||
}
|
||||
else
|
||||
PrintUnicodeLine(formattedMessage, level == LOG_ERROR);
|
||||
#endif
|
||||
|
||||
if (logFile_)
|
||||
{
|
||||
logFile_->WriteLine(formattedMessage);
|
||||
logFile_->Flush();
|
||||
}
|
||||
|
||||
// Log messages can be safely sent as an event only in single-instance mode
|
||||
if (logInstances.Size() == 1)
|
||||
{
|
||||
inWrite_ = true;
|
||||
|
||||
using namespace LogMessage;
|
||||
|
||||
VariantMap eventData;
|
||||
eventData[P_MESSAGE] = formattedMessage;
|
||||
logInstances[0]->SendEvent(E_LOGMESSAGE, eventData);
|
||||
|
||||
inWrite_ = false;
|
||||
}
|
||||
// If in quiet mode, still print the error message to the standard error stream
|
||||
if (level == LOG_ERROR)
|
||||
PrintUnicodeLine(formattedMessage, true);
|
||||
}
|
||||
else
|
||||
PrintUnicodeLine(formattedMessage, level == LOG_ERROR);
|
||||
#endif
|
||||
|
||||
if (logInstance->logFile_)
|
||||
{
|
||||
logInstance->logFile_->WriteLine(formattedMessage);
|
||||
logInstance->logFile_->Flush();
|
||||
}
|
||||
|
||||
logInstance->inWrite_ = true;
|
||||
|
||||
using namespace LogMessage;
|
||||
|
||||
VariantMap eventData;
|
||||
eventData[P_MESSAGE] = formattedMessage;
|
||||
logInstance->SendEvent(E_LOGMESSAGE, eventData);
|
||||
|
||||
logInstance->inWrite_ = false;
|
||||
}
|
||||
|
||||
void Log::WriteRaw(const String& message, bool error)
|
||||
{
|
||||
// Prevent recursion during log event
|
||||
if (inWrite_)
|
||||
if (!logInstance || logInstance->inWrite_)
|
||||
return;
|
||||
|
||||
logInstance->lastMessage_ = message;
|
||||
|
||||
#if defined(ANDROID)
|
||||
__android_log_print(ANDROID_LOG_INFO, "Urho3D", message.CString());
|
||||
#elif defined(IOS)
|
||||
SDL_IOS_LogMessage(message.CString());
|
||||
#else
|
||||
if (logInstance->quiet_)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
lastMessage_ = message;
|
||||
|
||||
#if defined(ANDROID)
|
||||
__android_log_print(ANDROID_LOG_INFO, "Urho3D", message.CString());
|
||||
#elif defined(IOS)
|
||||
SDL_IOS_LogMessage(message.CString());
|
||||
#else
|
||||
if (quiet_)
|
||||
{
|
||||
// If in quiet mode, still print the error message to the standard error stream
|
||||
if (error)
|
||||
PrintUnicode(message, true);
|
||||
}
|
||||
else
|
||||
PrintUnicode(message, error);
|
||||
#endif
|
||||
|
||||
if (logFile_)
|
||||
{
|
||||
logFile_->Write(message.CString(), message.Length());
|
||||
logFile_->Flush();
|
||||
}
|
||||
|
||||
// Log messages can be safely sent as an event only in single-instance mode
|
||||
if (logInstances.Size() == 1)
|
||||
{
|
||||
inWrite_ = true;
|
||||
|
||||
using namespace LogMessage;
|
||||
|
||||
VariantMap eventData;
|
||||
eventData[P_MESSAGE] = message;
|
||||
logInstances[0]->SendEvent(E_LOGMESSAGE, eventData);
|
||||
|
||||
inWrite_ = false;
|
||||
}
|
||||
// If in quiet mode, still print the error message to the standard error stream
|
||||
if (error)
|
||||
PrintUnicode(message, true);
|
||||
}
|
||||
else
|
||||
PrintUnicode(message, error);
|
||||
#endif
|
||||
|
||||
if (logInstance->logFile_)
|
||||
{
|
||||
logInstance->logFile_->Write(message.CString(), message.Length());
|
||||
logInstance->logFile_->Flush();
|
||||
}
|
||||
|
||||
logInstance->inWrite_ = true;
|
||||
|
||||
using namespace LogMessage;
|
||||
|
||||
VariantMap eventData;
|
||||
eventData[P_MESSAGE] = message;
|
||||
logInstance->SendEvent(E_LOGMESSAGE, eventData);
|
||||
|
||||
logInstance->inWrite_ = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
/// Return whether log messages are timestamped.
|
||||
bool GetTimeStamp() const { return timeStamp_; }
|
||||
/// Return last log message.
|
||||
String GetLastMessage() const;
|
||||
String GetLastMessage() const { return lastMessage_; }
|
||||
/// Return whether log is in quiet mode (only errors printed to standard error stream).
|
||||
bool IsQuiet() const { return quiet_; }
|
||||
|
||||
|
@ -76,17 +76,17 @@ public:
|
|||
|
||||
private:
|
||||
/// Log file.
|
||||
static SharedPtr<File> logFile_;
|
||||
SharedPtr<File> logFile_;
|
||||
/// Last log message.
|
||||
static String lastMessage_;
|
||||
String lastMessage_;
|
||||
/// Logging level.
|
||||
static int level_;
|
||||
int level_;
|
||||
/// Timestamp log messages flag.
|
||||
static bool timeStamp_;
|
||||
bool timeStamp_;
|
||||
/// In write flag to prevent recursion.
|
||||
static bool inWrite_;
|
||||
bool inWrite_;
|
||||
/// Quiet mode flag.
|
||||
static bool quiet_;
|
||||
bool quiet_;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_LOGGING
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(PackageFile);
|
||||
|
||||
PackageFile::PackageFile(Context* context) :
|
||||
Object(context),
|
||||
totalSize_(0),
|
||||
|
|
|
@ -56,13 +56,8 @@ int ConvertSDLKeyCode(int keySym, int scanCode)
|
|||
return SDL_toupper(keySym);
|
||||
}
|
||||
|
||||
static PODVector<Input*> inputInstances;
|
||||
|
||||
OBJECTTYPESTATIC(Input);
|
||||
|
||||
Input::Input(Context* context) :
|
||||
Object(context),
|
||||
eventQueue_(new PODVector<SDL_Event>()),
|
||||
mouseButtonDown_(0),
|
||||
mouseButtonPress_(0),
|
||||
mouseMoveWheel_(0),
|
||||
|
@ -75,15 +70,6 @@ Input::Input(Context* context) :
|
|||
suppressNextMouseMove_(false),
|
||||
initialized_(false)
|
||||
{
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
#ifdef ANDROID
|
||||
// On Android we may have instances from a previous run
|
||||
inputInstances.Clear();
|
||||
#endif
|
||||
inputInstances.Push(this);
|
||||
}
|
||||
|
||||
SubscribeToEvent(E_SCREENMODE, HANDLER(Input, HandleScreenMode));
|
||||
|
||||
// Try to initialize right now, but skip if screen mode is not yet set
|
||||
|
@ -92,12 +78,6 @@ Input::Input(Context* context) :
|
|||
|
||||
Input::~Input()
|
||||
{
|
||||
PODVector<SDL_Event>* eventQueue = reinterpret_cast<PODVector<SDL_Event>* >(eventQueue_);
|
||||
delete eventQueue;
|
||||
eventQueue_ = 0;
|
||||
|
||||
MutexLock lock(GetStaticMutex());
|
||||
inputInstances.Remove(this);
|
||||
}
|
||||
|
||||
void Input::Update()
|
||||
|
@ -125,87 +105,11 @@ void Input::Update()
|
|||
state.delta_ = IntVector2::ZERO;
|
||||
}
|
||||
|
||||
// Check for SDL events
|
||||
// Check and handle SDL events
|
||||
SDL_PumpEvents();
|
||||
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_Event evt;
|
||||
while (SDL_PeepEvents(&evt, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0)
|
||||
{
|
||||
// If only one instance, can handle event directly. Otherwise put to the correct input instance's event queue
|
||||
if (inputInstances.Size() > 1)
|
||||
{
|
||||
for (PODVector<Input*>::Iterator i = inputInstances.Begin(); i != inputInstances.End(); ++i)
|
||||
{
|
||||
bool storeEvent = false;
|
||||
|
||||
switch (evt.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
storeEvent = evt.key.windowID == (*i)->windowID_;
|
||||
break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
storeEvent = evt.text.windowID == (*i)->windowID_;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
storeEvent = evt.button.windowID == (*i)->windowID_;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
storeEvent = evt.wheel.windowID == (*i)->windowID_;
|
||||
break;
|
||||
|
||||
// Joystick and touch events do not have a windowID. Store depending on input focus
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYAXISMOTION:
|
||||
case SDL_JOYHATMOTION:
|
||||
case SDL_FINGERDOWN:
|
||||
case SDL_FINGERUP:
|
||||
case SDL_FINGERMOTION:
|
||||
storeEvent = (*i)->inputFocus_;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
storeEvent = evt.window.windowID == (*i)->windowID_;
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
storeEvent = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (storeEvent)
|
||||
{
|
||||
(*i)->eventQueueMutex_.Acquire();
|
||||
PODVector<SDL_Event>* eventQueue = reinterpret_cast<PODVector<SDL_Event>* >((*i)->eventQueue_);
|
||||
eventQueue->Push(evt);
|
||||
(*i)->eventQueueMutex_.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
HandleSDLEvent(&evt);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle own event queue now if necessary
|
||||
if (inputInstances.Size() > 1)
|
||||
{
|
||||
eventQueueMutex_.Acquire();
|
||||
|
||||
PODVector<SDL_Event>* eventQueue = reinterpret_cast<PODVector<SDL_Event>* >(eventQueue_);
|
||||
for (PODVector<SDL_Event>::Iterator i = eventQueue->Begin(); i != eventQueue->End(); ++i)
|
||||
HandleSDLEvent(&(*i));
|
||||
eventQueue->Clear();
|
||||
|
||||
eventQueueMutex_.Release();
|
||||
}
|
||||
SDL_Event evt;
|
||||
while (SDL_PeepEvents(&evt, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0)
|
||||
HandleSDLEvent(&evt);
|
||||
|
||||
// Check for activation and inactivation from SDL window flags. Must nullcheck the window pointer because it may have
|
||||
// been closed due to input events
|
||||
|
@ -232,7 +136,7 @@ void Input::Update()
|
|||
|
||||
#if !defined(ANDROID) && !defined(IOS)
|
||||
// Check for mouse move
|
||||
if (inputFocus_)
|
||||
if (inputFocus_ && (flags & SDL_WINDOW_MOUSE_FOCUS))
|
||||
{
|
||||
IntVector2 mousePosition = GetMousePosition();
|
||||
mouseMove_ = mousePosition - lastMousePosition_;
|
||||
|
@ -306,14 +210,10 @@ void Input::SetToggleFullscreen(bool enable)
|
|||
|
||||
bool Input::DetectJoysticks()
|
||||
{
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
ResetJoysticks();
|
||||
return true;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
ResetJoysticks();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Input::OpenJoystick(unsigned index)
|
||||
|
@ -325,8 +225,6 @@ bool Input::OpenJoystick(unsigned index)
|
|||
if (joysticks_[index].joystick_)
|
||||
return true;
|
||||
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
SDL_Joystick* joystick = SDL_JoystickOpen(index);
|
||||
if (joystick)
|
||||
{
|
||||
|
@ -354,8 +252,6 @@ bool Input::OpenJoystick(unsigned index)
|
|||
|
||||
void Input::CloseJoystick(unsigned index)
|
||||
{
|
||||
MutexLock lock(GetStaticMutex());
|
||||
|
||||
if (index < joysticks_.Size() && joysticks_[index].joystick_)
|
||||
{
|
||||
JoystickState& state = joysticks_[index];
|
||||
|
|
|
@ -218,10 +218,6 @@ private:
|
|||
HashMap<int, TouchState> touches_;
|
||||
/// Opened joysticks.
|
||||
Vector<JoystickState> joysticks_;
|
||||
/// Per-instance SDL event queue.
|
||||
void* eventQueue_;
|
||||
/// Per-instance SDL event queue mutex.
|
||||
Mutex eventQueueMutex_;
|
||||
/// Mouse buttons' down state.
|
||||
unsigned mouseButtonDown_;
|
||||
/// Mouse buttons' pressed state.
|
||||
|
|
|
@ -31,8 +31,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* NAVIGATION_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Navigable);
|
||||
|
||||
Navigable::Navigable(Context* context) :
|
||||
Component(context),
|
||||
recursive_(true)
|
||||
|
|
|
@ -142,8 +142,6 @@ struct FindPathData
|
|||
unsigned char pathFlags_[MAX_POLYS];
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(NavigationMesh);
|
||||
|
||||
NavigationMesh::NavigationMesh(Context* context) :
|
||||
Component(context),
|
||||
navMesh_(0),
|
||||
|
|
|
@ -33,8 +33,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* NAVIGATION_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(OffMeshConnection);
|
||||
|
||||
static const float DEFAULT_RADIUS = 1.0f;
|
||||
|
||||
OffMeshConnection::OffMeshConnection(Context* context) :
|
||||
|
|
|
@ -61,8 +61,6 @@ PackageUpload::PackageUpload() :
|
|||
{
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Connection);
|
||||
|
||||
Connection::Connection(Context* context, bool isClient, kNet::SharedPtr<kNet::MessageConnection> connection) :
|
||||
Object(context),
|
||||
position_(Vector3::ZERO),
|
||||
|
|
|
@ -43,8 +43,6 @@ namespace Urho3D
|
|||
|
||||
static const int DEFAULT_UPDATE_FPS = 30;
|
||||
|
||||
OBJECTTYPESTATIC(Network);
|
||||
|
||||
Network::Network(Context* context) :
|
||||
Object(context),
|
||||
updateFps_(DEFAULT_UPDATE_FPS),
|
||||
|
|
|
@ -36,8 +36,6 @@ static const float DEFAULT_DISTANCE_FACTOR = 0.0f;
|
|||
static const float DEFAULT_MIN_PRIORITY = 0.0f;
|
||||
static const float UPDATE_THRESHOLD = 100.0f;
|
||||
|
||||
OBJECTTYPESTATIC(NetworkPriority);
|
||||
|
||||
NetworkPriority::NetworkPriority(Context* context) :
|
||||
Component(context),
|
||||
basePriority_(DEFAULT_BASE_PRIORITY),
|
||||
|
|
|
@ -307,8 +307,6 @@ HeightfieldData::~HeightfieldData()
|
|||
{
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(CollisionShape);
|
||||
|
||||
CollisionShape::CollisionShape(Context* context) :
|
||||
Component(context),
|
||||
shape_(0),
|
||||
|
|
|
@ -51,8 +51,6 @@ static const char* typeNames[] =
|
|||
|
||||
extern const char* PHYSICS_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Constraint);
|
||||
|
||||
Constraint::Constraint(Context* context) :
|
||||
Component(context),
|
||||
constraint_(0),
|
||||
|
|
|
@ -106,8 +106,6 @@ struct PhysicsQueryCallback : public btCollisionWorld::ContactResultCallback
|
|||
PODVector<RigidBody*>& result_;
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(PhysicsWorld);
|
||||
|
||||
PhysicsWorld::PhysicsWorld(Context* context) :
|
||||
Component(context),
|
||||
collisionConfiguration_(0),
|
||||
|
|
|
@ -59,8 +59,6 @@ static const char* collisionEventModeNames[] =
|
|||
|
||||
extern const char* PHYSICS_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(RigidBody);
|
||||
|
||||
RigidBody::RigidBody(Context* context) :
|
||||
Component(context),
|
||||
body_(0),
|
||||
|
|
|
@ -190,8 +190,6 @@ bool CompressedLevel::Decompress(unsigned char* dest)
|
|||
}
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Image);
|
||||
|
||||
Image::Image(Context* context) :
|
||||
Resource(context),
|
||||
width_(0),
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Resource);
|
||||
|
||||
Resource::Resource(Context* context) :
|
||||
Object(context),
|
||||
memoryUse_(0)
|
||||
|
|
|
@ -58,8 +58,6 @@ static const char* checkDirs[] = {
|
|||
|
||||
static const SharedPtr<Resource> noResource;
|
||||
|
||||
OBJECTTYPESTATIC(ResourceCache);
|
||||
|
||||
ResourceCache::ResourceCache(Context* context) :
|
||||
Object(context),
|
||||
autoReloadResources_(false)
|
||||
|
|
|
@ -60,8 +60,6 @@ public:
|
|||
bool success_;
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(XMLFile);
|
||||
|
||||
XMLFile::XMLFile(Context* context) :
|
||||
Resource(context),
|
||||
document_(new pugi::xml_document())
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Component);
|
||||
|
||||
Component::Component(Context* context) :
|
||||
Serializable(context),
|
||||
node_(0),
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Node);
|
||||
|
||||
Node::Node(Context* context) :
|
||||
Serializable(context),
|
||||
worldTransform_(Matrix3x4::IDENTITY),
|
||||
|
|
|
@ -49,8 +49,6 @@ static const int ASYNC_LOAD_MAX_MSEC = (int)(1000.0f / ASYNC_LOAD_MIN_FPS);
|
|||
static const float DEFAULT_SMOOTHING_CONSTANT = 50.0f;
|
||||
static const float DEFAULT_SNAP_THRESHOLD = 5.0f;
|
||||
|
||||
OBJECTTYPESTATIC(Scene);
|
||||
|
||||
Scene::Scene(Context* context) :
|
||||
Node(context),
|
||||
replicatedNodeID_(FIRST_REPLICATED_ID),
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(Serializable);
|
||||
|
||||
Serializable::Serializable(Context* context) :
|
||||
Object(context),
|
||||
networkState_(0),
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
OBJECTTYPESTATIC(SmoothedTransform);
|
||||
|
||||
SmoothedTransform::SmoothedTransform(Context* context) :
|
||||
Component(context),
|
||||
targetPosition_(Vector3::ZERO),
|
||||
|
|
|
@ -131,8 +131,6 @@ void ExtractPropertyInfo(const String& functionName, const String& declaration,
|
|||
}
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(Script);
|
||||
|
||||
Script::Script(Context* context) :
|
||||
Object(context),
|
||||
scriptEngine_(0),
|
||||
|
|
|
@ -92,8 +92,6 @@ private:
|
|||
Deserializer& source_;
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(ScriptFile);
|
||||
|
||||
ScriptFile::ScriptFile(Context* context) :
|
||||
Resource(context),
|
||||
script_(GetSubsystem<Script>()),
|
||||
|
|
|
@ -57,8 +57,6 @@ static const char* methodDeclarations[] = {
|
|||
"void ApplyAttributes()"
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(ScriptInstance);
|
||||
|
||||
ScriptInstance::ScriptInstance(Context* context) :
|
||||
Component(context),
|
||||
script_(GetSubsystem<Script>()),
|
||||
|
|
|
@ -39,8 +39,6 @@ template<> BlendMode Variant::Get<BlendMode>() const
|
|||
return (BlendMode)GetInt();
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(BorderImage);
|
||||
|
||||
BorderImage::BorderImage(Context* context) :
|
||||
UIElement(context),
|
||||
imageRect_(IntRect::ZERO),
|
||||
|
|
|
@ -33,8 +33,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Button);
|
||||
|
||||
Button::Button(Context* context) :
|
||||
BorderImage(context),
|
||||
pressedOffset_(IntVector2::ZERO),
|
||||
|
|
|
@ -33,8 +33,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(CheckBox);
|
||||
|
||||
CheckBox::CheckBox(Context* context) :
|
||||
BorderImage(context),
|
||||
checkedOffset_(IntVector2::ZERO),
|
||||
|
|
|
@ -49,8 +49,6 @@ static const char* shapeNames[] =
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Cursor);
|
||||
|
||||
Cursor::Cursor(Context* context) :
|
||||
BorderImage(context),
|
||||
shape_(CS_NORMAL)
|
||||
|
|
|
@ -35,8 +35,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(DropDownList);
|
||||
|
||||
DropDownList::DropDownList(Context* context) :
|
||||
Menu(context),
|
||||
resizePopup_(false),
|
||||
|
|
|
@ -50,8 +50,6 @@ static bool CompareEntries(const FileSelectorEntry& lhs, const FileSelectorEntry
|
|||
return lhs.name_.Compare(rhs.name_, false) < 0;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(FileSelector);
|
||||
|
||||
FileSelector::FileSelector(Context* context) :
|
||||
Object(context),
|
||||
directoryMode_(false),
|
||||
|
|
|
@ -138,9 +138,6 @@ bool FontFace::IsDataLost() const
|
|||
return false;
|
||||
}
|
||||
|
||||
OBJECTTYPESTATIC(FreeTypeLibrary);
|
||||
OBJECTTYPESTATIC(Font);
|
||||
|
||||
Font::Font(Context* context) :
|
||||
Resource(context),
|
||||
fontDataSize_(0),
|
||||
|
|
|
@ -35,8 +35,6 @@ namespace Urho3D
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(LineEdit);
|
||||
|
||||
LineEdit::LineEdit(Context* context) :
|
||||
BorderImage(context),
|
||||
lastFont_(0),
|
||||
|
|
|
@ -156,9 +156,6 @@ private:
|
|||
UIElement* overlayContainer_;
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(HierarchyContainer);
|
||||
OBJECTTYPESTATIC(ListView);
|
||||
|
||||
ListView::ListView(Context* context) :
|
||||
ScrollView(context),
|
||||
highlightMode_(HM_FOCUS),
|
||||
|
|
|
@ -39,8 +39,6 @@ extern ShortStringHash VAR_ORIGIN;
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Menu);
|
||||
|
||||
Menu::Menu(Context* context) :
|
||||
Button(context),
|
||||
popupOffset_(IntVector2::ZERO),
|
||||
|
|
|
@ -38,8 +38,6 @@ static const float DEFAULT_REPEAT_RATE = 20.0f;
|
|||
extern const char* orientations[];
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(ScrollBar);
|
||||
|
||||
ScrollBar::ScrollBar(Context* context) :
|
||||
UIElement(context),
|
||||
scrollStep_(DEFAULT_SCROLL_STEP),
|
||||
|
|
|
@ -37,8 +37,6 @@ static const float STEP_FACTOR = 300.0f;
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(ScrollView);
|
||||
|
||||
ScrollView::ScrollView(Context* context) :
|
||||
UIElement(context),
|
||||
viewPosition_(IntVector2::ZERO),
|
||||
|
|
|
@ -46,8 +46,6 @@ template<> Orientation Variant::Get<Orientation>() const
|
|||
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Slider);
|
||||
|
||||
Slider::Slider(Context* context) :
|
||||
BorderImage(context),
|
||||
orientation_(O_HORIZONTAL),
|
||||
|
|
|
@ -36,8 +36,6 @@ extern const char* horizontalAlignments[];
|
|||
extern const char* verticalAlignments[];
|
||||
extern const char* UI_CATEGORY;
|
||||
|
||||
OBJECTTYPESTATIC(Sprite);
|
||||
|
||||
Sprite::Sprite(Context* context) :
|
||||
UIElement(context),
|
||||
floatPosition_(Vector2::ZERO),
|
||||
|
|
|
@ -54,8 +54,6 @@ struct GlyphLocation
|
|||
}
|
||||
};
|
||||
|
||||
OBJECTTYPESTATIC(Text);
|
||||
|
||||
Text::Text(Context* context) :
|
||||
UIElement(context),
|
||||
fontSize_(DEFAULT_FONT_SIZE),
|
||||
|
|
|
@ -43,8 +43,6 @@ extern const char* GEOMETRY_CATEGORY;
|
|||
|
||||
static const float TEXT_SCALING = 1.0f / 128.0f;
|
||||
|
||||
OBJECTTYPESTATIC(Text3D);
|
||||
|
||||
Text3D::Text3D(Context* context) :
|
||||
Drawable(context, DRAWABLE_GEOMETRY),
|
||||
text_(context),
|
||||
|
|
|
@ -64,8 +64,6 @@ const ShortStringHash VAR_PARENT_CHANGED("ParentChanged");
|
|||
|
||||
const char* UI_CATEGORY = "UI";
|
||||
|
||||
OBJECTTYPESTATIC(UI);
|
||||
|
||||
UI::UI(Context* context) :
|
||||
Object(context),
|
||||
rootElement_(new UIElement(context)),
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче