<commit_before>/*************************************************************************
 *
 *  $RCSfile: xmlxtimp.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hjs $ $Date: 2001-09-12 13:05:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_XMLXTIMP_HXX
#define _SVX_XMLXTIMP_HXX

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

namespace rtl { class OUString; }
namespace com { namespace sun { namespace star {
    namespace uno { template<class X> class Reference; }
    namespace uno { class XInterface; }
    namespace document { class XGraphicObjectResolver; }
    namespace container { class XNameContainer; }

} } }

class SvxXMLXTableImport : public SvXMLImport
{
public:
    SvxXMLXTableImport( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > & rTable,
                        com::sun::star::uno::Reference< com::sun::star::document::XGraphicObjectResolver >& xGrfResolver);
    virtual ~SvxXMLXTableImport() throw ();

    static sal_Bool load( const rtl::OUString& rUrl, const com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >& xTable ) throw();
protected:
    virtual SvXMLImportContext *CreateContext( sal_uInt16 nPrefix,
                                      const ::rtl::OUString& rLocalName,
                                      const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

private:
    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > & mrTable;
};

#endif

<commit_msg>INTEGRATION: CWS binfilter (1.3.332); FILE MERGED 2003/07/08 17:22:46 aw 1.3.332.1: #110680#<commit_after>/*************************************************************************
 *
 *  $RCSfile: xmlxtimp.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-03 13:27:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVX_XMLXTIMP_HXX
#define _SVX_XMLXTIMP_HXX

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

namespace rtl { class OUString; }
namespace com { namespace sun { namespace star {
    namespace uno { template<class X> class Reference; }
    namespace uno { class XInterface; }
    namespace document { class XGraphicObjectResolver; }
    namespace container { class XNameContainer; }

} } }

class SvxXMLXTableImport : public SvXMLImport
{
public:
    // #110680#
    SvxXMLXTableImport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
        const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > & rTable,
        com::sun::star::uno::Reference< com::sun::star::document::XGraphicObjectResolver >& xGrfResolver);

    virtual ~SvxXMLXTableImport() throw ();

    static sal_Bool load( const rtl::OUString& rUrl, const com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >& xTable ) throw();
protected:
    virtual SvXMLImportContext *CreateContext( sal_uInt16 nPrefix,
                                      const ::rtl::OUString& rLocalName,
                                      const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

private:
    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > & mrTable;
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: barcfg.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 08:59:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef SW_BARCFG_HXX
#define SW_BARCFG_HXX

#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif

class CfgUSHORTTable;

class SwToolbarConfigItem : public utl::ConfigItem
{
    sal_uInt16          aTbxIdArray[5];

    com::sun::star::uno::Sequence<rtl::OUString> GetPropertyNames();

public:
    SwToolbarConfigItem( sal_Bool bWeb );
    ~SwToolbarConfigItem();

    virtual void            Commit();

    void        SetTopToolbar( sal_Int32 nSelType, sal_uInt16 nBarId );
    sal_uInt16  GetTopToolbar( sal_Int32 nSelType );    //USHRT_MAX: noch nicht eingetragen
};

#endif
<commit_msg>INTEGRATION: CWS writercorehandoff (1.3.1324); FILE MERGED 2005/09/13 17:12:47 tra 1.3.1324.2: RESYNC: (1.3-1.4); FILE MERGED 2005/06/07 14:15:39 fme 1.3.1324.1: #i50348# General cleanup - removed unused header files, functions, members, declarations etc.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: barcfg.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 17:38:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef SW_BARCFG_HXX
#define SW_BARCFG_HXX
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif

class SwToolbarConfigItem : public utl::ConfigItem
{
    sal_uInt16          aTbxIdArray[5];

    com::sun::star::uno::Sequence<rtl::OUString> GetPropertyNames();

public:
    SwToolbarConfigItem( sal_Bool bWeb );
    ~SwToolbarConfigItem();

    virtual void            Commit();

    void        SetTopToolbar( sal_Int32 nSelType, sal_uInt16 nBarId );
    sal_uInt16  GetTopToolbar( sal_Int32 nSelType );    //USHRT_MAX: noch nicht eingetragen
};

#endif
<|endoftext|>


<commit_before>#include <ruby.h>

#include "leveldb/db.h"
#include "leveldb/slice.h"

static VALUE m_leveldb;
static VALUE c_db;
static VALUE c_error;

// support 1.9 and 1.8
#ifndef RSTRING_PTR
#define RSTRING_PTR(v) RSTRING(v)->ptr
#endif

// convert status errors into exceptions
#define RAISE_ON_ERROR(status) do { \
  if(!status.ok()) { \
    VALUE exc = rb_exc_new2(c_error, status.ToString().c_str()); \
    rb_exc_raise(exc); \
  }  \
} while(0)

typedef struct bound_db {
  leveldb::DB* db;
} bound_db;

static void db_free(bound_db* db) {
  delete db->db;
}

static VALUE db_make(VALUE klass, VALUE v_pathname, VALUE v_create_if_necessary, VALUE v_break_if_exists) {
  Check_Type(v_pathname, T_STRING);

  bound_db* db = new bound_db;
  char* pathname_c = RSTRING_PTR(v_pathname);
  std::string pathname = std::string((char*)RSTRING_PTR(v_pathname));

  leveldb::Options options;
  if(RTEST(v_create_if_necessary)) options.create_if_missing = true;
  if(RTEST(v_break_if_exists)) options.error_if_exists = true;
  leveldb::Status status = leveldb::DB::Open(options, pathname, &db->db);
  RAISE_ON_ERROR(status);

  VALUE o_db = Data_Wrap_Struct(klass, NULL, db_free, db);
  VALUE argv[1] = { v_pathname };
  rb_obj_call_init(o_db, 1, argv);

  return o_db;
}

static VALUE db_close(VALUE self) {
  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  db_free(db);
  return Qtrue;
}

#define RUBY_STRING_TO_SLICE(x) leveldb::Slice(RSTRING_PTR(x), RSTRING_LEN(x))
#define SLICE_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
#define STRING_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
static VALUE db_get(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
  if(status.IsNotFound()) return Qnil;

  RAISE_ON_ERROR(status);
  return STRING_TO_RUBY_STRING(value);
}

static VALUE db_delete(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);

  if(status.IsNotFound()) return Qnil;

  status = db->db->Delete(leveldb::WriteOptions(), key);
  RAISE_ON_ERROR(status);

  return STRING_TO_RUBY_STRING(value);
}

static VALUE db_exists(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);

  if(status.IsNotFound()) return Qfalse;
  return Qtrue;
}

static VALUE db_put(VALUE self, VALUE v_key, VALUE v_value) {
  Check_Type(v_key, T_STRING);
  Check_Type(v_value, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  leveldb::Slice value = RUBY_STRING_TO_SLICE(v_value);
  leveldb::Status status = db->db->Put(leveldb::WriteOptions(), key, value);

  RAISE_ON_ERROR(status);

  return v_value;
}

static VALUE db_size(VALUE self) {
  long count = 0;

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);
  leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());

  // apparently this is how we have to do it. slow and painful!
  for (it->SeekToFirst(); it->Valid(); it->Next()) count++;
  RAISE_ON_ERROR(it->status());
  delete it;
  return INT2NUM(count);
}

static VALUE db_each(VALUE self) {
  bound_db* db;
  Data_Get_Struct(self, bound_db, db);
  leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());

  for (it->SeekToFirst(); it->Valid(); it->Next()) {
    VALUE key = SLICE_TO_RUBY_STRING(it->key());
    VALUE value = SLICE_TO_RUBY_STRING(it->value());
    VALUE ary = rb_ary_new2(2);
    rb_ary_push(ary, key);
    rb_ary_push(ary, value);
    rb_yield(ary);
  }

  RAISE_ON_ERROR(it->status());
  delete it;

  return self;
}

static VALUE db_init(VALUE self, VALUE v_pathname) {
  rb_iv_set(self, "@pathname", v_pathname);
  return self;
}

extern "C" {
void Init_leveldb() {
  VALUE m_leveldb;

  m_leveldb = rb_define_module("LevelDB");

  c_db = rb_define_class_under(m_leveldb, "DB", rb_cObject);
  rb_define_singleton_method(c_db, "make", (VALUE (*)(...))db_make, 3);
  rb_define_method(c_db, "initialize", (VALUE (*)(...))db_init, 1);
  rb_define_method(c_db, "get", (VALUE (*)(...))db_get, 1);
  rb_define_method(c_db, "delete", (VALUE (*)(...))db_delete, 1);
  rb_define_method(c_db, "put", (VALUE (*)(...))db_put, 2);
  rb_define_method(c_db, "exists?", (VALUE (*)(...))db_exists, 1);
  rb_define_method(c_db, "close", (VALUE (*)(...))db_close, 0);
  rb_define_method(c_db, "size", (VALUE (*)(...))db_size, 0);
  rb_define_method(c_db, "each", (VALUE (*)(...))db_each, 0);

  c_error = rb_define_class_under(m_leveldb, "Error", rb_eStandardError);
}
}
<commit_msg>bugfix: don't double-free memory when close() is called<commit_after>#include <ruby.h>

#include "leveldb/db.h"
#include "leveldb/slice.h"

static VALUE m_leveldb;
static VALUE c_db;
static VALUE c_error;

// support 1.9 and 1.8
#ifndef RSTRING_PTR
#define RSTRING_PTR(v) RSTRING(v)->ptr
#endif

// convert status errors into exceptions
#define RAISE_ON_ERROR(status) do { \
  if(!status.ok()) { \
    VALUE exc = rb_exc_new2(c_error, status.ToString().c_str()); \
    rb_exc_raise(exc); \
  }  \
} while(0)

typedef struct bound_db {
  leveldb::DB* db;
} bound_db;

static void db_free(bound_db* db) {
  if(db->db != NULL) {
    delete db->db;
    db->db = NULL;
  }
  delete db;
}

static VALUE db_make(VALUE klass, VALUE v_pathname, VALUE v_create_if_necessary, VALUE v_break_if_exists) {
  Check_Type(v_pathname, T_STRING);

  bound_db* db = new bound_db;
  char* pathname_c = RSTRING_PTR(v_pathname);
  std::string pathname = std::string((char*)RSTRING_PTR(v_pathname));

  leveldb::Options options;
  if(RTEST(v_create_if_necessary)) options.create_if_missing = true;
  if(RTEST(v_break_if_exists)) options.error_if_exists = true;
  leveldb::Status status = leveldb::DB::Open(options, pathname, &db->db);
  RAISE_ON_ERROR(status);

  VALUE o_db = Data_Wrap_Struct(klass, NULL, db_free, db);
  VALUE argv[1] = { v_pathname };
  rb_obj_call_init(o_db, 1, argv);

  return o_db;
}

static VALUE db_close(VALUE self) {
  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  if(db->db != NULL) {
    delete db->db;
    db->db = NULL;
  }
  return Qtrue;
}

#define RUBY_STRING_TO_SLICE(x) leveldb::Slice(RSTRING_PTR(x), RSTRING_LEN(x))
#define SLICE_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
#define STRING_TO_RUBY_STRING(x) rb_str_new(x.data(), x.size())
static VALUE db_get(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);
  if(status.IsNotFound()) return Qnil;

  RAISE_ON_ERROR(status);
  return STRING_TO_RUBY_STRING(value);
}

static VALUE db_delete(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);

  if(status.IsNotFound()) return Qnil;

  status = db->db->Delete(leveldb::WriteOptions(), key);
  RAISE_ON_ERROR(status);

  return STRING_TO_RUBY_STRING(value);
}

static VALUE db_exists(VALUE self, VALUE v_key) {
  Check_Type(v_key, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  std::string value;
  leveldb::Status status = db->db->Get(leveldb::ReadOptions(), key, &value);

  if(status.IsNotFound()) return Qfalse;
  return Qtrue;
}

static VALUE db_put(VALUE self, VALUE v_key, VALUE v_value) {
  Check_Type(v_key, T_STRING);
  Check_Type(v_value, T_STRING);

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);

  leveldb::Slice key = RUBY_STRING_TO_SLICE(v_key);
  leveldb::Slice value = RUBY_STRING_TO_SLICE(v_value);
  leveldb::Status status = db->db->Put(leveldb::WriteOptions(), key, value);

  RAISE_ON_ERROR(status);

  return v_value;
}

static VALUE db_size(VALUE self) {
  long count = 0;

  bound_db* db;
  Data_Get_Struct(self, bound_db, db);
  leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());

  // apparently this is how we have to do it. slow and painful!
  for (it->SeekToFirst(); it->Valid(); it->Next()) count++;
  RAISE_ON_ERROR(it->status());
  delete it;
  return INT2NUM(count);
}

static VALUE db_each(VALUE self) {
  bound_db* db;
  Data_Get_Struct(self, bound_db, db);
  leveldb::Iterator* it = db->db->NewIterator(leveldb::ReadOptions());

  for (it->SeekToFirst(); it->Valid(); it->Next()) {
    VALUE key = SLICE_TO_RUBY_STRING(it->key());
    VALUE value = SLICE_TO_RUBY_STRING(it->value());
    VALUE ary = rb_ary_new2(2);
    rb_ary_push(ary, key);
    rb_ary_push(ary, value);
    rb_yield(ary);
  }

  RAISE_ON_ERROR(it->status());
  delete it;

  return self;
}

static VALUE db_init(VALUE self, VALUE v_pathname) {
  rb_iv_set(self, "@pathname", v_pathname);
  return self;
}

extern "C" {
void Init_leveldb() {
  VALUE m_leveldb;

  m_leveldb = rb_define_module("LevelDB");

  c_db = rb_define_class_under(m_leveldb, "DB", rb_cObject);
  rb_define_singleton_method(c_db, "make", (VALUE (*)(...))db_make, 3);
  rb_define_method(c_db, "initialize", (VALUE (*)(...))db_init, 1);
  rb_define_method(c_db, "get", (VALUE (*)(...))db_get, 1);
  rb_define_method(c_db, "delete", (VALUE (*)(...))db_delete, 1);
  rb_define_method(c_db, "put", (VALUE (*)(...))db_put, 2);
  rb_define_method(c_db, "exists?", (VALUE (*)(...))db_exists, 1);
  rb_define_method(c_db, "close", (VALUE (*)(...))db_close, 0);
  rb_define_method(c_db, "size", (VALUE (*)(...))db_size, 0);
  rb_define_method(c_db, "each", (VALUE (*)(...))db_each, 0);

  c_error = rb_define_class_under(m_leveldb, "Error", rb_eStandardError);
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: colmgr.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 11:55:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _COLMGR_HXX
#define _COLMGR_HXX

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

#ifndef _FMTCLDS_HXX //autogen
#include <fmtclds.hxx>
#endif

SW_DLLPUBLIC void FitToActualSize(SwFmtCol& rCol, USHORT nWidth);

class SW_DLLPUBLIC SwColMgr
{
public:
        // lActWidth wird aus den Edits des Seitendialogs
        // direkt uebergeben
    SwColMgr(const SfxItemSet &rSet, USHORT nActWidth = USHRT_MAX);
    ~SwColMgr();

    inline USHORT       GetCount() const;
    void                SetCount(USHORT nCount, USHORT nGutterWidth);
    USHORT              GetGutterWidth(USHORT nPos = USHRT_MAX) const;
    void                SetGutterWidth(USHORT nWidth, USHORT nPos = USHRT_MAX);

    USHORT              GetColWidth(USHORT nIdx) const;
    void                SetColWidth(USHORT nIdx, USHORT nWidth);

    inline BOOL         IsAutoWidth() const;
    void                SetAutoWidth(BOOL bOn = TRUE, USHORT lGutterWidth = 0);

    inline BOOL         HasLine() const;
    inline void         SetNoLine();

    inline void         SetLineWidthAndColor(ULONG nWidth, const Color& rCol);
    inline ULONG        GetLineWidth() const;
    inline const Color& GetLineColor() const;

    inline SwColLineAdj GetAdjust() const;
    inline void         SetAdjust(SwColLineAdj);

    short               GetLineHeightPercent() const;
    void                SetLineHeightPercent(short nPercent);

    inline void         NoCols();
    void                Update();

    const SwFmtCol&     GetColumns() const { return aFmtCol; }

    void                SetActualWidth(USHORT nW);
    USHORT              GetActualSize() const { return nWidth; }

private:

    SwFmtCol            aFmtCol;
    USHORT              nWidth;
};

// INLINE METHODE --------------------------------------------------------

inline  USHORT SwColMgr::GetCount() const
{
    return aFmtCol.GetNumCols();
}
inline void         SwColMgr::SetLineWidthAndColor(ULONG nLWidth, const Color& rCol)
{
    aFmtCol.SetLineWidth(nLWidth);
    aFmtCol.SetLineColor(rCol);
}
inline ULONG        SwColMgr::GetLineWidth() const
{
    return aFmtCol.GetLineWidth();
}
inline const Color& SwColMgr::GetLineColor() const
{
    return aFmtCol.GetLineColor();
}
inline  SwColLineAdj SwColMgr::GetAdjust() const
{
    return aFmtCol.GetLineAdj();
}
inline  void SwColMgr::SetAdjust(SwColLineAdj eAdj)
{
    aFmtCol.SetLineAdj(eAdj);
}
inline BOOL SwColMgr::IsAutoWidth() const
{
    return aFmtCol.IsOrtho();
}
inline void SwColMgr::SetAutoWidth(BOOL bOn, USHORT nGutterWidth)
{
    aFmtCol.SetOrtho(bOn, nGutterWidth, nWidth);
}
inline void SwColMgr::NoCols()
{
    aFmtCol.GetColumns().DeleteAndDestroy(0, aFmtCol.GetColumns().Count());
}
inline BOOL SwColMgr::HasLine() const
{
    return GetAdjust() != COLADJ_NONE;
}
inline void SwColMgr::SetNoLine()
{
    SetAdjust(COLADJ_NONE);
}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.4.242); FILE MERGED 2008/04/01 12:55:25 thb 1.4.242.2: #i85898# Stripping all external header guards 2008/03/31 16:58:28 rt 1.4.242.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: colmgr.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _COLMGR_HXX
#define _COLMGR_HXX

#include "swdllapi.h"
#include <fmtclds.hxx>

SW_DLLPUBLIC void FitToActualSize(SwFmtCol& rCol, USHORT nWidth);

class SW_DLLPUBLIC SwColMgr
{
public:
        // lActWidth wird aus den Edits des Seitendialogs
        // direkt uebergeben
    SwColMgr(const SfxItemSet &rSet, USHORT nActWidth = USHRT_MAX);
    ~SwColMgr();

    inline USHORT       GetCount() const;
    void                SetCount(USHORT nCount, USHORT nGutterWidth);
    USHORT              GetGutterWidth(USHORT nPos = USHRT_MAX) const;
    void                SetGutterWidth(USHORT nWidth, USHORT nPos = USHRT_MAX);

    USHORT              GetColWidth(USHORT nIdx) const;
    void                SetColWidth(USHORT nIdx, USHORT nWidth);

    inline BOOL         IsAutoWidth() const;
    void                SetAutoWidth(BOOL bOn = TRUE, USHORT lGutterWidth = 0);

    inline BOOL         HasLine() const;
    inline void         SetNoLine();

    inline void         SetLineWidthAndColor(ULONG nWidth, const Color& rCol);
    inline ULONG        GetLineWidth() const;
    inline const Color& GetLineColor() const;

    inline SwColLineAdj GetAdjust() const;
    inline void         SetAdjust(SwColLineAdj);

    short               GetLineHeightPercent() const;
    void                SetLineHeightPercent(short nPercent);

    inline void         NoCols();
    void                Update();

    const SwFmtCol&     GetColumns() const { return aFmtCol; }

    void                SetActualWidth(USHORT nW);
    USHORT              GetActualSize() const { return nWidth; }

private:

    SwFmtCol            aFmtCol;
    USHORT              nWidth;
};

// INLINE METHODE --------------------------------------------------------

inline  USHORT SwColMgr::GetCount() const
{
    return aFmtCol.GetNumCols();
}
inline void         SwColMgr::SetLineWidthAndColor(ULONG nLWidth, const Color& rCol)
{
    aFmtCol.SetLineWidth(nLWidth);
    aFmtCol.SetLineColor(rCol);
}
inline ULONG        SwColMgr::GetLineWidth() const
{
    return aFmtCol.GetLineWidth();
}
inline const Color& SwColMgr::GetLineColor() const
{
    return aFmtCol.GetLineColor();
}
inline  SwColLineAdj SwColMgr::GetAdjust() const
{
    return aFmtCol.GetLineAdj();
}
inline  void SwColMgr::SetAdjust(SwColLineAdj eAdj)
{
    aFmtCol.SetLineAdj(eAdj);
}
inline BOOL SwColMgr::IsAutoWidth() const
{
    return aFmtCol.IsOrtho();
}
inline void SwColMgr::SetAutoWidth(BOOL bOn, USHORT nGutterWidth)
{
    aFmtCol.SetOrtho(bOn, nGutterWidth, nWidth);
}
inline void SwColMgr::NoCols()
{
    aFmtCol.GetColumns().DeleteAndDestroy(0, aFmtCol.GetColumns().Count());
}
inline BOOL SwColMgr::HasLine() const
{
    return GetAdjust() != COLADJ_NONE;
}
inline void SwColMgr::SetNoLine()
{
    SetAdjust(COLADJ_NONE);
}

#endif
<|endoftext|>


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * 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; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "cluceneindexwriter.h"
#include <CLucene.h>
#include <CLucene/store/Lock.h>
#include "cluceneindexreader.h"
#include "cluceneindexmanager.h"
#include <CLucene/util/stringreader.h>
#include <sstream>
#include <assert.h>

#ifdef STRIGI_USE_CLUCENE_COMPRESSEDFIELDS
#include "jsgzipcompressstream.h"
#endif

#include <iostream>

using lucene::document::Document;
using lucene::document::Field;
using lucene::index::IndexWriter;
using lucene::index::Term;
using lucene::index::TermDocs;
using lucene::search::IndexSearcher;
using lucene::search::Hits;
using lucene::util::BitSet;

using lucene::util::Reader;
using namespace std;
using namespace Strigi;

struct CLuceneDocData {
    lucene::document::Document doc;
    std::string content;
};

CLuceneIndexWriter::CLuceneIndexWriter(CLuceneIndexManager* m):
    manager(m), doccount(0) {
    addMapping(_T(""),_T("content"));
}
CLuceneIndexWriter::~CLuceneIndexWriter() {
}
void
CLuceneIndexWriter::addText(const AnalysisResult* idx, const char* text,
        int32_t length) {
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    doc->content.append(text, length);
}

#ifdef _UCS2
typedef map<wstring, wstring> CLuceneIndexWriterFieldMapType;
#else
typedef map<string, string> CLuceneIndexWriterFieldMapType;
#endif
CLuceneIndexWriterFieldMapType CLuceneIndexWriterFieldMap;

void CLuceneIndexWriter::addMapping(const TCHAR* from, const TCHAR* to){
    CLuceneIndexWriterFieldMap[from] = to;
}
const TCHAR*
CLuceneIndexWriter::mapId(const TCHAR* id) {
    if (id == 0) id = _T("");
    CLuceneIndexWriterFieldMapType::iterator itr
        = CLuceneIndexWriterFieldMap.find(id);
    if (itr == CLuceneIndexWriterFieldMap.end()) {
        return id;
    } else {
        return itr->second.c_str();
    }
}
void
CLuceneIndexWriter::addValue(const AnalysisResult* idx,
        AnalyzerConfiguration::FieldType type, const TCHAR* name,
        const TCHAR* value) {
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    Field* field = new Field(name, value,
        (type & AnalyzerConfiguration::Stored) == AnalyzerConfiguration::Stored,
        (type & AnalyzerConfiguration::Indexed) == AnalyzerConfiguration::Indexed,
        (type & AnalyzerConfiguration::Tokenized) == AnalyzerConfiguration::Tokenized);
    doc->doc.add(*field);
}
void
CLuceneIndexWriter::addValue(const AnalysisResult* idx,
        AnalyzerConfiguration::FieldType type, const TCHAR* fn,
        const std::string& value) {
#if defined(_UCS2)
    addValue(idx, type, CLuceneIndexWriter::mapId(fn),
        utf8toucs2(value).c_str());
#else
    addValue(idx, type, CLuceneIndexWriter::mapId(fn), value.c_str());
#endif
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, const std::string& value) {
    AnalyzerConfiguration::FieldType type
        = idx->config().indexType(field);
    if (type == AnalyzerConfiguration::None) return;
#if defined(_UCS2)
    addValue(idx, type, utf8toucs2(field->key()).c_str(), value);
#else
    addValue(idx, type, field->key(), value);
#endif
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, uint32_t value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, int32_t value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field,
        const unsigned char* data, uint32_t size) {
    addValue(idx, field, string((const char*)data, (string::size_type)size));
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, double value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::startAnalysis(const AnalysisResult* idx) {
    doccount++;
    CLuceneDocData*doc = new CLuceneDocData();
    idx->setWriterData(doc);
}
/*
    Close all left open indexwriters for this path.
*/
void
CLuceneIndexWriter::finishAnalysis(const AnalysisResult* idx) {
    const FieldRegister& fr = idx->config().fieldRegister();
    addValue(idx, fr.pathField, idx->path());
    string field = idx->encoding();
    if (field.length()) addValue(idx, fr.encodingField, field);
    field = idx->mimeType();
    if (field.length()) addValue(idx, fr.mimetypeField, field);
    field = idx->fileName();
    if (field.length()) addValue(idx, fr.filenameField, field);
    field = idx->extension();
    if (field.length()) addValue(idx, fr.extensionField, field);
    addValue(idx, fr.embeddepthField, idx->depth());
    addValue(idx, fr.mtimeField, (uint32_t)idx->mTime());
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    wstring c(utf8toucs2(doc->content));
    jstreams::StringReader<char>* sr = NULL; //we use this for compressed streams

    if (doc->content.length() > 0) {
        const TCHAR* mappedFn = mapId(_T(""));
#if defined(_UCS2)
    #ifndef STRIGI_USE_CLUCENE_COMPRESSEDFIELDS
        doc->doc.add(*Field::Text(mappedFn, c.c_str(), false));
    #else
        // lets store the content as utf8. remember, the stream is required
        // until the document is added, so a static construction of stringreader
        // is not good enough
        sr = new jstreams::StringReader<char>(doc->content.c_str(), doc->content.length(), false);

    // add the stored field with the zipstream
    doc->doc.add(*new Field(mappedFn, new jstreams::GZipCompressInputStream(sr),
        Field::STORE_YES));

    // add the tokenized/indexed field
    doc->doc.add(*new Field::Text(mappedFn, c.c_str(),
            Field::STORE_NO | Field::INDEX_TOKENIZED));
    #endif
#else //_UCS2
        doc->doc.add(*Field::Text(mappedFn, doc->content.c_str()) );
#endif
    }
    lucene::index::IndexWriter* writer = manager->refWriter();
    if (writer) {
        try {
            writer->addDocument(&doc->doc);
        } catch (CLuceneError& err) {
            fprintf(stderr, "%s: %s\n", idx->path().c_str(), err.what());
        }
    }
    manager->derefWriter();
    delete doc;
    if ( sr )
        delete sr;
    manager->setIndexMTime();
}
void
CLuceneIndexWriter::deleteEntries(const std::vector<std::string>& entries) {
    manager->closeWriter();
    if (!manager->luceneReader()->checkReader()) {
        fprintf(stderr,"cannot delete entry: lucene reader cannot be opened\n");
        return;
    }
    lucene::index::IndexReader* reader = manager->luceneReader()->reader;

    for (uint i=0; i<entries.size(); ++i) {
        deleteEntry(entries[i], reader);
    }
    reader->commit();
    manager->setIndexMTime();
}
void
CLuceneIndexWriter::deleteEntry(const string& entry,
        lucene::index::IndexReader* reader) {

    wstring tstr(utf8toucs2(entry));
    int32_t prefixLen = tstr.length();
    const TCHAR* prefixText = tstr.c_str();
    int32_t maxdoc = reader->maxDoc();
    for (int32_t i = 0; i < maxdoc; ++i) {
        if (!reader->isDeleted(i)) {
            Document* d = reader->document(i);
            const TCHAR* t = d->get(_T("system.location"));
            if (t && _tcsncmp(t, prefixText, prefixLen) == 0) {
                reader->deleteDocument(i);
            }
            _CLDELETE(d);
        }
    }
}
void
CLuceneIndexWriter::deleteAllEntries() {
    manager->deleteIndex();
}
void
CLuceneIndexWriter::commit() {
    manager->closeWriter();
}

//this function is in 0.9.17, which we do not have yet...
bool isLuceneFile(const char* filename){
    if ( !filename )
        return false;
    size_t len = strlen(filename);
    if ( len < 6 ) //need at least x.frx
        return false;
    const char* ext = filename + len;
    while ( *ext != '.' && ext != filename )
        ext--;

    if ( strcmp(ext, ".cfs") == 0 )
        return true;
    else if ( strcmp(ext, ".fnm") == 0 )
        return true;
    else if ( strcmp(ext, ".fdx") == 0 )
        return true;
    else if ( strcmp(ext, ".fdt") == 0 )
        return true;
    else if ( strcmp(ext, ".tii") == 0 )
        return true;
    else if ( strcmp(ext, ".tis") == 0 )
        return true;
    else if ( strcmp(ext, ".frq") == 0 )
        return true;
    else if ( strcmp(ext, ".prx") == 0 )
        return true;
    else if ( strcmp(ext, ".del") == 0 )
        return true;
    else if ( strcmp(ext, ".tvx") == 0 )
        return true;
    else if ( strcmp(ext, ".tvd") == 0 )
        return true;
    else if ( strcmp(ext, ".tvf") == 0 )
        return true;
    else if ( strcmp(ext, ".tvp") == 0 )
        return true;

    else if ( strcmp(filename, "segments") == 0 )
        return true;
    else if ( strcmp(filename, "segments.new") == 0 )
        return true;
    else if ( strcmp(filename, "deletable") == 0 )
        return true;

    else if ( strncmp(ext,".f",2)==0 ){
        const char* n = ext+2;
        if ( *n && _istdigit(*n) )
            return true;
    }

    return false;
}

void
CLuceneIndexWriter::cleanUp() {
    // remove all unused lucene file elements...
    // unused elements are the result of unexpected shutdowns...
    // this can add up to a lot of after a while.

    lucene::index::IndexReader* reader = manager->luceneReader()->reader;
    if (!reader) {
        return;
    }
    lucene::store::Directory* directory = reader->getDirectory();

    // Instantiate SegmentInfos
    lucene::store::LuceneLock* lock = directory->makeLock("commit.lock");
#ifdef LUCENE_COMMIT_LOCK_TIMEOUT
    // version <0.9.16
    bool locked = lock->obtain(LUCENE_COMMIT_LOCK_TIMEOUT);
#else
    bool locked = lock->obtain(lucene::index::IndexWriter::COMMIT_LOCK_TIMEOUT);
#endif
    if (!locked) {
        return;
    }
    lucene::index::SegmentInfos infos;
    try {
        //Have SegmentInfos read the segments file in directory
        infos.read(directory);
    } catch(...) {
        lock->release();
        return; //todo: this may suggest an error...
    }
    lock->release();

    int i;
    set<string> segments;
    for (i = 0; i < infos.size(); i++) {
            lucene::index::SegmentInfo* info = infos.info(i);
            segments.insert(info->name);
    }

    char** files = directory->list();
    char tmp[CL_MAX_PATH];
    for (i = 0; files[i] != NULL; ++i) {
        char* file = files[i];

        int fileLength = strlen(file);
        if ( fileLength < 6 ) {
            continue;
        }

        if (strncmp(file,"segments", 8) == 0
                || strncmp(file, "deletable", 9) == 0) {
            continue;
        }
        if (!isLuceneFile(file)) {
            continue;
        }

        strcpy(tmp, file);
        tmp[fileLength-4] = '\0';

        if (segments.find(tmp) != segments.end()) {
            continue;
        }

        directory->deleteFile(file, false);
    }
    for (i = 0; files[i] != NULL; i++) {
        _CLDELETE_CaARRAY(files[i]);
    }
    _CLDELETE_ARRAY(files);
}

void
CLuceneIndexWriter::initWriterData(const FieldRegister& f) {
    map<string, RegisteredField*>::const_iterator i;
    map<string, RegisteredField*>::const_iterator end = f.fields().end();
    for (i = f.fields().begin(); i != end; ++i) {
        i->second->setWriterData(0);
    }
}
void
CLuceneIndexWriter::releaseWriterData(const FieldRegister& f) {
    map<string, RegisteredField*>::const_iterator i;
    map<string, RegisteredField*>::const_iterator end = f.fields().end();
    for (i = f.fields().begin(); i != end; ++i) {
        delete static_cast<int*>(i->second->writerData());
    }
}
<commit_msg>catch exception<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * 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; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "cluceneindexwriter.h"
#include <CLucene.h>
#include <CLucene/store/Lock.h>
#include "cluceneindexreader.h"
#include "cluceneindexmanager.h"
#include <CLucene/util/stringreader.h>
#include <sstream>
#include <assert.h>

#ifdef STRIGI_USE_CLUCENE_COMPRESSEDFIELDS
#include "jsgzipcompressstream.h"
#endif

#include <iostream>

using lucene::document::Document;
using lucene::document::Field;
using lucene::index::IndexWriter;
using lucene::index::Term;
using lucene::index::TermDocs;
using lucene::search::IndexSearcher;
using lucene::search::Hits;
using lucene::util::BitSet;

using lucene::util::Reader;
using namespace std;
using namespace Strigi;

struct CLuceneDocData {
    lucene::document::Document doc;
    std::string content;
};

CLuceneIndexWriter::CLuceneIndexWriter(CLuceneIndexManager* m):
    manager(m), doccount(0) {
    addMapping(_T(""),_T("content"));
}
CLuceneIndexWriter::~CLuceneIndexWriter() {
}
void
CLuceneIndexWriter::addText(const AnalysisResult* idx, const char* text,
        int32_t length) {
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    doc->content.append(text, length);
}

#ifdef _UCS2
typedef map<wstring, wstring> CLuceneIndexWriterFieldMapType;
#else
typedef map<string, string> CLuceneIndexWriterFieldMapType;
#endif
CLuceneIndexWriterFieldMapType CLuceneIndexWriterFieldMap;

void CLuceneIndexWriter::addMapping(const TCHAR* from, const TCHAR* to){
    CLuceneIndexWriterFieldMap[from] = to;
}
const TCHAR*
CLuceneIndexWriter::mapId(const TCHAR* id) {
    if (id == 0) id = _T("");
    CLuceneIndexWriterFieldMapType::iterator itr
        = CLuceneIndexWriterFieldMap.find(id);
    if (itr == CLuceneIndexWriterFieldMap.end()) {
        return id;
    } else {
        return itr->second.c_str();
    }
}
void
CLuceneIndexWriter::addValue(const AnalysisResult* idx,
        AnalyzerConfiguration::FieldType type, const TCHAR* name,
        const TCHAR* value) {
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    Field* field = new Field(name, value,
        (type & AnalyzerConfiguration::Stored) == AnalyzerConfiguration::Stored,
        (type & AnalyzerConfiguration::Indexed) == AnalyzerConfiguration::Indexed,
        (type & AnalyzerConfiguration::Tokenized) == AnalyzerConfiguration::Tokenized);
    doc->doc.add(*field);
}
void
CLuceneIndexWriter::addValue(const AnalysisResult* idx,
        AnalyzerConfiguration::FieldType type, const TCHAR* fn,
        const std::string& value) {
#if defined(_UCS2)
    addValue(idx, type, CLuceneIndexWriter::mapId(fn),
        utf8toucs2(value).c_str());
#else
    addValue(idx, type, CLuceneIndexWriter::mapId(fn), value.c_str());
#endif
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, const std::string& value) {
    AnalyzerConfiguration::FieldType type
        = idx->config().indexType(field);
    if (type == AnalyzerConfiguration::None) return;
#if defined(_UCS2)
    addValue(idx, type, utf8toucs2(field->key()).c_str(), value);
#else
    addValue(idx, type, field->key(), value);
#endif
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, uint32_t value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, int32_t value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field,
        const unsigned char* data, uint32_t size) {
    addValue(idx, field, string((const char*)data, (string::size_type)size));
}
void
CLuceneIndexWriter::addValue(const Strigi::AnalysisResult* idx,
        const Strigi::RegisteredField* field, double value) {
    ostringstream o;
    o << value;
    addValue(idx, field, o.str());
}
void
CLuceneIndexWriter::startAnalysis(const AnalysisResult* idx) {
    doccount++;
    CLuceneDocData*doc = new CLuceneDocData();
    idx->setWriterData(doc);
}
/*
    Close all left open indexwriters for this path.
*/
void
CLuceneIndexWriter::finishAnalysis(const AnalysisResult* idx) {
    const FieldRegister& fr = idx->config().fieldRegister();
    addValue(idx, fr.pathField, idx->path());
    string field = idx->encoding();
    if (field.length()) addValue(idx, fr.encodingField, field);
    field = idx->mimeType();
    if (field.length()) addValue(idx, fr.mimetypeField, field);
    field = idx->fileName();
    if (field.length()) addValue(idx, fr.filenameField, field);
    field = idx->extension();
    if (field.length()) addValue(idx, fr.extensionField, field);
    addValue(idx, fr.embeddepthField, idx->depth());
    addValue(idx, fr.mtimeField, (uint32_t)idx->mTime());
    CLuceneDocData* doc = static_cast<CLuceneDocData*>(idx->writerData());
    wstring c(utf8toucs2(doc->content));
    jstreams::StringReader<char>* sr = NULL; //we use this for compressed streams

    if (doc->content.length() > 0) {
        const TCHAR* mappedFn = mapId(_T(""));
#if defined(_UCS2)
    #ifndef STRIGI_USE_CLUCENE_COMPRESSEDFIELDS
        doc->doc.add(*Field::Text(mappedFn, c.c_str(), false));
    #else
        // lets store the content as utf8. remember, the stream is required
        // until the document is added, so a static construction of stringreader
        // is not good enough
        sr = new jstreams::StringReader<char>(doc->content.c_str(), doc->content.length(), false);

    // add the stored field with the zipstream
    doc->doc.add(*new Field(mappedFn, new jstreams::GZipCompressInputStream(sr),
        Field::STORE_YES));

    // add the tokenized/indexed field
    doc->doc.add(*new Field::Text(mappedFn, c.c_str(),
            Field::STORE_NO | Field::INDEX_TOKENIZED));
    #endif
#else //_UCS2
        doc->doc.add(*Field::Text(mappedFn, doc->content.c_str()) );
#endif
    }
    lucene::index::IndexWriter* writer = manager->refWriter();
    if (writer) {
        try {
            writer->addDocument(&doc->doc);
        } catch (CLuceneError& err) {
            fprintf(stderr, "%s: %s\n", idx->path().c_str(), err.what());
        }
    }
    manager->derefWriter();
    delete doc;
    if ( sr )
        delete sr;
    manager->setIndexMTime();
}
void
CLuceneIndexWriter::deleteEntries(const std::vector<std::string>& entries) {
    manager->closeWriter();
    if (!manager->luceneReader()->checkReader()) {
        fprintf(stderr,"cannot delete entry: lucene reader cannot be opened\n");
        return;
    }
    lucene::index::IndexReader* reader = manager->luceneReader()->reader;

    for (uint i=0; i<entries.size(); ++i) {
        deleteEntry(entries[i], reader);
    }
    reader->commit();
    manager->setIndexMTime();
}
void
CLuceneIndexWriter::deleteEntry(const string& entry,
        lucene::index::IndexReader* reader) {

    wstring tstr(utf8toucs2(entry));
    int32_t prefixLen = tstr.length();
    const TCHAR* prefixText = tstr.c_str();
    int32_t maxdoc = reader->maxDoc();
    for (int32_t i = 0; i < maxdoc; ++i) {
        if (!reader->isDeleted(i)) {
            Document* d = reader->document(i);
            const TCHAR* t = d->get(_T("system.location"));
            if (t && _tcsncmp(t, prefixText, prefixLen) == 0) {
                try {
                    reader->deleteDocument(i);
                } catch (...) {
                    fprintf(stderr, "could not delete document");
                }
            }
            _CLDELETE(d);
        }
    }
}
void
CLuceneIndexWriter::deleteAllEntries() {
    manager->deleteIndex();
}
void
CLuceneIndexWriter::commit() {
    manager->closeWriter();
}

//this function is in 0.9.17, which we do not have yet...
bool isLuceneFile(const char* filename){
    if ( !filename )
        return false;
    size_t len = strlen(filename);
    if ( len < 6 ) //need at least x.frx
        return false;
    const char* ext = filename + len;
    while ( *ext != '.' && ext != filename )
        ext--;

    if ( strcmp(ext, ".cfs") == 0 )
        return true;
    else if ( strcmp(ext, ".fnm") == 0 )
        return true;
    else if ( strcmp(ext, ".fdx") == 0 )
        return true;
    else if ( strcmp(ext, ".fdt") == 0 )
        return true;
    else if ( strcmp(ext, ".tii") == 0 )
        return true;
    else if ( strcmp(ext, ".tis") == 0 )
        return true;
    else if ( strcmp(ext, ".frq") == 0 )
        return true;
    else if ( strcmp(ext, ".prx") == 0 )
        return true;
    else if ( strcmp(ext, ".del") == 0 )
        return true;
    else if ( strcmp(ext, ".tvx") == 0 )
        return true;
    else if ( strcmp(ext, ".tvd") == 0 )
        return true;
    else if ( strcmp(ext, ".tvf") == 0 )
        return true;
    else if ( strcmp(ext, ".tvp") == 0 )
        return true;

    else if ( strcmp(filename, "segments") == 0 )
        return true;
    else if ( strcmp(filename, "segments.new") == 0 )
        return true;
    else if ( strcmp(filename, "deletable") == 0 )
        return true;

    else if ( strncmp(ext,".f",2)==0 ){
        const char* n = ext+2;
        if ( *n && _istdigit(*n) )
            return true;
    }

    return false;
}

void
CLuceneIndexWriter::cleanUp() {
    // remove all unused lucene file elements...
    // unused elements are the result of unexpected shutdowns...
    // this can add up to a lot of after a while.

    lucene::index::IndexReader* reader = manager->luceneReader()->reader;
    if (!reader) {
        return;
    }
    lucene::store::Directory* directory = reader->getDirectory();

    // Instantiate SegmentInfos
    lucene::store::LuceneLock* lock = directory->makeLock("commit.lock");
#ifdef LUCENE_COMMIT_LOCK_TIMEOUT
    // version <0.9.16
    bool locked = lock->obtain(LUCENE_COMMIT_LOCK_TIMEOUT);
#else
    bool locked = lock->obtain(lucene::index::IndexWriter::COMMIT_LOCK_TIMEOUT);
#endif
    if (!locked) {
        return;
    }
    lucene::index::SegmentInfos infos;
    try {
        //Have SegmentInfos read the segments file in directory
        infos.read(directory);
    } catch(...) {
        lock->release();
        return; //todo: this may suggest an error...
    }
    lock->release();

    int i;
    set<string> segments;
    for (i = 0; i < infos.size(); i++) {
            lucene::index::SegmentInfo* info = infos.info(i);
            segments.insert(info->name);
    }

    char** files = directory->list();
    char tmp[CL_MAX_PATH];
    for (i = 0; files[i] != NULL; ++i) {
        char* file = files[i];

        int fileLength = strlen(file);
        if ( fileLength < 6 ) {
            continue;
        }

        if (strncmp(file,"segments", 8) == 0
                || strncmp(file, "deletable", 9) == 0) {
            continue;
        }
        if (!isLuceneFile(file)) {
            continue;
        }

        strcpy(tmp, file);
        tmp[fileLength-4] = '\0';

        if (segments.find(tmp) != segments.end()) {
            continue;
        }

        directory->deleteFile(file, false);
    }
    for (i = 0; files[i] != NULL; i++) {
        _CLDELETE_CaARRAY(files[i]);
    }
    _CLDELETE_ARRAY(files);
}

void
CLuceneIndexWriter::initWriterData(const FieldRegister& f) {
    map<string, RegisteredField*>::const_iterator i;
    map<string, RegisteredField*>::const_iterator end = f.fields().end();
    for (i = f.fields().begin(); i != end; ++i) {
        i->second->setWriterData(0);
    }
}
void
CLuceneIndexWriter::releaseWriterData(const FieldRegister& f) {
    map<string, RegisteredField*>::const_iterator i;
    map<string, RegisteredField*>::const_iterator end = f.fields().end();
    for (i = f.fields().begin(); i != end; ++i) {
        delete static_cast<int*>(i->second->writerData());
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: initui.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-05-10 16:28:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _INITUI_HXX
#define _INITUI_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

/*
 * Forward Declarations
 */
class String;
class SwThesaurus;
class SpellCheck;
class SvStringsDtor;

/*
 * Extern Definitions
 */
extern  SwThesaurus*    pThes;
extern  String          GetSWGVersion();

extern  String*         pOldGrfCat;
extern  String*         pOldTabCat;
extern  String*         pOldFrmCat;

extern  String*         pCurrGlosGroup;

//CHINA001  add for swui to access global variables in sw. Begin
String* GetOldGrfCat();
String* GetOldTabCat();
String* GetOldFrmCat();
String* GetOldDrwCat();
String* GetCurrGlosGroup();
void SetCurrGlosGroup(String* pStr);
//CHINA001 End for add

extern SvStringsDtor*   pDBNameList;

extern SvStringsDtor*   pAuthFieldNameList;
extern SvStringsDtor*   pAuthFieldTypeList;

// stellt die Textbausteinverwaltung zur Verfuegung
class SwGlossaries;
SwGlossaries* GetGlossaries();

class SwGlossaryList;

BOOL HasGlossaryList();
SwGlossaryList* GetGlossaryList();

extern  void _InitUI();
extern  void _FinitUI();
extern  void _InitSpell();
extern  void _FinitSpell();

#endif
<commit_msg>INTEGRATION: CWS tune03 (1.2.82); FILE MERGED 2004/07/19 19:11:27 mhu 1.2.82.1: #i29979# Added SW_DLLPUBLIC/PRIVATE (see swdllapi.h) to exported symbols/classes.<commit_after>/*************************************************************************
 *
 *  $RCSfile: initui.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-08-23 08:59:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _INITUI_HXX
#define _INITUI_HXX

#ifndef _SOLAR_H
#include "tools/solar.h"
#endif

#ifndef INCLUDED_SWDLLAPI_H
#include "swdllapi.h"
#endif

/*
 * Forward Declarations
 */
class String;
class SwThesaurus;
class SpellCheck;
class SvStringsDtor;

/*
 * Extern Definitions
 */
extern  SwThesaurus*    pThes;
extern  String          GetSWGVersion();

extern  String*         pOldGrfCat;
extern  String*         pOldTabCat;
extern  String*         pOldFrmCat;

extern  String*         pCurrGlosGroup;

//CHINA001  add for swui to access global variables in sw. Begin
SW_DLLPUBLIC String* GetOldGrfCat();
SW_DLLPUBLIC String* GetOldTabCat();
SW_DLLPUBLIC String* GetOldFrmCat();
SW_DLLPUBLIC String* GetOldDrwCat();

SW_DLLPUBLIC String* GetCurrGlosGroup();
SW_DLLPUBLIC void SetCurrGlosGroup(String* pStr);
//CHINA001 End for add

extern SvStringsDtor*   pDBNameList;

extern SvStringsDtor*   pAuthFieldNameList;
extern SvStringsDtor*   pAuthFieldTypeList;

// stellt die Textbausteinverwaltung zur Verfuegung
class SwGlossaries;
SW_DLLPUBLIC SwGlossaries* GetGlossaries();

class SwGlossaryList;

BOOL HasGlossaryList();
SwGlossaryList* GetGlossaryList();

extern  void _InitUI();
extern  void _FinitUI();
extern  void _InitSpell();
extern  void _FinitSpell();

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wolesh.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 10:18:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SWWOLESH_HXX
#define _SWWOLESH_HXX

#include "olesh.hxx"

class SwWebOleShell: public SwOleShell
{
public:
    SFX_DECL_INTERFACE(SW_WEBOLESHELL);

    virtual     ~SwWebOleShell();
                SwWebOleShell(SwView &rView);
};

#endif

<commit_msg>INTEGRATION: CWS swwarnings (1.2.710); FILE MERGED 2007/03/05 12:45:51 tl 1.2.710.1: #i69287# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wolesh.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 12:15:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SWWOLESH_HXX
#define _SWWOLESH_HXX

#include "olesh.hxx"

class SwWebOleShell: public SwOleShell
{
public:
    SFX_DECL_INTERFACE(SW_WEBOLESHELL)

    virtual     ~SwWebOleShell();
                SwWebOleShell(SwView &rView);
};

#endif

<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "EC_VolumeTrigger.h"
#include "EC_RigidBody.h"
#include "EC_Placeable.h"
#include "Entity.h"
#include "PhysicsModule.h"
#include "PhysicsWorld.h"
#include "PhysicsUtils.h"
#include <OgreAxisAlignedBox.h>
#include "btBulletDynamicsCommon.h"

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("EC_VolumeTrigger");

EC_VolumeTrigger::EC_VolumeTrigger(IModule* module) :
    IComponent(module->GetFramework()),
    byPivot(this, "By Pivot", false),
    entities(this, "Entities"),
    owner_(checked_static_cast<Physics::PhysicsModule*>(module))
{
    QObject::connect(this, SIGNAL(OnAttributeChanged(IAttribute*, AttributeChange::Type)),
            SLOT(AttributeUpdated(IAttribute*)));

    connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()));
}

EC_VolumeTrigger::~EC_VolumeTrigger()
{

}

QList<Scene::EntityWeakPtr> EC_VolumeTrigger::GetEntitiesInside() const
{
    return entities_.keys();
}

int EC_VolumeTrigger::GetNumEntitiesInside() const
{
    return entities_.size();
}

Scene::Entity* EC_VolumeTrigger::GetEntityInside(int idx) const
{
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    if (idx >=0 && idx < entities.size())
    {
        Scene::EntityPtr entity = entities.at(idx).lock();
        if (entity)
            return entity.get();
    }
    return 0;
}

QStringList EC_VolumeTrigger::GetEntityNamesInside() const
{
    QStringList entitynames;
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    foreach (Scene::EntityWeakPtr entityw, entities)
    {
        Scene::EntityPtr entity = entityw.lock();
        if (entity)
            entitynames.append(entity->GetName());
    }

    return entitynames;
}

float EC_VolumeTrigger::GetEntityInsidePercent(const Scene::Entity *entity) const
{
    if (entity)
    {
        boost::shared_ptr<EC_RigidBody> otherRigidbody = entity->GetComponent<EC_RigidBody>();

        boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
        if (rigidbody && otherRigidbody)
        {
            Vector3df thisBoxMin, thisBoxMax;
            rigidbody->GetAabbox(thisBoxMin, thisBoxMax);

            Vector3df otherBoxMin, otherBoxMax;
            otherRigidbody->GetAabbox(otherBoxMin, otherBoxMax);

            Ogre::AxisAlignedBox thisBox(thisBoxMin.x, thisBoxMin.y, thisBoxMin.z, thisBoxMax.x, thisBoxMax.y, thisBoxMax.z);
            Ogre::AxisAlignedBox otherBox(otherBoxMin.x, otherBoxMin.y, otherBoxMin.z, otherBoxMax.x, otherBoxMax.y, otherBoxMax.z);

            return (thisBox.intersection(otherBox).volume() / otherBox.volume());
        } else
            LogWarning("EC_VolumeTrigger: no EC_RigidBody for entity or volume.");
    }
    return 0.0f;
}

float EC_VolumeTrigger::GetEntityInsidePercentByName(const QString &name) const
{
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    foreach(Scene::EntityWeakPtr wentity, entities)
    {
        Scene::EntityPtr entity = wentity.lock();
        if (entity && entity->GetName().compare(name) == 0)
            return GetEntityInsidePercent(entity.get());
    }
    return 0.f;
}

bool EC_VolumeTrigger::IsInterestingEntity(const QString &name) const
{
    QVariantList interestingEntities = entities.Get();
    if (interestingEntities.isEmpty())
        return true;

    foreach (QVariant intname, interestingEntities)
    {
        if (intname.toString().compare(name) == 0)
        {
            return true;
        }
    }
    return false;
}

bool EC_VolumeTrigger::IsPivotInside(Scene::Entity *entity) const
{
    boost::shared_ptr<EC_Placeable> placeable = entity->GetComponent<EC_Placeable>();
    boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
    if (placeable && rigidbody)
    {
        const Transform& trans = placeable->transform.Get();
        const Vector3df& pivot = trans.position;

        return ( RayTestSingle(Vector3df(pivot.x, pivot.y, pivot.z - 1e7), pivot, rigidbody->GetRigidBody()) &&
                 RayTestSingle(Vector3df(pivot.x, pivot.y, pivot.z + 1e7), pivot, rigidbody->GetRigidBody()) );
    }
    LogWarning("EC_VolumeTrigger::IsPivotInside(): entity has no EC_Placeable or volume has no EC_RigidBody.");
    return false;
}

bool EC_VolumeTrigger::IsInsideVolume(const Vector3df& point) const
{
    boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
    if (!rigidbody)
    {
        LogWarning("Volume has no EC_RigidBody.");
        return false;
    }

    return RayTestSingle(Vector3df(point.x, point.y, point.z - 1e7), point, rigidbody->GetRigidBody()) &&
           RayTestSingle(Vector3df(point.x, point.y, point.z + 1e7), point, rigidbody->GetRigidBody());
}

void EC_VolumeTrigger::AttributeUpdated(IAttribute* attribute)
{
    //! \todo Attribute updates not handled yet, there are a bit too many problems of what signals to send after the update -cm

    //if (attribute == &mass)
    //    ReadBody();
}

void EC_VolumeTrigger::UpdateSignals()
{
    Scene::Entity* parent = GetParentEntity();
    if (!parent)
        return;

    connect(parent, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), this, SLOT(CheckForRigidBody()));

    Scene::SceneManager* scene = parent->GetScene();
    Physics::PhysicsWorld* world = owner_->GetPhysicsWorldForScene(scene);
    if (world)
        connect(world, SIGNAL(Updated(float)), this, SLOT(OnPhysicsUpdate()));
}

void EC_VolumeTrigger::CheckForRigidBody()
{
    Scene::Entity* parent = GetParentEntity();
    if (!parent)
        return;

    if (!rigidbody_.lock())
    {
        boost::shared_ptr<EC_RigidBody> rigidbody = parent->GetComponent<EC_RigidBody>();
        if (rigidbody)
        {
            rigidbody_ = rigidbody;
            connect(rigidbody.get(), SIGNAL(PhysicsCollision(Scene::Entity*, const Vector3df&, const Vector3df&, float, float, bool)),
                this, SLOT(OnPhysicsCollision(Scene::Entity*, const Vector3df&, const Vector3df&, float, float, bool)));
        }
    }
}

void EC_VolumeTrigger::OnPhysicsUpdate()
{
    QMap<Scene::EntityWeakPtr, bool>::iterator i = entities_.begin();
    while (i != entities_.end())
    {
        if (!i.value())
        {
            bool active = true;
            Scene::EntityPtr entity = i.key().lock();
            // inactive rigid bodies don't generate collisions, so before emitting EntityLeave -event, make sure the body is active.
            if (entity)
            {
                boost::shared_ptr<EC_RigidBody> rigidbody = entity->GetComponent<EC_RigidBody>();
                if (rigidbody)
                    active = rigidbody->IsActive();
            }
            if (active)
            {
                i = entities_.erase(i);

                if (entity)
                {
                    emit EntityLeave(entity.get());
                    disconnect(entity.get(), SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
                }
                continue;
            }
        } else
        {
            entities_.insert(i.key(), false);
        }
        i++;
    }
}

void EC_VolumeTrigger::OnPhysicsCollision(Scene::Entity* otherEntity, const Vector3df& position, const Vector3df& normal, float distance, float impulse, bool newCollision)
{
    assert (otherEntity && "Physics collision with no entity.");

    if (!entities.Get().isEmpty() && !IsInterestingEntity(otherEntity->GetName()))
        return;

    Scene::EntityPtr entity = otherEntity->shared_from_this();

    if (byPivot.Get())
    {
        if (IsPivotInside(entity.get()))
        {
            if (entities_.find(entity) == entities_.end())
            {
                emit EntityEnter(otherEntity);
                connect(otherEntity, SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
            }

            entities_.insert(entity, true);
        }
    } else
    {
        if (newCollision)
        {
            // make sure the entity isn't already inside the volume
            if (entities_.find(entity) == entities_.end())
            {
                emit EntityEnter(otherEntity);
                connect(otherEntity, SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
            }
        }
        entities_.insert(entity, true);
    }
}

void EC_VolumeTrigger::OnEntityRemoved(Scene::Entity *entity)
{
    Scene::EntityWeakPtr ptr = entity->shared_from_this();
    QMap<Scene::EntityWeakPtr, bool>::iterator i = entities_.find(ptr);
    if (i != entities_.end())
    {
        entities_.erase(i);

        emit EntityLeave(entity);
    }
}

<commit_msg>VolumeTrigger: experimentally remove the activity check for EntityLeave signal, couldn't get it working right and disabling it seems to do no harm?<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "EC_VolumeTrigger.h"
#include "EC_RigidBody.h"
#include "EC_Placeable.h"
#include "Entity.h"
#include "PhysicsModule.h"
#include "PhysicsWorld.h"
#include "PhysicsUtils.h"
#include <OgreAxisAlignedBox.h>
#include "btBulletDynamicsCommon.h"

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("EC_VolumeTrigger");

EC_VolumeTrigger::EC_VolumeTrigger(IModule* module) :
    IComponent(module->GetFramework()),
    byPivot(this, "By Pivot", false),
    entities(this, "Entities"),
    owner_(checked_static_cast<Physics::PhysicsModule*>(module))
{
    QObject::connect(this, SIGNAL(OnAttributeChanged(IAttribute*, AttributeChange::Type)),
            SLOT(AttributeUpdated(IAttribute*)));

    connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()));
}

EC_VolumeTrigger::~EC_VolumeTrigger()
{

}

QList<Scene::EntityWeakPtr> EC_VolumeTrigger::GetEntitiesInside() const
{
    return entities_.keys();
}

int EC_VolumeTrigger::GetNumEntitiesInside() const
{
    return entities_.size();
}

Scene::Entity* EC_VolumeTrigger::GetEntityInside(int idx) const
{
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    if (idx >=0 && idx < entities.size())
    {
        Scene::EntityPtr entity = entities.at(idx).lock();
        if (entity)
            return entity.get();
    }
    return 0;
}

QStringList EC_VolumeTrigger::GetEntityNamesInside() const
{
    QStringList entitynames;
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    foreach (Scene::EntityWeakPtr entityw, entities)
    {
        Scene::EntityPtr entity = entityw.lock();
        if (entity)
            entitynames.append(entity->GetName());
    }

    return entitynames;
}

float EC_VolumeTrigger::GetEntityInsidePercent(const Scene::Entity *entity) const
{
    if (entity)
    {
        boost::shared_ptr<EC_RigidBody> otherRigidbody = entity->GetComponent<EC_RigidBody>();

        boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
        if (rigidbody && otherRigidbody)
        {
            Vector3df thisBoxMin, thisBoxMax;
            rigidbody->GetAabbox(thisBoxMin, thisBoxMax);

            Vector3df otherBoxMin, otherBoxMax;
            otherRigidbody->GetAabbox(otherBoxMin, otherBoxMax);

            Ogre::AxisAlignedBox thisBox(thisBoxMin.x, thisBoxMin.y, thisBoxMin.z, thisBoxMax.x, thisBoxMax.y, thisBoxMax.z);
            Ogre::AxisAlignedBox otherBox(otherBoxMin.x, otherBoxMin.y, otherBoxMin.z, otherBoxMax.x, otherBoxMax.y, otherBoxMax.z);

            return (thisBox.intersection(otherBox).volume() / otherBox.volume());
        } else
            LogWarning("EC_VolumeTrigger: no EC_RigidBody for entity or volume.");
    }
    return 0.0f;
}

float EC_VolumeTrigger::GetEntityInsidePercentByName(const QString &name) const
{
    QList<Scene::EntityWeakPtr> entities = entities_.keys();
    foreach(Scene::EntityWeakPtr wentity, entities)
    {
        Scene::EntityPtr entity = wentity.lock();
        if (entity && entity->GetName().compare(name) == 0)
            return GetEntityInsidePercent(entity.get());
    }
    return 0.f;
}

bool EC_VolumeTrigger::IsInterestingEntity(const QString &name) const
{
    QVariantList interestingEntities = entities.Get();
    if (interestingEntities.isEmpty())
        return true;

    foreach (QVariant intname, interestingEntities)
    {
        if (intname.toString().compare(name) == 0)
        {
            return true;
        }
    }
    return false;
}

bool EC_VolumeTrigger::IsPivotInside(Scene::Entity *entity) const
{
    boost::shared_ptr<EC_Placeable> placeable = entity->GetComponent<EC_Placeable>();
    boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
    if (placeable && rigidbody)
    {
        const Transform& trans = placeable->transform.Get();
        const Vector3df& pivot = trans.position;

        return ( RayTestSingle(Vector3df(pivot.x, pivot.y, pivot.z - 1e7), pivot, rigidbody->GetRigidBody()) &&
                 RayTestSingle(Vector3df(pivot.x, pivot.y, pivot.z + 1e7), pivot, rigidbody->GetRigidBody()) );
    }
    LogWarning("EC_VolumeTrigger::IsPivotInside(): entity has no EC_Placeable or volume has no EC_RigidBody.");
    return false;
}

bool EC_VolumeTrigger::IsInsideVolume(const Vector3df& point) const
{
    boost::shared_ptr<EC_RigidBody> rigidbody = rigidbody_.lock();
    if (!rigidbody)
    {
        LogWarning("Volume has no EC_RigidBody.");
        return false;
    }

    return RayTestSingle(Vector3df(point.x, point.y, point.z - 1e7), point, rigidbody->GetRigidBody()) &&
           RayTestSingle(Vector3df(point.x, point.y, point.z + 1e7), point, rigidbody->GetRigidBody());
}

void EC_VolumeTrigger::AttributeUpdated(IAttribute* attribute)
{
    //! \todo Attribute updates not handled yet, there are a bit too many problems of what signals to send after the update -cm

    //if (attribute == &mass)
    //    ReadBody();
}

void EC_VolumeTrigger::UpdateSignals()
{
    Scene::Entity* parent = GetParentEntity();
    if (!parent)
        return;

    connect(parent, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), this, SLOT(CheckForRigidBody()));

    Scene::SceneManager* scene = parent->GetScene();
    Physics::PhysicsWorld* world = owner_->GetPhysicsWorldForScene(scene);
    if (world)
        connect(world, SIGNAL(Updated(float)), this, SLOT(OnPhysicsUpdate()));
}

void EC_VolumeTrigger::CheckForRigidBody()
{
    Scene::Entity* parent = GetParentEntity();
    if (!parent)
        return;

    if (!rigidbody_.lock())
    {
        boost::shared_ptr<EC_RigidBody> rigidbody = parent->GetComponent<EC_RigidBody>();
        if (rigidbody)
        {
            rigidbody_ = rigidbody;
            connect(rigidbody.get(), SIGNAL(PhysicsCollision(Scene::Entity*, const Vector3df&, const Vector3df&, float, float, bool)),
                this, SLOT(OnPhysicsCollision(Scene::Entity*, const Vector3df&, const Vector3df&, float, float, bool)));
        }
    }
}

void EC_VolumeTrigger::OnPhysicsUpdate()
{
    QMap<Scene::EntityWeakPtr, bool>::iterator i = entities_.begin();
    while (i != entities_.end())
    {
        if (!i.value())
        {
            Scene::EntityPtr entity = i.key().lock();
            /* disabled the check 'cause couldn't get the targets active, and the (possible) extran signaling doesn't do harm? --antont
            bool active = true;
            // inactive rigid bodies don't generate collisions, so before emitting EntityLeave -event, make sure the body is active.
            if (entity)
            {
                boost::shared_ptr<EC_RigidBody> rigidbody = entity->GetComponent<EC_RigidBody>();
                if (rigidbody)
                    active = rigidbody->IsActive();
            }
            if (active)*/
            if (true)
            {
                i = entities_.erase(i);

                if (entity)
                {
                    emit EntityLeave(entity.get());
                    disconnect(entity.get(), SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
                }
                continue;
            }
        } else
        {
            entities_.insert(i.key(), false);
        }
        i++;
    }
}

void EC_VolumeTrigger::OnPhysicsCollision(Scene::Entity* otherEntity, const Vector3df& position, const Vector3df& normal, float distance, float impulse, bool newCollision)
{
    assert (otherEntity && "Physics collision with no entity.");

    if (!entities.Get().isEmpty() && !IsInterestingEntity(otherEntity->GetName()))
        return;

    Scene::EntityPtr entity = otherEntity->shared_from_this();

    if (byPivot.Get())
    {
        if (IsPivotInside(entity.get()))
        {
            if (entities_.find(entity) == entities_.end())
            {
                emit EntityEnter(otherEntity);
                connect(otherEntity, SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
            }

            entities_.insert(entity, true);
        }
    } else
    {
        if (newCollision)
        {
            // make sure the entity isn't already inside the volume
            if (entities_.find(entity) == entities_.end())
            {
                emit EntityEnter(otherEntity);
                connect(otherEntity, SIGNAL(EntityRemoved(Scene::Entity*, AttributeChange::Type)), this, SLOT(OnEntityRemoved(Scene::Entity*)));
            }
        }
        entities_.insert(entity, true);
    }
}

void EC_VolumeTrigger::OnEntityRemoved(Scene::Entity *entity)
{
    Scene::EntityWeakPtr ptr = entity->shared_from_this();
    QMap<Scene::EntityWeakPtr, bool>::iterator i = entities_.find(ptr);
    if (i != entities_.end())
    {
        entities_.erase(i);

        emit EntityLeave(entity);
    }
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "movement_system.h"
#include "entity_system/world.h"
#include "../messages/intent_message.h"
#include "../messages/animate_message.h"

#include "../components/gun_component.h"

/* leave the air drag to simulate top speeds in a sidescroller

*/

using namespace messages;

void movement_system::consume_events(world& owner) {
	auto events = owner.get_message_queue<messages::intent_message>();

	for (auto it : events) {
		switch (it.intent) {
		case intent_message::intent_type::MOVE_FORWARD:
			it.subject->get<components::movement>().moving_forward = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_BACKWARD:
			it.subject->get<components::movement>().moving_backward = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_LEFT:
			it.subject->get<components::movement>().moving_left = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_RIGHT:
			it.subject->get<components::movement>().moving_right = it.state_flag;
			break;
		default: break;
		}
	}
}

template <typename T> int sgn(T val) {
	return (T(0) < val) - (val < T(0));
}

void movement_system::substep(world& owner) {
	auto& physics_sys = owner.get_system<physics_system>();

	for (auto it : targets) {
		auto& physics = it->get<components::physics>();
		auto& movement = it->get<components::movement>();

		vec2<> resultant;

		if (movement.requested_movement.non_zero()) {
			/* rotate to our frame of reference */
			//resultant.x = sgn(vec2<>(movement.requested_movement).rotate(-movement.axis_rotation_degrees, vec2<>()).x) * movement.input_acceleration.x;
			resultant.x = vec2<>(movement.requested_movement).rotate(-movement.axis_rotation_degrees, vec2<>()).x;
		}
		else {
			resultant.x = movement.moving_right * movement.input_acceleration.x - movement.moving_left * movement.input_acceleration.x;
			resultant.y = movement.moving_backward * movement.input_acceleration.y - movement.moving_forward * movement.input_acceleration.y;
		}

		b2Vec2 vel = physics.body->GetLinearVelocity();

		float ground_angle = 0.f;
		bool was_ground_hit = false;

		if (movement.sidescroller_setup) {
			if (movement.thrust_parallel_to_ground_length > 0.f) {
				auto out = physics_sys.ray_cast(
					physics.body->GetPosition(),
					physics.body->GetPosition() + vec2<>::from_degrees(movement.axis_rotation_degrees + 90) * movement.thrust_parallel_to_ground_length * PIXELS_TO_METERSf,
					movement.ground_filter, it);

				was_ground_hit = out.hit;
				if (was_ground_hit)
					ground_angle = out.normal.get_degrees() + 90;
			}

			if (std::abs(resultant.x) < b2_epsilon && vel.LengthSquared() > 0) {
				physics.body->SetLinearDampingVec(movement.inverse_thrust_brake * PIXELS_TO_METERSf);
				physics.body->SetLinearDampingAngle(was_ground_hit ? ground_angle : movement.axis_rotation_degrees);
			}
			else {
				physics.body->SetLinearDampingVec(b2Vec2(0, 0));
			}
		}
		else {
			physics.body->SetLinearDampingVec(b2Vec2(0, 0));
			physics.body->SetLinearDampingAngle(0.f);
		}

		if (resultant.non_zero()) {
			if (movement.braking_damping >= 0.f)
				physics.body->SetLinearDamping(0.f);

			resultant.rotate(was_ground_hit ? ground_angle : movement.axis_rotation_degrees, vec2<>());

			physics.body->ApplyForce(resultant * PIXELS_TO_METERSf, physics.body->GetWorldCenter() + (movement.force_offset * PIXELS_TO_METERSf), true);
		}
		else if (movement.braking_damping >= 0.f)
			physics.body->SetLinearDamping(movement.braking_damping);

		float32 speed = vel.Normalize();

		if ((vel.x != 0.f || vel.y != 0.f) && movement.air_resistance > 0.f)
			physics.body->ApplyForce(movement.air_resistance * speed * speed * -vel, physics.body->GetWorldCenter(), true);
	}
}

void movement_system::process_entities(world& owner) {
	for (auto it : targets) {
		auto& physics = it->get<components::physics>();
		auto& movement = it->get<components::movement>();

		b2Vec2 vel = physics.body->GetLinearVelocity();
		float32 speed = vel.Normalize() * METERS_TO_PIXELSf;

		animate_message msg;

		msg.change_speed = true;

		if (movement.max_speed_animation == 0.f) msg.speed_factor = 0.f;
		else msg.speed_factor = speed / movement.max_speed_animation;

		msg.change_animation = true;
		msg.preserve_state_if_animation_changes = false;
		msg.message_type = ((speed <= 1.f) ? animate_message::type::STOP : animate_message::type::CONTINUE);
		msg.animation_priority = 0;

		for (auto receiver : movement.animation_receivers) {
			animate_message copy(msg);
			copy.animation_type = animate_message::animation::MOVE;

			auto* gun = receiver.target->find<components::gun>();

			if (gun)
				copy.animation_type = gun->current_swing_direction ? animate_message::animation::MOVE_CW : animate_message::animation::MOVE_CCW;

			copy.subject = receiver.target;

			if (!receiver.stop_at_zero_movement)
				copy.message_type = animate_message::type::CONTINUE;

			owner.post_message(copy);
		}
	}
}
<commit_msg>clamping requested movement to input acceleration<commit_after>#include "stdafx.h"
#include "movement_system.h"
#include "entity_system/world.h"
#include "../messages/intent_message.h"
#include "../messages/animate_message.h"

#include "../components/gun_component.h"

/* leave the air drag to simulate top speeds in a sidescroller

*/

using namespace messages;

void movement_system::consume_events(world& owner) {
	auto events = owner.get_message_queue<messages::intent_message>();

	for (auto it : events) {
		switch (it.intent) {
		case intent_message::intent_type::MOVE_FORWARD:
			it.subject->get<components::movement>().moving_forward = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_BACKWARD:
			it.subject->get<components::movement>().moving_backward = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_LEFT:
			it.subject->get<components::movement>().moving_left = it.state_flag;
			break;
		case intent_message::intent_type::MOVE_RIGHT:
			it.subject->get<components::movement>().moving_right = it.state_flag;
			break;
		default: break;
		}
	}
}

template <typename T> int sgn(T val) {
	return (T(0) < val) - (val < T(0));
}

void movement_system::substep(world& owner) {
	auto& physics_sys = owner.get_system<physics_system>();

	for (auto it : targets) {
		auto& physics = it->get<components::physics>();
		auto& movement = it->get<components::movement>();

		vec2<> resultant;

		if (movement.requested_movement.non_zero()) {
			/* rotate to our frame of reference */
			//resultant.x = sgn(vec2<>(movement.requested_movement).rotate(-movement.axis_rotation_degrees, vec2<>()).x) * movement.input_acceleration.x;
			resultant.x = vec2<>(movement.requested_movement).rotate(-movement.axis_rotation_degrees, vec2<>()).x;
			clamp(resultant.x, -movement.input_acceleration.x, movement.input_acceleration.x);
		}
		else {
			resultant.x = movement.moving_right * movement.input_acceleration.x - movement.moving_left * movement.input_acceleration.x;
			resultant.y = movement.moving_backward * movement.input_acceleration.y - movement.moving_forward * movement.input_acceleration.y;
		}

		b2Vec2 vel = physics.body->GetLinearVelocity();

		float ground_angle = 0.f;
		bool was_ground_hit = false;

		if (movement.sidescroller_setup) {
			if (movement.thrust_parallel_to_ground_length > 0.f) {
				auto out = physics_sys.ray_cast(
					physics.body->GetPosition(),
					physics.body->GetPosition() + vec2<>::from_degrees(movement.axis_rotation_degrees + 90) * movement.thrust_parallel_to_ground_length * PIXELS_TO_METERSf,
					movement.ground_filter, it);

				was_ground_hit = out.hit;
				if (was_ground_hit)
					ground_angle = out.normal.get_degrees() + 90;
			}

			if (std::abs(resultant.x) < b2_epsilon && vel.LengthSquared() > 0) {
				physics.body->SetLinearDampingVec(movement.inverse_thrust_brake * PIXELS_TO_METERSf);
				physics.body->SetLinearDampingAngle(was_ground_hit ? ground_angle : movement.axis_rotation_degrees);
			}
			else {
				physics.body->SetLinearDampingVec(b2Vec2(0, 0));
			}
		}
		else {
			physics.body->SetLinearDampingVec(b2Vec2(0, 0));
			physics.body->SetLinearDampingAngle(0.f);
		}

		if (resultant.non_zero()) {
			if (movement.braking_damping >= 0.f)
				physics.body->SetLinearDamping(0.f);

			resultant.rotate(was_ground_hit ? ground_angle : movement.axis_rotation_degrees, vec2<>());

			physics.body->ApplyForce(resultant * PIXELS_TO_METERSf, physics.body->GetWorldCenter() + (movement.force_offset * PIXELS_TO_METERSf), true);
		}
		else if (movement.braking_damping >= 0.f)
			physics.body->SetLinearDamping(movement.braking_damping);

		float32 speed = vel.Normalize();

		if ((vel.x != 0.f || vel.y != 0.f) && movement.air_resistance > 0.f)
			physics.body->ApplyForce(movement.air_resistance * speed * speed * -vel, physics.body->GetWorldCenter(), true);
	}
}

void movement_system::process_entities(world& owner) {
	for (auto it : targets) {
		auto& physics = it->get<components::physics>();
		auto& movement = it->get<components::movement>();

		b2Vec2 vel = physics.body->GetLinearVelocity();
		float32 speed = vel.Normalize() * METERS_TO_PIXELSf;

		animate_message msg;

		msg.change_speed = true;

		if (movement.max_speed_animation == 0.f) msg.speed_factor = 0.f;
		else msg.speed_factor = speed / movement.max_speed_animation;

		msg.change_animation = true;
		msg.preserve_state_if_animation_changes = false;
		msg.message_type = ((speed <= 1.f) ? animate_message::type::STOP : animate_message::type::CONTINUE);
		msg.animation_priority = 0;

		for (auto receiver : movement.animation_receivers) {
			animate_message copy(msg);
			copy.animation_type = animate_message::animation::MOVE;

			auto* gun = receiver.target->find<components::gun>();

			if (gun)
				copy.animation_type = gun->current_swing_direction ? animate_message::animation::MOVE_CW : animate_message::animation::MOVE_CCW;

			copy.subject = receiver.target;

			if (!receiver.stop_at_zero_movement)
				copy.message_type = animate_message::type::CONTINUE;

			owner.post_message(copy);
		}
	}
}
<|endoftext|>