<commit_before>/*
    Copyright (C) 2000-2001 by <NAME>
    Copyright (C) 1998-2000 by <NAME> <<EMAIL>>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_THREADED_LOADER_H__
#define __CS_THREADED_LOADER_H__

#include "csutil/cscolor.h"
#include "csutil/threadmanager.h"
#include "csutil/scf_implementation.h"
#include "csutil/strhash.h"
#include "csutil/weakrefarr.h"
#include "csutil/weakrefhash.h"

#include "iengine/campos.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/portal.h"
#include "iengine/sector.h"
#include "iengine/sharevar.h"
#include "imap/ldrctxt.h"
#include "imap/loader.h"
#include "isndsys/ss_loader.h"
#include "isndsys/ss_manager.h"
#include "isndsys/ss_renderer.h"
#include "iutil/comp.h"
#include "iutil/object.h"
#include "ivaria/engseq.h"

#include "ldrplug.h"
#include "proxyimage.h"

class csReversibleTransform;
struct iCollection;
struct iDocumentNode;
struct iEngine;
struct iImageIO;
struct iImposter;
struct iLODControl;
struct iMapNode;
struct iObjectModel;
struct iObjectRegistry;
struct iSceneNodeArray;
struct iShaderVarStringSet;
struct iStringSet;
struct iSyntaxService;
struct iTriangleMesh;
struct iVFS;

CS_PLUGIN_NAMESPACE_BEGIN(csparser)
{
  class csLoaderContext;

  template<class T, class Interface>
  class csLoaderIterator : public scfImplementation1<csLoaderIterator<T, Interface>,
                                                     Interface>
  {
  public:
    csLoaderIterator(csRefArray<T>* objects, CS::Threading::Mutex* lock) :
        scfImplementation1<csLoaderIterator<T, Interface>,
                           Interface> (this),
        lock(*lock), objects(objects), itr(objects->GetIterator())
        {
        }

        virtual ~csLoaderIterator()
        {
          objects->Empty();
        }

        T* Next()
        {
          return itr.Next();
        }

        bool HasNext() const
        {
          return itr.HasNext();
        }

  private:
    CS::Threading::MutexScopedLock lock;
    csRefArray<T>* objects;
    typename csRefArray<T>::Iterator itr;
  };

  class csThreadedLoader : public ThreadedCallable<csThreadedLoader>,
                           public scfImplementation3<csThreadedLoader,
                                                     iThreadedLoader,
                                                     iComponent,
                                                     iEventHandler>
  {
    typedef csThreadedLoader ThisType;
  public:
    csThreadedLoader(iBase *p);
    virtual ~csThreadedLoader();

    bool HandleEvent(iEvent&);
    CS_EVENTHANDLER_NAMES("crystalspace.level.loader.threaded")
    CS_EVENTHANDLER_NIL_CONSTRAINTS

    virtual bool Initialize(iObjectRegistry *object_reg);

    iObjectRegistry* GetObjectRegistry() const { return object_reg; }

    virtual csPtr<iSectorLoaderIterator> GetLoaderSectors()
    {
      csRef<iSectorLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iSector, iSectorLoaderIterator>(&loaderSectors, &sectorsLock));
      return csPtr<iSectorLoaderIterator>(itr);
    }
    virtual csPtr<iMeshFactLoaderIterator> GetLoaderMeshFactories()
    {
      csRef<iMeshFactLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMeshFactoryWrapper, iMeshFactLoaderIterator>(&loaderMeshFactories, &meshfactsLock));
      return csPtr<iMeshFactLoaderIterator>(itr);
    }
    virtual csPtr<iMeshLoaderIterator> GetLoaderMeshes()
    {
      csRef<iMeshLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMeshWrapper, iMeshLoaderIterator>(&loaderMeshes, &meshesLock));
      return csPtr<iMeshLoaderIterator>(itr);
    }
    virtual csPtr<iCamposLoaderIterator> GetLoaderCameraPositions()
    {
      csRef<iCamposLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iCameraPosition, iCamposLoaderIterator>(&loaderCameraPositions, &camposLock));
      return csPtr<iCamposLoaderIterator>(itr);
    }
    virtual csPtr<iTextureLoaderIterator> GetLoaderTextures()
    {
      csRef<iTextureLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iTextureWrapper, iTextureLoaderIterator>(&loaderTextures, &texturesLock));
      return csPtr<iTextureLoaderIterator>(itr);
    }
    virtual csPtr<iMaterialLoaderIterator> GetLoaderMaterials()
    {
      csRef<iMaterialLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMaterialWrapper, iMaterialLoaderIterator>(&loaderMaterials, &materialsLock));
      return csPtr<iMaterialLoaderIterator>(itr);
    }
    virtual csPtr<iSharedVarLoaderIterator> GetLoaderSharedVariables()
    {
      csRef<iSharedVarLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iSharedVariable, iSharedVarLoaderIterator>(&loaderSharedVariables, &sharedvarLock));
      return csPtr<iSharedVarLoaderIterator>(itr);
    }

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadImage, csLoaderReturn, const char*, fname,
      int, Format, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadImage, csLoaderReturn, iDataBuffer*, buf,
      int, Format, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL5(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Filename,
    int, Flags, csRef<iTextureManager>, texman, csRef<iImage>*, image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL5(csThreadedLoader, LoadTexture, csLoaderReturn, iDataBuffer*, buf,
    int, Flags, iTextureManager*, texman, csRef<iImage>*, image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL8(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Name,
    iDataBuffer*, buf, int, Flags, iTextureManager*, texman, bool, reg, bool, create_material, bool,
    free_image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL10(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Name,
    const char*, FileName, int, Flags, iTextureManager*, texman, bool, reg, bool, create_material,
    bool, free_image, iCollection*, Collection, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL2(csThreadedLoader, LoadSoundSysData, csLoaderReturn, const char*, fname,
    bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadSoundStream, csLoaderReturn, const char*, fname,
    int, mode3d, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadSoundWrapper, csLoaderReturn, const char*, name,
    const char*, fname, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadMeshObjectFactory, csLoaderReturn, const char*, fname,
    iStreamSource*, ssource, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadMeshObject, csLoaderReturn, const char*, fname,
    iStreamSource*, ssource, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadShader, csLoaderReturn, const char*, filename,
    bool, registerShader, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL7(csThreadedLoader, LoadMapFile, csLoaderReturn, const char*, filename,
    bool, clearEngine, iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL7(csThreadedLoader, LoadMap, csLoaderReturn, iDocumentNode*, world_node,
    bool, clearEngine, iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadLibraryFile, csLoaderReturn, const char*, filename,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadLibrary, csLoaderReturn, iDocumentNode*, lib_node,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadFile, csLoaderReturn, const char*, fname,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadBuffer, csLoaderReturn, iDataBuffer*, buffer,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadNode, csLoaderReturn, csRef<iDocumentNode>,
    node, csRef<iCollection>, collection, csRef<iStreamSource>, ssource, csRef<iMissingLoaderData>,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    void AddSectorToList(iSector* obj)
    {
      CS::Threading::MutexScopedLock lock(sectorsLock);
      loaderSectors.Push(obj);
      obj->DecRef(); // Compensate for CreateSector IncRef().
    }

    void AddMeshFactToList(iMeshFactoryWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(meshfactsLock);
      loaderMeshFactories.Push(obj);
    }

    void AddMeshToList(iMeshWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(meshesLock);
      loaderMeshes.Push(obj);
    }

    void AddCamposToList(iCameraPosition* obj)
    {
      CS::Threading::MutexScopedLock lock(camposLock);
      loaderCameraPositions.Push(obj);
    }

    void AddTextureToList(iTextureWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(texturesLock);
      loaderTextures.Push(obj);
    }

    void AddMaterialToList(iMaterialWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(materialsLock);
      loaderMaterials.Push(obj);
    }

    void AddSharedVarToList(iSharedVariable* obj)
    {
      CS::Threading::MutexScopedLock lock(sharedvarLock);
      loaderSharedVariables.Push(obj);
    }

    void AddLightToList(iLight* obj, const char* name)
    {
      CS::Threading::MutexScopedLock lock(lightsLock);
      loadedLights.Put(csString(name), obj);
    }

  protected:

    friend class csLoaderContext;

    // Shared lists and locks.
    CS::Threading::Mutex sectorsLock;
    CS::Threading::Mutex meshfactsLock;
    CS::Threading::Mutex meshesLock;
    CS::Threading::Mutex camposLock;
    CS::Threading::Mutex texturesLock;
    CS::Threading::Mutex materialsLock;
    CS::Threading::Mutex sharedvarLock;
    CS::Threading::Mutex lightsLock;

    // Final objects.
    csRefArray<iSector> loaderSectors;
    csRefArray<iMeshFactoryWrapper> loaderMeshFactories;
    csRefArray<iMeshWrapper> loaderMeshes;
    csRefArray<iCameraPosition> loaderCameraPositions;
    csRefArray<iTextureWrapper> loaderTextures;
    csRefArray<iMaterialWrapper> loaderMaterials;
    csRefArray<iSharedVariable> loaderSharedVariables;
    csWeakRefHash<iLight, csString> loadedLights;

    // General loading objects.
    csHash<csRef<iThreadReturn>, const char*> loadingMeshObjects;
    CS::Threading::Mutex loadingMeshObjectsLock;

    void AddLoadingMeshObject(const char* name, csRef<iThreadReturn> itr)
    {
      CS::Threading::MutexScopedLock lock(loadingMeshObjectsLock);
      if(!FindLoadedMeshObject(name))
      {
        loadingMeshObjects.Put(name, itr);
      }
    }

    bool FindLoadedMeshObject(const char* name)
    {
      CS::Threading::MutexScopedLock lock(meshesLock);
      for(size_t i=0; i<loaderMeshes.GetSize(); i++)
      {
        if(csString(name).Compare(loaderMeshes[i]->QueryObject()->GetName()))
        {
          return true;
        }
      }

      return false;
    }

    void RemoveLoadingMeshObject(const char* name, csRef<iThreadReturn> itr)
    {
      CS::Threading::MutexScopedLock lock(loadingMeshObjectsLock);
      loadingMeshObjects.Delete(name, itr);
    }

    // Loading texture objects.
    csArray<const char*> loadingTextures;
    CS::Threading::RecursiveMutex loadingTexturesLock;

    bool AddLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      if(!FindLoadingTexture(name))
      {
        loadingTextures.Push(name);
        return true;
      }
      return false;
    }

    bool FindLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      return loadingTextures.Find(name) != csArrayItemNotFound;
    }

    void RemoveLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      loadingTextures.Delete(name);
    }

    // Loading material objects.
    csArray<const char*> loadingMaterials;
    CS::Threading::RecursiveMutex loadingMaterialsLock;

    bool AddLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      if(!FindLoadingMaterial(name))
      {
        loadingMaterials.Push(name);
        return true;
      }
      return false;
    }

    bool FindLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      return loadingMaterials.Find(name) != csArrayItemNotFound;
    }

    void RemoveLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      loadingMaterials.Delete(name);
    }

    // Loading meshfact objects.
    csArray<const char*> loadingMeshFacts;<commit_msg>- A few type changes.<commit_after>/*
    Copyright (C) 2000-2001 by <NAME>
    Copyright (C) 1998-2000 by <NAME> <<EMAIL>>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_THREADED_LOADER_H__
#define __CS_THREADED_LOADER_H__

#include "csutil/cscolor.h"
#include "csutil/threadmanager.h"
#include "csutil/scf_implementation.h"
#include "csutil/strhash.h"
#include "csutil/weakrefarr.h"
#include "csutil/weakrefhash.h"

#include "iengine/campos.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/portal.h"
#include "iengine/sector.h"
#include "iengine/sharevar.h"
#include "imap/ldrctxt.h"
#include "imap/loader.h"
#include "isndsys/ss_loader.h"
#include "isndsys/ss_manager.h"
#include "isndsys/ss_renderer.h"
#include "iutil/comp.h"
#include "iutil/object.h"
#include "ivaria/engseq.h"

#include "ldrplug.h"
#include "proxyimage.h"

class csReversibleTransform;
struct iCollection;
struct iDocumentNode;
struct iEngine;
struct iImageIO;
struct iImposter;
struct iLODControl;
struct iMapNode;
struct iObjectModel;
struct iObjectRegistry;
struct iSceneNodeArray;
struct iShaderVarStringSet;
struct iStringSet;
struct iSyntaxService;
struct iTriangleMesh;
struct iVFS;

CS_PLUGIN_NAMESPACE_BEGIN(csparser)
{
  class csLoaderContext;

  template<class T, class Interface>
  class csLoaderIterator : public scfImplementation1<csLoaderIterator<T, Interface>,
                                                     Interface>
  {
  public:
    csLoaderIterator(csRefArray<T>* objects, CS::Threading::Mutex* lock) :
        scfImplementation1<csLoaderIterator<T, Interface>,
                           Interface> (this),
        lock(*lock), objects(objects), itr(objects->GetIterator())
        {
        }

        virtual ~csLoaderIterator()
        {
          objects->Empty();
        }

        T* Next()
        {
          return itr.Next();
        }

        bool HasNext() const
        {
          return itr.HasNext();
        }

  private:
    CS::Threading::MutexScopedLock lock;
    csRefArray<T>* objects;
    typename csRefArray<T>::Iterator itr;
  };

  class csThreadedLoader : public ThreadedCallable<csThreadedLoader>,
                           public scfImplementation3<csThreadedLoader,
                                                     iThreadedLoader,
                                                     iComponent,
                                                     iEventHandler>
  {
    typedef csThreadedLoader ThisType;
  public:
    csThreadedLoader(iBase *p);
    virtual ~csThreadedLoader();

    bool HandleEvent(iEvent&);
    CS_EVENTHANDLER_NAMES("crystalspace.level.loader.threaded")
    CS_EVENTHANDLER_NIL_CONSTRAINTS

    virtual bool Initialize(iObjectRegistry *object_reg);

    iObjectRegistry* GetObjectRegistry() const { return object_reg; }

    virtual csPtr<iSectorLoaderIterator> GetLoaderSectors()
    {
      csRef<iSectorLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iSector, iSectorLoaderIterator>(&loaderSectors, &sectorsLock));
      return csPtr<iSectorLoaderIterator>(itr);
    }
    virtual csPtr<iMeshFactLoaderIterator> GetLoaderMeshFactories()
    {
      csRef<iMeshFactLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMeshFactoryWrapper, iMeshFactLoaderIterator>(&loaderMeshFactories, &meshfactsLock));
      return csPtr<iMeshFactLoaderIterator>(itr);
    }
    virtual csPtr<iMeshLoaderIterator> GetLoaderMeshes()
    {
      csRef<iMeshLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMeshWrapper, iMeshLoaderIterator>(&loaderMeshes, &meshesLock));
      return csPtr<iMeshLoaderIterator>(itr);
    }
    virtual csPtr<iCamposLoaderIterator> GetLoaderCameraPositions()
    {
      csRef<iCamposLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iCameraPosition, iCamposLoaderIterator>(&loaderCameraPositions, &camposLock));
      return csPtr<iCamposLoaderIterator>(itr);
    }
    virtual csPtr<iTextureLoaderIterator> GetLoaderTextures()
    {
      csRef<iTextureLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iTextureWrapper, iTextureLoaderIterator>(&loaderTextures, &texturesLock));
      return csPtr<iTextureLoaderIterator>(itr);
    }
    virtual csPtr<iMaterialLoaderIterator> GetLoaderMaterials()
    {
      csRef<iMaterialLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iMaterialWrapper, iMaterialLoaderIterator>(&loaderMaterials, &materialsLock));
      return csPtr<iMaterialLoaderIterator>(itr);
    }
    virtual csPtr<iSharedVarLoaderIterator> GetLoaderSharedVariables()
    {
      csRef<iSharedVarLoaderIterator> itr;
      itr.AttachNew(new csLoaderIterator<iSharedVariable, iSharedVarLoaderIterator>(&loaderSharedVariables, &sharedvarLock));
      return csPtr<iSharedVarLoaderIterator>(itr);
    }

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadImage, csLoaderReturn, const char*, fname,
      int, Format, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadImage, csLoaderReturn, iDataBuffer*, buf,
      int, Format, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL5(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Filename,
    int, Flags, csRef<iTextureManager>, texman, csRef<iImage>*, image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL5(csThreadedLoader, LoadTexture, csLoaderReturn, iDataBuffer*, buf,
    int, Flags, iTextureManager*, texman, csRef<iImage>*, image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL8(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Name,
    iDataBuffer*, buf, int, Flags, iTextureManager*, texman, bool, reg, bool, create_material, bool,
    free_image, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL10(csThreadedLoader, LoadTexture, csLoaderReturn, const char*, Name,
    const char*, FileName, int, Flags, iTextureManager*, texman, bool, reg, bool, create_material,
    bool, free_image, iCollection*, Collection, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL2(csThreadedLoader, LoadSoundSysData, csLoaderReturn, const char*, fname,
    bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadSoundStream, csLoaderReturn, const char*, fname,
    int, mode3d, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadSoundWrapper, csLoaderReturn, const char*, name,
    const char*, fname, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadMeshObjectFactory, csLoaderReturn, const char*, fname,
    iStreamSource*, ssource, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadMeshObject, csLoaderReturn, const char*, fname,
    iStreamSource*, ssource, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL3(csThreadedLoader, LoadShader, csLoaderReturn, const char*, filename,
    bool, registerShader, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL7(csThreadedLoader, LoadMapFile, csLoaderReturn, const char*, filename,
    bool, clearEngine, iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL7(csThreadedLoader, LoadMap, csLoaderReturn, iDocumentNode*, world_node,
    bool, clearEngine, iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadLibraryFile, csLoaderReturn, const char*, filename,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadLibrary, csLoaderReturn, iDocumentNode*, lib_node,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadFile, csLoaderReturn, const char*, fname,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadBuffer, csLoaderReturn, iDataBuffer*, buffer,
    iCollection*, collection, iStreamSource*, ssource, iMissingLoaderData*, missingdata, uint,
    keepFlags, bool, do_verbose, THREADED, false, false)

    THREADED_CALLABLE_DECL6(csThreadedLoader, LoadNode, csLoaderReturn, csRef<iDocumentNode>,
    node, csRef<iCollection>, collection, csRef<iStreamSource>, ssource, csRef<iMissingLoaderData>,
    missingdata, uint, keepFlags, bool, do_verbose, THREADED, false, false)

    void AddSectorToList(iSector* obj)
    {
      CS::Threading::MutexScopedLock lock(sectorsLock);
      loaderSectors.Push(obj);
      obj->DecRef(); // Compensate for CreateSector IncRef().
    }

    void AddMeshFactToList(iMeshFactoryWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(meshfactsLock);
      loaderMeshFactories.Push(obj);
    }

    void AddMeshToList(iMeshWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(meshesLock);
      loaderMeshes.Push(obj);
    }

    void AddCamposToList(iCameraPosition* obj)
    {
      CS::Threading::MutexScopedLock lock(camposLock);
      loaderCameraPositions.Push(obj);
    }

    void AddTextureToList(iTextureWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(texturesLock);
      loaderTextures.Push(obj);
    }

    void AddMaterialToList(iMaterialWrapper* obj)
    {
      CS::Threading::MutexScopedLock lock(materialsLock);
      loaderMaterials.Push(obj);
    }

    void AddSharedVarToList(iSharedVariable* obj)
    {
      CS::Threading::MutexScopedLock lock(sharedvarLock);
      loaderSharedVariables.Push(obj);
    }

    void AddLightToList(iLight* obj, const char* name)
    {
      CS::Threading::MutexScopedLock lock(lightsLock);
      loadedLights.Put(csString(name), obj);
    }

  protected:

    friend class csLoaderContext;

    // Shared lists and locks.
    CS::Threading::Mutex sectorsLock;
    CS::Threading::Mutex meshfactsLock;
    CS::Threading::Mutex meshesLock;
    CS::Threading::Mutex camposLock;
    CS::Threading::Mutex texturesLock;
    CS::Threading::Mutex materialsLock;
    CS::Threading::Mutex sharedvarLock;
    CS::Threading::Mutex lightsLock;

    // Final objects.
    csRefArray<iSector> loaderSectors;
    csRefArray<iMeshFactoryWrapper> loaderMeshFactories;
    csRefArray<iMeshWrapper> loaderMeshes;
    csRefArray<iCameraPosition> loaderCameraPositions;
    csRefArray<iTextureWrapper> loaderTextures;
    csRefArray<iMaterialWrapper> loaderMaterials;
    csRefArray<iSharedVariable> loaderSharedVariables;
    csWeakRefHash<iLight, csString> loadedLights;

    // General loading objects.
    csHash<csRef<iThreadReturn>, csString> loadingMeshObjects;
    CS::Threading::Mutex loadingMeshObjectsLock;

    void AddLoadingMeshObject(const char* name, csRef<iThreadReturn> itr)
    {
      CS::Threading::MutexScopedLock lock(loadingMeshObjectsLock);
      if(!FindLoadedMeshObject(name))
      {
        loadingMeshObjects.Put(name, itr);
      }
    }

    bool FindLoadedMeshObject(const char* name)
    {
      CS::Threading::MutexScopedLock lock(meshesLock);
      for(size_t i=0; i<loaderMeshes.GetSize(); i++)
      {
        if(csString(name).Compare(loaderMeshes[i]->QueryObject()->GetName()))
        {
          return true;
        }
      }

      return false;
    }

    void RemoveLoadingMeshObject(const char* name, csRef<iThreadReturn> itr)
    {
      CS::Threading::MutexScopedLock lock(loadingMeshObjectsLock);
      loadingMeshObjects.Delete(name, itr);
    }

    // Loading texture objects.
    csArray<csString> loadingTextures;
    CS::Threading::RecursiveMutex loadingTexturesLock;

    bool AddLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      if(!FindLoadingTexture(name))
      {
        loadingTextures.Push(name);
        return true;
      }
      return false;
    }

    bool FindLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      return loadingTextures.Find(name) != csArrayItemNotFound;
    }

    void RemoveLoadingTexture(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingTexturesLock);
      loadingTextures.Delete(name);
    }

    // Loading material objects.
    csArray<csString> loadingMaterials;
    CS::Threading::RecursiveMutex loadingMaterialsLock;

    bool AddLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      if(!FindLoadingMaterial(name))
      {
        loadingMaterials.Push(name);
        return true;
      }
      return false;
    }

    bool FindLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      return loadingMaterials.Find(name) != csArrayItemNotFound;
    }

    void RemoveLoadingMaterial(const char* name)
    {
      CS::Threading::RecursiveMutexScopedLock lock(loadingMaterialsLock);
      loadingMaterials.Delete(name);
    }

    // Loading meshfact objects.
    csArray<csString> loadingMeshFacts;
{'fraction_non_alphanumeric': 0.09459364206668076, 'fraction_numerical': 0.003524353281172905, 'mean_word_length': 4.146925448938871, 'pattern_counts': {'":': 0, '<': 133, '<?xml version=': 0, '>': 141, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '110596', 'n_tokens_mistral': 8721, 'n_tokens_neox': 8514, 'n_words': 1799}