<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrap_hidclex.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 05:05: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
 *
 ************************************************************************/

#include "hidc_yy.cxx"
<commit_msg>INTEGRATION: CWS pchfix02 (1.2.10); FILE MERGED 2006/09/01 17:40:15 kaib 1.2.10.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wrap_hidclex.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 11:32:42 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_soltools.hxx"

#include "hidc_yy.cxx"
<|endoftext|>


<commit_before>/*
 * ArcEmu MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2008-2011 <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "StdAfx.h"
#include "EventableObject.h"

EventableObject::~EventableObject()
{
	/* decrement event count on all events */

	EventMap::iterator itr = m_events.begin();
	for(; itr != m_events.end(); ++itr)
	{
		itr->second->deleted = true;
		itr->second->DecRef();
	}

	m_events.clear();
}

EventableObject::EventableObject()
{
	/* commented, these will be allocated when the first event is added. */
	//m_event_Instanceid = event_GetInstanceID();
	//m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
	m_refs = 1;
	m_holder = 0;
	m_event_Instanceid = -1;

	m_events.clear();
}

void EventableObject::event_AddEvent(TimedEvent * ptr)
{
	m_lock.Acquire();

	if( m_holder == NULL )
	{
		m_event_Instanceid = event_GetInstanceID();
		m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);

        if( m_holder == NULL ){

            ///////////////////////////////////////// this is for me for debugging purposes - dfighter ////////////////////////////
            // Arcemu::Util::ARCEMU_ASSERT( false );
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // We still couldn't find an eventholder for us so let's run in WorldRunnable
            m_event_Instanceid = WORLD_INSTANCE;
            m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
        }
	}

    // We still couldn't find an event holder for ourselves :(
    Arcemu::Util::ARCEMU_ASSERT(   m_holder != NULL );

    // If we are flagged not to run in WorldRunnable then we won't!
    // This is much better than adding us to the eventholder and removing on an update
    if( m_event_Instanceid == WORLD_INSTANCE && ( ptr->eventFlag & EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ) ){
        delete ptr->cb;
        delete ptr;

        ///////////////////////////////////////// this is for me for debugging purposes - dfighter ////////////////////////////
        // Arcemu::Util::ARCEMU_ASSERT( false );
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		m_lock.Release();
        return;
    }

	ptr->IncRef();
	ptr->instanceId = m_event_Instanceid;
	pair<uint32,TimedEvent*> p(ptr->eventType, ptr);
	m_events.insert( p );
	m_lock.Release();

    /* Add to event manager */
	m_holder->AddEvent(ptr);
}

void EventableObject::event_RemoveByPointer(TimedEvent * ev)
{
	m_lock.Acquire();
	EventMap::iterator itr = m_events.find(ev->eventType);
	EventMap::iterator it2;
	if(itr != m_events.end())
	{
		do
		{
			it2 = itr++;

			if(it2->second == ev)
			{
				it2->second->deleted = true;
				it2->second->DecRef();
				m_events.erase(it2);
				m_lock.Release();
				return;
			}

		} while(itr != m_events.upper_bound(ev->eventType));
	}
	m_lock.Release();
}

void EventableObject::event_RemoveEvents(uint32 EventType)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	if(EventType == EVENT_REMOVAL_FLAG_ALL)
	{
		EventMap::iterator itr = m_events.begin();
		for(; itr != m_events.end(); ++itr)
		{
			itr->second->deleted = true;
			itr->second->DecRef();
		}
		m_events.clear();
	}
	else
	{
		EventMap::iterator itr = m_events.find(EventType);
		EventMap::iterator it2;
		if(itr != m_events.end())
		{
			do
			{
				it2 = itr++;

				it2->second->deleted = true;
				it2->second->DecRef();
				m_events.erase(it2);

			} while(itr != m_events.upper_bound(EventType));
		}
	}

	m_lock.Release();
}

void EventableObject::event_RemoveEvents()
{
	event_RemoveEvents(EVENT_REMOVAL_FLAG_ALL);
}

void EventableObject::event_ModifyTimeLeft(uint32 EventType, time_t TimeLeft,bool unconditioned)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if(unconditioned)
				itr->second->currTime = TimeLeft;
			else itr->second->currTime = (TimeLeft > itr->second->msTime) ? itr->second->msTime : TimeLeft;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

bool EventableObject::event_GetTimeLeft(uint32 EventType, time_t * Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return false;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if( itr->second->deleted )
			{
				++itr;
				continue;
			}

			*Time = (uint32)itr->second->currTime;
			m_lock.Release();
			return true;

		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
	return false;
}

void EventableObject::event_ModifyTime(uint32 EventType, time_t Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			itr->second->msTime = Time;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

void EventableObject::event_ModifyTimeAndTimeLeft(uint32 EventType, time_t Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			itr->second->currTime = itr->second->msTime = Time;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

bool EventableObject::event_HasEvent(uint32 EventType)
{
	bool ret = false;
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return false;
	}

	//ret = m_events.find(EventType) == m_events.end() ? false : true;
	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if(!itr->second->deleted)
			{
				ret = true;
				break;
			}
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
	return ret;
}

EventableObjectHolder::EventableObjectHolder(int32 instance_id) : mInstanceId(instance_id)
{
	m_insertPool.clear();
	sEventMgr.AddEventHolder(this, instance_id);
}

EventableObjectHolder::~EventableObjectHolder()
{
	sEventMgr.RemoveEventHolder(this);

	/* decrement events reference count */
	m_lock.Acquire();
	EventList::iterator itr = m_events.begin();
	for(; itr != m_events.end(); ++itr)
		(*itr)->DecRef();
	m_lock.Release();
}

void EventableObjectHolder::Update(time_t time_difference)
{
	m_lock.Acquire();			// <<<<

	/* Insert any pending objects in the insert pool. */
	m_insertPoolLock.Acquire();
	InsertableQueue::iterator iqi;
	InsertableQueue::iterator iq2 = m_insertPool.begin();
	while(iq2 != m_insertPool.end())
	{
		iqi = iq2++;
		if((*iqi)->deleted || (*iqi)->instanceId != mInstanceId)
			(*iqi)->DecRef();
		else
			m_events.push_back( (*iqi) );

		m_insertPool.erase(iqi);
	}
	m_insertPoolLock.Release();

	/* Now we can proceed normally. */
	EventList::iterator itr = m_events.begin();
	EventList::iterator it2;
	TimedEvent * ev;

	while(itr != m_events.end())
	{
		it2 = itr++;

		if((*it2)->instanceId != mInstanceId || (*it2)->deleted ){

			(*it2)->DecRef();

			// remove from this list.
			m_events.erase(it2);

			continue;
		}

		// Event Update Procedure
		ev = *it2;

		if(ev->currTime <= time_difference)
		{
			// execute the callback
			if(ev->eventFlag & EVENT_FLAG_DELETES_OBJECT)
			{
				m_events.erase(it2);
				ev->deleted = true;
				ev->cb->execute();
				ev->DecRef();
				continue;
			}
			else
				ev->cb->execute();

			// check if the event is expired now.
            if(ev->repeats && --ev->repeats == 0)
			{
				// Event expired :>

				/* remove the event from the object */
				/*obj = (EventableObject*)ev->obj;
				obj->event_RemoveByPointer(ev);*/

				/* remove the event from here */
				ev->deleted = true;
				ev->DecRef();
				m_events.erase(it2);

				continue;
			}
			else if(ev->deleted)
			{
				// event is now deleted
				ev->DecRef(); //this was added on "addevent"
				m_events.erase(it2);
				continue;
			}

			// event has to repeat again, reset the timer
			ev->currTime = ev->msTime;
		}
		else
		{
			// event is still "waiting", subtract time difference
			ev->currTime -= time_difference;
		}
	}

	m_lock.Release();
}

void EventableObject::event_Relocate()
{
	/* prevent any new stuff from getting added */
	m_lock.Acquire();

	EventableObjectHolder * nh = sEventMgr.GetEventHolder(event_GetInstanceID());
	if(nh != m_holder)
	{
		// whee, we changed event holder :>
		// doing this will change the instanceid on all the events, as well as add to the new holder.

		//If nh is NULL then we were removed from world. There's no reason to be added to WORLD_INSTANCE EventMgr, let's just wait till something will add us again to world.
		if( nh == NULL )
		{
			//set instaceId to 0 to each event of this EventableObject, so EventableObjectHolder::Update() will remove them from its EventList.
			for( EventMap::iterator itr = m_events.begin(); itr != m_events.end(); ++itr )
			{
				itr->second->instanceId = 0;
			}
			// reset our instance id.
			m_event_Instanceid = 0;
		}
		else
		{
			nh->AddObject(this);
			// reset our instance id
			m_event_Instanceid = nh->GetInstanceID();
		}
		// reset our m_holder pointer
		m_holder = nh;
	}

	/* safe again to add */
	m_lock.Release();
}

uint32 EventableObject::event_GetEventPeriod(uint32 EventType)
{
	uint32 ret = 0;
	m_lock.Acquire();
	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
		ret = (uint32)itr->second->msTime;

	m_lock.Release();
	return ret;
}

void EventableObjectHolder::AddEvent(TimedEvent * ev)
{
	// m_lock NEEDS TO BE A RECURSIVE MUTEX
	ev->IncRef();
	if(!m_lock.AttemptAcquire())
	{
		m_insertPoolLock.Acquire();
		m_insertPool.push_back( ev );
		m_insertPoolLock.Release();
	}
	else
	{
		m_events.push_back( ev );
		m_lock.Release();
	}
}

void EventableObjectHolder::AddObject(EventableObject * obj)
{
	// transfer all of this objects events into our holder
	if(!m_lock.AttemptAcquire())
	{
		// The other thread is obviously occupied. We have to use an insert pool here, otherwise
		// if 2 threads relocate at once we'll hit a deadlock situation.
		m_insertPoolLock.Acquire();
		EventMap::iterator it2;

		for(EventMap::iterator itr = obj->m_events.begin(); itr != obj->m_events.end(); ++itr)
		{
			// ignore deleted events (shouldn't be any in here, actually)
			if(itr->second->deleted)
			{
				/*it2 = itr++;
				itr->second->DecRef();
				obj->m_events.erase(it2);*/
				continue;
			}

			itr->second->IncRef();
			itr->second->instanceId = mInstanceId;
			m_insertPool.push_back(itr->second);
		}

		// Release the insert pool.
		m_insertPoolLock.Release();

		// Ignore the rest of this stuff
		return;
	}
	else
	{
		for(EventMap::iterator itr = obj->m_events.begin(); itr != obj->m_events.end(); ++itr)
		{
			// ignore deleted events
			if(itr->second->deleted)
				continue;

			itr->second->IncRef();
			itr->second->instanceId = mInstanceId;
			m_events.push_back( itr->second );
		}
		m_lock.Release();
	}
}
<commit_msg>FIXED: Memory leak in EventableObjectHolder, caused by not DecRef'ing the events in the insert pool.<commit_after>/*
 * ArcEmu MMORPG Server
 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
 * Copyright (C) 2008-2011 <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "StdAfx.h"
#include "EventableObject.h"

EventableObject::~EventableObject()
{
	/* decrement event count on all events */

	EventMap::iterator itr = m_events.begin();
	for(; itr != m_events.end(); ++itr)
	{
		itr->second->deleted = true;
		itr->second->DecRef();
	}

	m_events.clear();
}

EventableObject::EventableObject()
{
	/* commented, these will be allocated when the first event is added. */
	//m_event_Instanceid = event_GetInstanceID();
	//m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
	m_refs = 1;
	m_holder = 0;
	m_event_Instanceid = -1;

	m_events.clear();
}

void EventableObject::event_AddEvent(TimedEvent * ptr)
{
	m_lock.Acquire();

	if( m_holder == NULL )
	{
		m_event_Instanceid = event_GetInstanceID();
		m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);

        if( m_holder == NULL ){

            ///////////////////////////////////////// this is for me for debugging purposes - dfighter ////////////////////////////
            // Arcemu::Util::ARCEMU_ASSERT( false );
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // We still couldn't find an eventholder for us so let's run in WorldRunnable
            m_event_Instanceid = WORLD_INSTANCE;
            m_holder = sEventMgr.GetEventHolder(m_event_Instanceid);
        }
	}

    // We still couldn't find an event holder for ourselves :(
    Arcemu::Util::ARCEMU_ASSERT(   m_holder != NULL );

    // If we are flagged not to run in WorldRunnable then we won't!
    // This is much better than adding us to the eventholder and removing on an update
    if( m_event_Instanceid == WORLD_INSTANCE && ( ptr->eventFlag & EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ) ){
        delete ptr->cb;
        delete ptr;

        ///////////////////////////////////////// this is for me for debugging purposes - dfighter ////////////////////////////
        // Arcemu::Util::ARCEMU_ASSERT( false );
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		m_lock.Release();
        return;
    }

	ptr->IncRef();
	ptr->instanceId = m_event_Instanceid;
	pair<uint32,TimedEvent*> p(ptr->eventType, ptr);
	m_events.insert( p );
	m_lock.Release();

    /* Add to event manager */
	m_holder->AddEvent(ptr);
}

void EventableObject::event_RemoveByPointer(TimedEvent * ev)
{
	m_lock.Acquire();
	EventMap::iterator itr = m_events.find(ev->eventType);
	EventMap::iterator it2;
	if(itr != m_events.end())
	{
		do
		{
			it2 = itr++;

			if(it2->second == ev)
			{
				it2->second->deleted = true;
				it2->second->DecRef();
				m_events.erase(it2);
				m_lock.Release();
				return;
			}

		} while(itr != m_events.upper_bound(ev->eventType));
	}
	m_lock.Release();
}

void EventableObject::event_RemoveEvents(uint32 EventType)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	if(EventType == EVENT_REMOVAL_FLAG_ALL)
	{
		EventMap::iterator itr = m_events.begin();
		for(; itr != m_events.end(); ++itr)
		{
			itr->second->deleted = true;
			itr->second->DecRef();
		}
		m_events.clear();
	}
	else
	{
		EventMap::iterator itr = m_events.find(EventType);
		EventMap::iterator it2;
		if(itr != m_events.end())
		{
			do
			{
				it2 = itr++;

				it2->second->deleted = true;
				it2->second->DecRef();
				m_events.erase(it2);

			} while(itr != m_events.upper_bound(EventType));
		}
	}

	m_lock.Release();
}

void EventableObject::event_RemoveEvents()
{
	event_RemoveEvents(EVENT_REMOVAL_FLAG_ALL);
}

void EventableObject::event_ModifyTimeLeft(uint32 EventType, time_t TimeLeft,bool unconditioned)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if(unconditioned)
				itr->second->currTime = TimeLeft;
			else itr->second->currTime = (TimeLeft > itr->second->msTime) ? itr->second->msTime : TimeLeft;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

bool EventableObject::event_GetTimeLeft(uint32 EventType, time_t * Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return false;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if( itr->second->deleted )
			{
				++itr;
				continue;
			}

			*Time = (uint32)itr->second->currTime;
			m_lock.Release();
			return true;

		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
	return false;
}

void EventableObject::event_ModifyTime(uint32 EventType, time_t Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			itr->second->msTime = Time;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

void EventableObject::event_ModifyTimeAndTimeLeft(uint32 EventType, time_t Time)
{
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return;
	}

	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			itr->second->currTime = itr->second->msTime = Time;
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
}

bool EventableObject::event_HasEvent(uint32 EventType)
{
	bool ret = false;
	m_lock.Acquire();
	if(!m_events.size())
	{
		m_lock.Release();
		return false;
	}

	//ret = m_events.find(EventType) == m_events.end() ? false : true;
	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
	{
		do
		{
			if(!itr->second->deleted)
			{
				ret = true;
				break;
			}
			++itr;
		} while(itr != m_events.upper_bound(EventType));
	}

	m_lock.Release();
	return ret;
}

EventableObjectHolder::EventableObjectHolder(int32 instance_id) : mInstanceId(instance_id)
{
	m_insertPool.clear();
	sEventMgr.AddEventHolder(this, instance_id);
}

EventableObjectHolder::~EventableObjectHolder()
{
	sEventMgr.RemoveEventHolder(this);

	m_insertPoolLock.Acquire();
	EventList::iterator insertPoolItr = m_insertPool.begin();
	for(; insertPoolItr != m_insertPool.end(); ++insertPoolItr)
		(*insertPoolItr)->DecRef();
	m_insertPoolLock.Release();

	/* decrement events reference count */
	m_lock.Acquire();
	EventList::iterator itr = m_events.begin();
	for(; itr != m_events.end(); ++itr)
		(*itr)->DecRef();
	m_lock.Release();
}

void EventableObjectHolder::Update(time_t time_difference)
{
	m_lock.Acquire();			// <<<<

	/* Insert any pending objects in the insert pool. */
	m_insertPoolLock.Acquire();
	InsertableQueue::iterator iqi;
	InsertableQueue::iterator iq2 = m_insertPool.begin();
	while(iq2 != m_insertPool.end())
	{
		iqi = iq2++;
		if((*iqi)->deleted || (*iqi)->instanceId != mInstanceId)
			(*iqi)->DecRef();
		else
			m_events.push_back( (*iqi) );

		m_insertPool.erase(iqi);
	}
	m_insertPoolLock.Release();

	/* Now we can proceed normally. */
	EventList::iterator itr = m_events.begin();
	EventList::iterator it2;
	TimedEvent * ev;

	while(itr != m_events.end())
	{
		it2 = itr++;

		if((*it2)->instanceId != mInstanceId || (*it2)->deleted ){

			(*it2)->DecRef();

			// remove from this list.
			m_events.erase(it2);

			continue;
		}

		// Event Update Procedure
		ev = *it2;

		if(ev->currTime <= time_difference)
		{
			// execute the callback
			if(ev->eventFlag & EVENT_FLAG_DELETES_OBJECT)
			{
				m_events.erase(it2);
				ev->deleted = true;
				ev->cb->execute();
				ev->DecRef();
				continue;
			}
			else
				ev->cb->execute();

			// check if the event is expired now.
            if(ev->repeats && --ev->repeats == 0)
			{
				// Event expired :>

				/* remove the event from the object */
				/*obj = (EventableObject*)ev->obj;
				obj->event_RemoveByPointer(ev);*/

				/* remove the event from here */
				ev->deleted = true;
				ev->DecRef();
				m_events.erase(it2);

				continue;
			}
			else if(ev->deleted)
			{
				// event is now deleted
				ev->DecRef(); //this was added on "addevent"
				m_events.erase(it2);
				continue;
			}

			// event has to repeat again, reset the timer
			ev->currTime = ev->msTime;
		}
		else
		{
			// event is still "waiting", subtract time difference
			ev->currTime -= time_difference;
		}
	}

	m_lock.Release();
}

void EventableObject::event_Relocate()
{
	/* prevent any new stuff from getting added */
	m_lock.Acquire();

	EventableObjectHolder * nh = sEventMgr.GetEventHolder(event_GetInstanceID());
	if(nh != m_holder)
	{
		// whee, we changed event holder :>
		// doing this will change the instanceid on all the events, as well as add to the new holder.

		//If nh is NULL then we were removed from world. There's no reason to be added to WORLD_INSTANCE EventMgr, let's just wait till something will add us again to world.
		if( nh == NULL )
		{
			//set instaceId to 0 to each event of this EventableObject, so EventableObjectHolder::Update() will remove them from its EventList.
			for( EventMap::iterator itr = m_events.begin(); itr != m_events.end(); ++itr )
			{
				itr->second->instanceId = 0;
			}
			// reset our instance id.
			m_event_Instanceid = 0;
		}
		else
		{
			nh->AddObject(this);
			// reset our instance id
			m_event_Instanceid = nh->GetInstanceID();
		}
		// reset our m_holder pointer
		m_holder = nh;
	}

	/* safe again to add */
	m_lock.Release();
}

uint32 EventableObject::event_GetEventPeriod(uint32 EventType)
{
	uint32 ret = 0;
	m_lock.Acquire();
	EventMap::iterator itr = m_events.find(EventType);
	if(itr != m_events.end())
		ret = (uint32)itr->second->msTime;

	m_lock.Release();
	return ret;
}

void EventableObjectHolder::AddEvent(TimedEvent * ev)
{
	// m_lock NEEDS TO BE A RECURSIVE MUTEX
	ev->IncRef();
	if(!m_lock.AttemptAcquire())
	{
		m_insertPoolLock.Acquire();
		m_insertPool.push_back( ev );
		m_insertPoolLock.Release();
	}
	else
	{
		m_events.push_back( ev );
		m_lock.Release();
	}
}

void EventableObjectHolder::AddObject(EventableObject * obj)
{
	// transfer all of this objects events into our holder
	if(!m_lock.AttemptAcquire())
	{
		// The other thread is obviously occupied. We have to use an insert pool here, otherwise
		// if 2 threads relocate at once we'll hit a deadlock situation.
		m_insertPoolLock.Acquire();
		EventMap::iterator it2;

		for(EventMap::iterator itr = obj->m_events.begin(); itr != obj->m_events.end(); ++itr)
		{
			// ignore deleted events (shouldn't be any in here, actually)
			if(itr->second->deleted)
			{
				/*it2 = itr++;
				itr->second->DecRef();
				obj->m_events.erase(it2);*/
				continue;
			}

			itr->second->IncRef();
			itr->second->instanceId = mInstanceId;
			m_insertPool.push_back(itr->second);
		}

		// Release the insert pool.
		m_insertPoolLock.Release();

		// Ignore the rest of this stuff
		return;
	}
	else
	{
		for(EventMap::iterator itr = obj->m_events.begin(); itr != obj->m_events.end(); ++itr)
		{
			// ignore deleted events
			if(itr->second->deleted)
				continue;

			itr->second->IncRef();
			itr->second->instanceId = mInstanceId;
			m_events.push_back( itr->second );
		}
		m_lock.Release();
	}
}
<|endoftext|>


<commit_before>//===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-python.h"

#include "CommandObjectHelp.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// CommandObjectHelp
//-------------------------------------------------------------------------

CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
    CommandObjectParsed (interpreter,
                         "help",
                         "Show a list of all debugger commands, or give details about specific commands.",
                         "help [<cmd-name>]"), m_options (interpreter)
{
    CommandArgumentEntry arg;
    CommandArgumentData command_arg;

    // Define the first (and only) variant of this arg.
    command_arg.arg_type = eArgTypeCommandName;
    command_arg.arg_repetition = eArgRepeatStar;

    // There is only one variant this argument could be; put it into the argument entry.
    arg.push_back (command_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back (arg);
}

CommandObjectHelp::~CommandObjectHelp()
{
}

OptionDefinition
CommandObjectHelp::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Hide aliases in the command list."},
    { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Hide user-defined commands from the list."},
    { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Include commands prefixed with an underscore."},
    { 0, false, NULL, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};

bool
CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
{
    CommandObject::CommandMap::iterator pos;
    CommandObject *cmd_obj;
    const size_t argc = command.GetArgumentCount ();

    // 'help' doesn't take any arguments, other than command names.  If argc is 0, we show the user
    // all commands (aliases and user commands if asked for).  Otherwise every argument must be the name of a command or a sub-command.
    if (argc == 0)
    {
        uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
        if (m_options.m_show_aliases)
            cmd_types |= CommandInterpreter::eCommandTypesAliases;
        if (m_options.m_show_user_defined)
            cmd_types |= CommandInterpreter::eCommandTypesUserDef;
        if (m_options.m_show_hidden)
            cmd_types |= CommandInterpreter::eCommandTypesHidden;

        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        m_interpreter.GetHelp (result, cmd_types);  // General help
    }
    else
    {
        // Get command object for the first command argument. Only search built-in command dictionary.
        StringList matches;
        cmd_obj = m_interpreter.GetCommandObject (command.GetArgumentAtIndex (0), &matches);
        bool is_alias_command = m_interpreter.AliasExists (command.GetArgumentAtIndex (0));
        std::string alias_name = command.GetArgumentAtIndex(0);

        if (cmd_obj != NULL)
        {
            StringList matches;
            bool all_okay = true;
            CommandObject *sub_cmd_obj = cmd_obj;
            // Loop down through sub_command dictionaries until we find the command object that corresponds
            // to the help command entered.
            for (size_t i = 1; i < argc && all_okay; ++i)
            {
                std::string sub_command = command.GetArgumentAtIndex(i);
                matches.Clear();
                if (! sub_cmd_obj->IsMultiwordObject ())
                {
                    all_okay = false;
                }
                else
                {
                    CommandObject *found_cmd;
                    found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
                    if (found_cmd == NULL)
                        all_okay = false;
                    else if (matches.GetSize() > 1)
                        all_okay = false;
                    else
                        sub_cmd_obj = found_cmd;
                }
            }

            if (!all_okay || (sub_cmd_obj == NULL))
            {
                std::string cmd_string;
                command.GetCommandString (cmd_string);
                if (matches.GetSize() >= 2)
                {
                    StreamString s;
                    s.Printf ("ambiguous command %s", cmd_string.c_str());
                    size_t num_matches = matches.GetSize();
                    for (size_t match_idx = 0; match_idx < num_matches; match_idx++)
                    {
                        s.Printf ("\n\t%s", matches.GetStringAtIndex(match_idx));
                    }
                    s.Printf ("\n");
                    result.AppendError(s.GetData());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else if (!sub_cmd_obj)
                {
                    result.AppendErrorWithFormat("'%s' is not a known command.\n"
                                                 "Try '%shelp' to see a current list of commands.\n",
                                                 cmd_string.c_str(),
                                                 m_interpreter.GetCommandPrefix());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else
                {
                    result.GetOutputStream().Printf("'%s' is not a known command.\n"
                                                   "Try '%shelp' to see a current list of commands.\n"
                                                    "The closest match is '%s'. Help on it follows.\n\n",
                                                   cmd_string.c_str(),
                                                   m_interpreter.GetCommandPrefix(),
                                                   sub_cmd_obj->GetCommandName());
                }
            }

            sub_cmd_obj->GenerateHelpText(result);

            if (is_alias_command)
            {
                StreamString sstr;
                m_interpreter.GetAliasHelp (alias_name.c_str(), cmd_obj->GetCommandName(), sstr);
                result.GetOutputStream().Printf ("\n'%s' is an abbreviation for %s\n", alias_name.c_str(), sstr.GetData());
            }
        }
        else if (matches.GetSize() > 0)
        {
            Stream &output_strm = result.GetOutputStream();
            output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
            const size_t match_count = matches.GetSize();
            for (size_t i = 0; i < match_count; i++)
            {
                output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
            }
        }
        else
        {
            // Maybe the user is asking for help about a command argument rather than a command.
            const CommandArgumentType arg_type = CommandObject::LookupArgumentName (command.GetArgumentAtIndex (0));
            if (arg_type != eArgTypeLastArg)
            {
                Stream &output_strm = result.GetOutputStream ();
                CommandObject::GetArgumentHelp (output_strm, arg_type, m_interpreter);
                result.SetStatus (eReturnStatusSuccessFinishNoResult);
            }
            else
            {
                result.AppendErrorWithFormat
                    ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
                     command.GetArgumentAtIndex(0),
                     m_interpreter.GetCommandPrefix());
                result.SetStatus (eReturnStatusFailed);
            }
        }
    }

    return result.Succeeded();
}

int
CommandObjectHelp::HandleCompletion
(
    Args &input,
    int &cursor_index,
    int &cursor_char_position,
    int match_start_point,
    int max_return_elements,
    bool &word_complete,
    StringList &matches
)
{
    // Return the completions of the commands in the help system:
    if (cursor_index == 0)
    {
        return m_interpreter.HandleCompletionMatches (input,
                                                    cursor_index,
                                                    cursor_char_position,
                                                    match_start_point,
                                                    max_return_elements,
                                                    word_complete,
                                                    matches);
    }
    else
    {
        CommandObject *cmd_obj = m_interpreter.GetCommandObject (input.GetArgumentAtIndex(0));

        // The command that they are getting help on might be ambiguous, in which case we should complete that,
        // otherwise complete with the command the user is getting help on...

        if (cmd_obj)
        {
            input.Shift();
            cursor_index--;
            return cmd_obj->HandleCompletion (input,
                                              cursor_index,
                                              cursor_char_position,
                                              match_start_point,
                                              max_return_elements,
                                              word_complete,
                                              matches);
        }
        else
        {
            return m_interpreter.HandleCompletionMatches (input,
                                                        cursor_index,
                                                        cursor_char_position,
                                                        match_start_point,
                                                        max_return_elements,
                                                        word_complete,
                                                        matches);
        }
    }
}
<commit_msg>Fix build after r226068: cannot initialize 'int' with 'nullptr_t'<commit_after>//===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-python.h"

#include "CommandObjectHelp.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// CommandObjectHelp
//-------------------------------------------------------------------------

CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
    CommandObjectParsed (interpreter,
                         "help",
                         "Show a list of all debugger commands, or give details about specific commands.",
                         "help [<cmd-name>]"), m_options (interpreter)
{
    CommandArgumentEntry arg;
    CommandArgumentData command_arg;

    // Define the first (and only) variant of this arg.
    command_arg.arg_type = eArgTypeCommandName;
    command_arg.arg_repetition = eArgRepeatStar;

    // There is only one variant this argument could be; put it into the argument entry.
    arg.push_back (command_arg);

    // Push the data for the first argument into the m_arguments vector.
    m_arguments.push_back (arg);
}

CommandObjectHelp::~CommandObjectHelp()
{
}

OptionDefinition
CommandObjectHelp::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Hide aliases in the command list."},
    { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Hide user-defined commands from the list."},
    { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Include commands prefixed with an underscore."},
    { 0, false, NULL, 0, 0, 0, NULL, 0, eArgTypeNone, NULL }
};

bool
CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
{
    CommandObject::CommandMap::iterator pos;
    CommandObject *cmd_obj;
    const size_t argc = command.GetArgumentCount ();

    // 'help' doesn't take any arguments, other than command names.  If argc is 0, we show the user
    // all commands (aliases and user commands if asked for).  Otherwise every argument must be the name of a command or a sub-command.
    if (argc == 0)
    {
        uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
        if (m_options.m_show_aliases)
            cmd_types |= CommandInterpreter::eCommandTypesAliases;
        if (m_options.m_show_user_defined)
            cmd_types |= CommandInterpreter::eCommandTypesUserDef;
        if (m_options.m_show_hidden)
            cmd_types |= CommandInterpreter::eCommandTypesHidden;

        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        m_interpreter.GetHelp (result, cmd_types);  // General help
    }
    else
    {
        // Get command object for the first command argument. Only search built-in command dictionary.
        StringList matches;
        cmd_obj = m_interpreter.GetCommandObject (command.GetArgumentAtIndex (0), &matches);
        bool is_alias_command = m_interpreter.AliasExists (command.GetArgumentAtIndex (0));
        std::string alias_name = command.GetArgumentAtIndex(0);

        if (cmd_obj != NULL)
        {
            StringList matches;
            bool all_okay = true;
            CommandObject *sub_cmd_obj = cmd_obj;
            // Loop down through sub_command dictionaries until we find the command object that corresponds
            // to the help command entered.
            for (size_t i = 1; i < argc && all_okay; ++i)
            {
                std::string sub_command = command.GetArgumentAtIndex(i);
                matches.Clear();
                if (! sub_cmd_obj->IsMultiwordObject ())
                {
                    all_okay = false;
                }
                else
                {
                    CommandObject *found_cmd;
                    found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
                    if (found_cmd == NULL)
                        all_okay = false;
                    else if (matches.GetSize() > 1)
                        all_okay = false;
                    else
                        sub_cmd_obj = found_cmd;
                }
            }

            if (!all_okay || (sub_cmd_obj == NULL))
            {
                std::string cmd_string;
                command.GetCommandString (cmd_string);
                if (matches.GetSize() >= 2)
                {
                    StreamString s;
                    s.Printf ("ambiguous command %s", cmd_string.c_str());
                    size_t num_matches = matches.GetSize();
                    for (size_t match_idx = 0; match_idx < num_matches; match_idx++)
                    {
                        s.Printf ("\n\t%s", matches.GetStringAtIndex(match_idx));
                    }
                    s.Printf ("\n");
                    result.AppendError(s.GetData());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else if (!sub_cmd_obj)
                {
                    result.AppendErrorWithFormat("'%s' is not a known command.\n"
                                                 "Try '%shelp' to see a current list of commands.\n",
                                                 cmd_string.c_str(),
                                                 m_interpreter.GetCommandPrefix());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                else
                {
                    result.GetOutputStream().Printf("'%s' is not a known command.\n"
                                                   "Try '%shelp' to see a current list of commands.\n"
                                                    "The closest match is '%s'. Help on it follows.\n\n",
                                                   cmd_string.c_str(),
                                                   m_interpreter.GetCommandPrefix(),
                                                   sub_cmd_obj->GetCommandName());
                }
            }

            sub_cmd_obj->GenerateHelpText(result);

            if (is_alias_command)
            {
                StreamString sstr;
                m_interpreter.GetAliasHelp (alias_name.c_str(), cmd_obj->GetCommandName(), sstr);
                result.GetOutputStream().Printf ("\n'%s' is an abbreviation for %s\n", alias_name.c_str(), sstr.GetData());
            }
        }
        else if (matches.GetSize() > 0)
        {
            Stream &output_strm = result.GetOutputStream();
            output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
            const size_t match_count = matches.GetSize();
            for (size_t i = 0; i < match_count; i++)
            {
                output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
            }
        }
        else
        {
            // Maybe the user is asking for help about a command argument rather than a command.
            const CommandArgumentType arg_type = CommandObject::LookupArgumentName (command.GetArgumentAtIndex (0));
            if (arg_type != eArgTypeLastArg)
            {
                Stream &output_strm = result.GetOutputStream ();
                CommandObject::GetArgumentHelp (output_strm, arg_type, m_interpreter);
                result.SetStatus (eReturnStatusSuccessFinishNoResult);
            }
            else
            {
                result.AppendErrorWithFormat
                    ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
                     command.GetArgumentAtIndex(0),
                     m_interpreter.GetCommandPrefix());
                result.SetStatus (eReturnStatusFailed);
            }
        }
    }

    return result.Succeeded();
}

int
CommandObjectHelp::HandleCompletion
(
    Args &input,
    int &cursor_index,
    int &cursor_char_position,
    int match_start_point,
    int max_return_elements,
    bool &word_complete,
    StringList &matches
)
{
    // Return the completions of the commands in the help system:
    if (cursor_index == 0)
    {
        return m_interpreter.HandleCompletionMatches (input,
                                                    cursor_index,
                                                    cursor_char_position,
                                                    match_start_point,
                                                    max_return_elements,
                                                    word_complete,
                                                    matches);
    }
    else
    {
        CommandObject *cmd_obj = m_interpreter.GetCommandObject (input.GetArgumentAtIndex(0));

        // The command that they are getting help on might be ambiguous, in which case we should complete that,
        // otherwise complete with the command the user is getting help on...

        if (cmd_obj)
        {
            input.Shift();
            cursor_index--;
            return cmd_obj->HandleCompletion (input,
                                              cursor_index,
                                              cursor_char_position,
                                              match_start_point,
                                              max_return_elements,
                                              word_complete,
                                              matches);
        }
        else
        {
            return m_interpreter.HandleCompletionMatches (input,
                                                        cursor_index,
                                                        cursor_char_position,
                                                        match_start_point,
                                                        max_return_elements,
                                                        word_complete,
                                                        matches);
        }
    }
}
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: randomCoilShiftProcessor.C,v 1.6.20.2 2007-04-12 13:53:22 anne Exp $

#include<BALL/NMR/randomCoilShiftProcessor.h>
#include<BALL/FORMAT/parameterSection.h>

namespace BALL
{

	const char* RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT = "RandomCoilShift";

	RandomCoilShiftProcessor::RandomCoilShiftProcessor()
	{
		system_ = NULL;
	}

	RandomCoilShiftProcessor::RandomCoilShiftProcessor(const RandomCoilShiftProcessor& processor)
		:	ShiftModule(processor),
			shift_map_(processor.shift_map_)
	{
		system_ = NULL;
	}

	RandomCoilShiftProcessor::~RandomCoilShiftProcessor()

	{
	}

	void RandomCoilShiftProcessor::init()
	{
		// We assume the worst case.
		valid_ = false;
		system_ = NULL;

		// Make sure we have correct parameters.
		if (parameters_ == 0)
		{
			return;
		}

		// Extract the data from the correct section.
		ParameterSection parameter_section;
		parameter_section.extractSection(*parameters_, "RandomCoilShifts");

		// Make sure the section contains the required columns.
		if (!parameter_section.hasVariable("shift"))
		{
			return;
		}

		// Extract the random coil shifts from the parameter section.
		Position shift_column = parameter_section.getColumnIndex("shift");
		for (Position i = 0; i < parameter_section.getNumberOfKeys(); i++)
		{
			shift_map_.insert(parameter_section.getKey(i),
												parameter_section.getValue(i, shift_column).toFloat());
		}

		// Initialization complete - mark the module as valid.
		valid_ = true;

		return;
	}

	Processor::Result RandomCoilShiftProcessor::operator () (Composite& composite)
	{
		// We are just interested in atoms.
		Atom* atom_ptr = dynamic_cast<Atom*>(&composite);
		if (atom_ptr == 0)
		{
			return Processor::CONTINUE;
		}

		// Try to get the system.
		if (!system_   && (RTTI::isKindOf<System>(atom_ptr->getRoot())))
		{
			system_ = dynamic_cast<System*>(&(atom_ptr->getRoot()));
		}

		// Get the atoms full name.
		String full_name = atom_ptr->getFullName();
		full_name.substitute(":", " ");
		if (!shift_map_.has(full_name))
		{
			full_name = atom_ptr->getFullName(Atom::NO_VARIANT_EXTENSIONS);
			full_name.substitute(":", " ");
			if (!shift_map_.has(full_name))
			{
				full_name = "* " + atom_ptr->getName();
				if (!shift_map_.has(full_name))
				{
					full_name = "";
				}
			}
		}

		if (full_name != "")
		{
			// Retrieve the random coil shift from the hash map.
			const float& delta_RC = shift_map_[full_name];

			// Add the random coil shift to the total shift value.
			float delta = atom_ptr->getProperty(ShiftModule::PROPERTY__SHIFT).getFloat();
			delta += delta_RC;
			atom_ptr->setProperty(ShiftModule::PROPERTY__SHIFT, delta);

			// Store the random coil shift as the random coil shift property.
			atom_ptr->setProperty(RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT, delta_RC);
		}

		return Processor::CONTINUE;
	}

	void   RandomCoilShiftProcessor::postprocessing_()
		throw()
	{
		if (system_)
		{
			// Add for all CA 0.2 times the values of HA ramdon coil shift contribution.
			for (BALL::ResidueIterator r_it = system_->beginResidue(); r_it != system_->endResidue(); ++r_it)
			{
				Atom* CA = 0;
				Atom* HA = 0;

				for (BALL::AtomIterator at_it = r_it->beginAtom(); +at_it; ++at_it)
				{
					if (at_it->getName() == "CA")
						CA = &(*at_it);
					if (at_it->getName() == "HA")
						HA = &(*at_it);
				}

				if (CA && HA)
				{
					float total = CA->getProperty(ShiftModule::PROPERTY__SHIFT).getFloat();
					float ca_shift = CA->getProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT).getFloat();
					float ha_shift = HA->getProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT).getFloat();

					CA->setProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT, ca_shift + 0.2*ha_shift);
					CA->setProperty(ShiftModule::PROPERTY__SHIFT, total+ 0.2*ha_shift );
				}
			}
		}
		else
		{
				Log.error() << "Error in RandomCoilShiftProcessor: no system found for postprocessing. ("
				 					<< __FILE__ << " " << __LINE__ << ")" <<  std::endl;
		}
	}
}//namespace BALL
<commit_msg>Found some ancient throws, arrg!<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: randomCoilShiftProcessor.C,v 1.6.20.2 2007-04-12 13:53:22 anne Exp $

#include<BALL/NMR/randomCoilShiftProcessor.h>
#include<BALL/FORMAT/parameterSection.h>

namespace BALL
{

	const char* RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT = "RandomCoilShift";

	RandomCoilShiftProcessor::RandomCoilShiftProcessor()
	{
		system_ = NULL;
	}

	RandomCoilShiftProcessor::RandomCoilShiftProcessor(const RandomCoilShiftProcessor& processor)
		:	ShiftModule(processor),
			shift_map_(processor.shift_map_)
	{
		system_ = NULL;
	}

	RandomCoilShiftProcessor::~RandomCoilShiftProcessor()

	{
	}

	void RandomCoilShiftProcessor::init()
	{
		// We assume the worst case.
		valid_ = false;
		system_ = NULL;

		// Make sure we have correct parameters.
		if (parameters_ == 0)
		{
			return;
		}

		// Extract the data from the correct section.
		ParameterSection parameter_section;
		parameter_section.extractSection(*parameters_, "RandomCoilShifts");

		// Make sure the section contains the required columns.
		if (!parameter_section.hasVariable("shift"))
		{
			return;
		}

		// Extract the random coil shifts from the parameter section.
		Position shift_column = parameter_section.getColumnIndex("shift");
		for (Position i = 0; i < parameter_section.getNumberOfKeys(); i++)
		{
			shift_map_.insert(parameter_section.getKey(i),
												parameter_section.getValue(i, shift_column).toFloat());
		}

		// Initialization complete - mark the module as valid.
		valid_ = true;

		return;
	}

	Processor::Result RandomCoilShiftProcessor::operator () (Composite& composite)
	{
		// We are just interested in atoms.
		Atom* atom_ptr = dynamic_cast<Atom*>(&composite);
		if (atom_ptr == 0)
		{
			return Processor::CONTINUE;
		}

		// Try to get the system.
		if (!system_   && (RTTI::isKindOf<System>(atom_ptr->getRoot())))
		{
			system_ = dynamic_cast<System*>(&(atom_ptr->getRoot()));
		}

		// Get the atoms full name.
		String full_name = atom_ptr->getFullName();
		full_name.substitute(":", " ");
		if (!shift_map_.has(full_name))
		{
			full_name = atom_ptr->getFullName(Atom::NO_VARIANT_EXTENSIONS);
			full_name.substitute(":", " ");
			if (!shift_map_.has(full_name))
			{
				full_name = "* " + atom_ptr->getName();
				if (!shift_map_.has(full_name))
				{
					full_name = "";
				}
			}
		}

		if (full_name != "")
		{
			// Retrieve the random coil shift from the hash map.
			const float& delta_RC = shift_map_[full_name];

			// Add the random coil shift to the total shift value.
			float delta = atom_ptr->getProperty(ShiftModule::PROPERTY__SHIFT).getFloat();
			delta += delta_RC;
			atom_ptr->setProperty(ShiftModule::PROPERTY__SHIFT, delta);

			// Store the random coil shift as the random coil shift property.
			atom_ptr->setProperty(RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT, delta_RC);
		}

		return Processor::CONTINUE;
	}

	void   RandomCoilShiftProcessor::postprocessing_()
	{
		if (system_)
		{
			// Add for all CA 0.2 times the values of HA ramdon coil shift contribution.
			for (BALL::ResidueIterator r_it = system_->beginResidue(); r_it != system_->endResidue(); ++r_it)
			{
				Atom* CA = 0;
				Atom* HA = 0;

				for (BALL::AtomIterator at_it = r_it->beginAtom(); +at_it; ++at_it)
				{
					if (at_it->getName() == "CA")
						CA = &(*at_it);
					if (at_it->getName() == "HA")
						HA = &(*at_it);
				}

				if (CA && HA)
				{
					float total = CA->getProperty(ShiftModule::PROPERTY__SHIFT).getFloat();
					float ca_shift = CA->getProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT).getFloat();
					float ha_shift = HA->getProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT).getFloat();

					CA->setProperty(BALL::RandomCoilShiftProcessor::PROPERTY__RANDOM_COIL_SHIFT, ca_shift + 0.2*ha_shift);
					CA->setProperty(ShiftModule::PROPERTY__SHIFT, total+ 0.2*ha_shift );
				}
			}
		}
		else
		{
				Log.error() << "Error in RandomCoilShiftProcessor: no system found for postprocessing. ("
				 					<< __FILE__ << " " << __LINE__ << ")" <<  std::endl;
		}
	}
}//namespace BALL
<|endoftext|>


<commit_before>#include "stdafx.h"
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

class OptionManager
{
public:
    static inline HWND* hWnd = nullptr;
    static inline bool* bIsInvertX = nullptr;
    static inline bool* bIsInvertY = nullptr;
    static inline int* nMouseLookSensitivity = nullptr;
    static inline bool bGamepadUsed = false;
    static inline bool (*pScarfaceHook_GetMenuActive)() = nullptr;

    static inline bool IsInvertX()
    {
        return *bIsInvertX;
    }
    static inline bool IsInvertY()
    {
        return *bIsInvertY;
    }
    static inline float GetMouseLookSensitivity()
    {
        return *nMouseLookSensitivity / 10.0f;
    }
    static inline bool ScarfaceHook_GetMenuActive()
    {
        if (pScarfaceHook_GetMenuActive)
            return pScarfaceHook_GetMenuActive();
        else
            return false;
    }
};

void SetMouseInput(float* dest_x, float* dest_y, float value_x = 0.0f, float value_y = 0.0f)
{
    if (OptionManager::bGamepadUsed)
        return;

    if ((*OptionManager::hWnd == GetForegroundWindow()) && !OptionManager::ScarfaceHook_GetMenuActive())
    {
        RECT windowRect;
        POINT MousePos;
        GetCursorPos(&MousePos);
        GetWindowRect(*OptionManager::hWnd, &windowRect);
        int CenterX = ((windowRect.right - windowRect.left) / 2) + windowRect.left;
        int CenterY = ((windowRect.bottom - windowRect.top) / 2) + windowRect.top;

        float sign_x = 1.0f;
        float sign_y = 1.0f;
        if (OptionManager::IsInvertX())
            sign_x = -1.0f;
        if (OptionManager::IsInvertY())
            sign_y = -1.0f;

        if (value_x)
            *dest_x = value_x + ((float)((MousePos.x - CenterX) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_x;
        else
            *dest_x += ((float)((MousePos.x - CenterX) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_x;

        if (value_y)
            *dest_y = value_y + -((float)((MousePos.y - CenterY) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_y;
        else
            *dest_y += -((float)((MousePos.y - CenterY) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_y;

        SetCursorPos(CenterX, CenterY);
    }
}

injector::hook_back<char(__fastcall*)(float* mInputs, void* edx, float* angleH, float* angleV, float deltaTime)> hb_GenericVehicleCamera_ApplyRightStickMotion;
char __fastcall GenericVehicleCamera_ApplyRightStickMotion(float* mInputs, void* edx, float* angleH, float* angleV, float deltaTime)
{
    auto H = *angleH;
    auto V = *angleV;

    auto ret = hb_GenericVehicleCamera_ApplyRightStickMotion.fun(mInputs, edx, angleH, angleV, deltaTime);

    SetMouseInput(angleH, angleV, H, V);

    if ((GetAsyncKeyState(VK_RBUTTON)))
        return 1;
    else
        return ret;
}

void Init()
{
    CIniReader iniReader("");
    auto bSkipIntro = iniReader.ReadInteger("MAIN", "SkipIntro", 1) != 0;
    auto bScrollWeaponsWithMouseWheel = iniReader.ReadInteger("MAIN", "ScrollWeaponsWithMouseWheel", 1) != 0;

    if (bSkipIntro)
    {
        auto pattern = hook::pattern("E8 ? ? ? ? 83 C4 20 5F 5E C7 45");
        injector::MakeNOP(pattern.get_first(), 5); //movies
        pattern = hook::pattern("75 22 E8 ? ? ? ? 8B C8");
        injector::MakeNOP(pattern.get_first(), 2); //press to start
    }

    auto pattern = hook::pattern("A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A3");
    OptionManager::bIsInvertX = *pattern.get_first<bool*>(1);
    OptionManager::bIsInvertY = *pattern.get_first<bool*>(6);
    pattern = hook::pattern("E8 ? ? ? ? 56 68 ? ? ? ? E8 ? ? ? ? 83 C4 10");
    OptionManager::nMouseLookSensitivity = *(int**)(injector::GetBranchDestination(pattern.get_first()).as_int() + 5);

    pattern = hook::pattern("A3 ? ? ? ? 5B 74 0F");
    OptionManager::hWnd = *pattern.get_first<HWND*>(1);

    pattern = hook::pattern("D9 58 10 83 C4 5C C2 0C 00");
    struct SetOutput_Update_FreeLook
    {
        void operator()(injector::reg_pack& regs)
        {
            SetMouseInput((float*)(regs.eax + 0x0C), (float*)(regs.eax + 0x10));
        }
    }; injector::MakeInline<SetOutput_Update_FreeLook>(pattern.get_first(6));
    injector::MakeRET(pattern.get_first(6+5), 0xC);

    //camera blend disable
    pattern = hook::pattern("83 EC 10 57 8B F9 80 BF");
    injector::MakeRET(pattern.get_first(0), 8);

    //vehicle camera
    pattern = hook::pattern("E8 ? ? ? ? 84 C0 74 0C C6 85");
    hb_GenericVehicleCamera_ApplyRightStickMotion.fun = injector::MakeCALL(pattern.get_first(0), GenericVehicleCamera_ApplyRightStickMotion, true).get();

    //melee camera
    pattern = hook::pattern("D9 59 10 88 41 19");
    struct SetOutput_Update_MeleeTarget
    {
        void operator()(injector::reg_pack& regs)
        {
            *(uint8_t*)(regs.ecx + 0x19) = *(uint8_t*)&regs.eax;
            *(uint8_t*)(regs.ecx + 0x18) = 0;

            SetMouseInput((float*)(regs.ecx + 0x0C), (float*)(regs.ecx + 0x10));
        }
    }; injector::MakeInline<SetOutput_Update_MeleeTarget>(pattern.get_first(3), pattern.get_first(10));

    pattern = hook::pattern("B9 ? ? ? ? 21 4C 24 10 D9 44 24 10 89 54 24 14");
    struct GamepadCheck
    {
        void operator()(injector::reg_pack& regs)
        {
            regs.ecx = 0x7FFFFFFF;
            OptionManager::bGamepadUsed = (*(float*)(regs.esp + 0x1C) + *(float*)(regs.esp + 0x18)) != 0.0f;
        }
    }; injector::MakeInline<GamepadCheck>(pattern.get_first(0));

    if (bScrollWeaponsWithMouseWheel)
    {
        static int nMouseWheelValue = 0;
        pattern = hook::pattern("8B B7 ? ? ? ? 85 F6 74 21 90");
        struct GetDeviceDataHook
        {
            void operator()(injector::reg_pack& regs)
            {
                regs.esi = *(uint32_t*)(regs.edi + 0x264);

                auto rgdod = (LPDIDEVICEOBJECTDATA)(regs.esp + 0x10);
                if (rgdod)
                {
                    nMouseWheelValue = 0;
                    switch (rgdod->dwOfs)
                    {
                    case DIMOFS_Z:
                        nMouseWheelValue = rgdod->dwData;
                        break;
                    default:
                        break;
                    }
                }
            }
        }; injector::MakeInline<GetDeviceDataHook>(pattern.get_first(0), pattern.get_first(6));

        pattern = hook::pattern("0F BF 54 24 08 ? ? ? ? 03");
        if (pattern.empty()) pattern = hook::pattern("0F BF 54 24 ? E9");
        struct MouseScroll
        {
            void operator()(injector::reg_pack& regs)
            {
                *(int32_t*)&regs.edx = *(int16_t*)(regs.esp + 0x8);

                enum
                {
                    weaponleft = 0x9,
                    weaponright = 0xA
                };

                static auto counter = 0;
                if (nMouseWheelValue >= WHEEL_DELTA)
                    counter++;
                else if (nMouseWheelValue <= -WHEEL_DELTA)
                    counter--;
                else
                    counter = 0;

                static constexpr auto duration = 30;
                if (counter > 0 && counter < duration)
                    *(int16_t*)(regs.ecx + weaponleft * 2) = 1; // 1
                else if (counter < 0 && counter > -duration)
                    *(int16_t*)(regs.ecx + weaponright * 2) = 1; // 3

                if (counter < -duration || counter > duration)
                {
                    counter = 0;
                    nMouseWheelValue = 0;
                }
            }
        }; injector::MakeInline<MouseScroll>(pattern.get_first(0));
    }
}

void InitXidi()
{
    CIniReader iniReader("");
    auto bModernControlScheme = iniReader.ReadInteger("MAIN", "ModernControlScheme", 1) != 0;

    if (bModernControlScheme)
    {
        auto SetScarfaceData = (void (*)(uint32_t* menu, uint8_t* state))GetProcAddress(GetModuleHandleW(L"dinput8.dll"), "SetScarfaceData");
        if (SetScarfaceData)
        {
            auto nMenuCheck = *(uint32_t**)(injector::GetBranchDestination(hook::get_pattern("E8 ? ? ? ? 88 43 60")).as_int() + 1);
            auto bStateCheck = *hook::get_pattern<uint8_t*>("B9 ? ? ? ? E8 ? ? ? ? 5E C3", 1);
            SetScarfaceData(nMenuCheck, bStateCheck);
        }
    }
}

void InitScarfaceHook()
{
    OptionManager::pScarfaceHook_GetMenuActive = (bool (*)())GetProcAddress(GetModuleHandleW(L"ScarfaceHook.asi"), "ScarfaceHook_GetMenuActive");
}

CEXP void InitializeASI()
{
    std::call_once(CallbackHandler::flag, []()
    {
        CallbackHandler::RegisterCallback(Init, hook::pattern("B9 ? ? ? ? E8 ? ? ? ? 5E C3"));
        CallbackHandler::RegisterCallback(L"dinput8.dll", InitXidi);
        CallbackHandler::RegisterCallback(L"ScarfaceHook.asi", InitScarfaceHook);
    });
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        if (!IsUALPresent()) { InitializeASI(); }
    }
    return TRUE;
}<commit_msg>scarface: bugfix<commit_after>#include "stdafx.h"
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>

class OptionManager
{
public:
    static inline HWND* hWnd = nullptr;
    static inline bool* bIsInvertX = nullptr;
    static inline bool* bIsInvertY = nullptr;
    static inline int* nMouseLookSensitivity = nullptr;
    static inline bool bGamepadUsed = false;
    static inline bool (*pScarfaceHook_GetMenuActive)() = nullptr;

    static inline bool IsInvertX()
    {
        return *bIsInvertX;
    }
    static inline bool IsInvertY()
    {
        return *bIsInvertY;
    }
    static inline float GetMouseLookSensitivity()
    {
        return *nMouseLookSensitivity / 10.0f;
    }
    static inline bool ScarfaceHook_GetMenuActive()
    {
        if (pScarfaceHook_GetMenuActive)
            return pScarfaceHook_GetMenuActive();
        else
            return false;
    }
};

void SetMouseInput(float* dest_x, float* dest_y, float value_x = 0.0f, float value_y = 0.0f)
{
    if (OptionManager::bGamepadUsed)
        return;

    if ((*OptionManager::hWnd == GetForegroundWindow()) && !OptionManager::ScarfaceHook_GetMenuActive())
    {
        RECT windowRect;
        POINT MousePos;
        GetCursorPos(&MousePos);
        GetWindowRect(*OptionManager::hWnd, &windowRect);
        int CenterX = ((windowRect.right - windowRect.left) / 2) + windowRect.left;
        int CenterY = ((windowRect.bottom - windowRect.top) / 2) + windowRect.top;

        float sign_x = 1.0f;
        float sign_y = 1.0f;
        if (OptionManager::IsInvertX())
            sign_x = -1.0f;
        if (OptionManager::IsInvertY())
            sign_y = -1.0f;

        if (value_x)
            *dest_x = value_x + ((float)((MousePos.x - CenterX) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_x;
        else
            *dest_x += ((float)((MousePos.x - CenterX) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_x;

        if (value_y)
            *dest_y = value_y + -((float)((MousePos.y - CenterY) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_y;
        else
            *dest_y += -((float)((MousePos.y - CenterY) / 100.0f) * OptionManager::GetMouseLookSensitivity()) * sign_y;

        SetCursorPos(CenterX, CenterY);
    }
}

injector::hook_back<char(__fastcall*)(float* mInputs, void* edx, float* angleH, float* angleV, float deltaTime)> hb_GenericVehicleCamera_ApplyRightStickMotion;
char __fastcall GenericVehicleCamera_ApplyRightStickMotion(float* mInputs, void* edx, float* angleH, float* angleV, float deltaTime)
{
    auto H = *angleH;
    auto V = *angleV;

    auto ret = hb_GenericVehicleCamera_ApplyRightStickMotion.fun(mInputs, edx, angleH, angleV, deltaTime);

    SetMouseInput(angleH, angleV, H, V);

    if ((GetAsyncKeyState(VK_RBUTTON)))
        return 1;
    else
        return ret;
}

void Init()
{
    CIniReader iniReader("");
    auto bSkipIntro = iniReader.ReadInteger("MAIN", "SkipIntro", 1) != 0;
    auto bScrollWeaponsWithMouseWheel = iniReader.ReadInteger("MAIN", "ScrollWeaponsWithMouseWheel", 1) != 0;

    if (bSkipIntro)
    {
        auto pattern = hook::pattern("E8 ? ? ? ? 83 C4 20 5F 5E C7 45");
        injector::MakeNOP(pattern.get_first(), 5); //movies
        pattern = hook::pattern("75 22 E8 ? ? ? ? 8B C8");
        injector::MakeNOP(pattern.get_first(), 2); //press to start
    }

    auto pattern = hook::pattern("A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A2 ? ? ? ? A3");
    OptionManager::bIsInvertX = *pattern.get_first<bool*>(1);
    OptionManager::bIsInvertY = *pattern.get_first<bool*>(6);
    pattern = hook::pattern("E8 ? ? ? ? 56 68 ? ? ? ? E8 ? ? ? ? 83 C4 10");
    OptionManager::nMouseLookSensitivity = *(int**)(injector::GetBranchDestination(pattern.get_first()).as_int() + 5);

    pattern = hook::pattern("A3 ? ? ? ? 5B 74 0F");
    OptionManager::hWnd = *pattern.get_first<HWND*>(1);

    pattern = hook::pattern("D9 58 10 83 C4 5C C2 0C 00");
    struct SetOutput_Update_FreeLook
    {
        void operator()(injector::reg_pack& regs)
        {
            SetMouseInput((float*)(regs.eax + 0x0C), (float*)(regs.eax + 0x10));
        }
    }; injector::MakeInline<SetOutput_Update_FreeLook>(pattern.get_first(6));
    injector::MakeRET(pattern.get_first(6+5), 0xC);

    //camera blend disable
    pattern = hook::pattern("83 EC 10 57 8B F9 80 BF");
    injector::MakeRET(pattern.get_first(0), 8);

    //vehicle camera
    pattern = hook::pattern("E8 ? ? ? ? 84 C0 74 0C C6 85");
    hb_GenericVehicleCamera_ApplyRightStickMotion.fun = injector::MakeCALL(pattern.get_first(0), GenericVehicleCamera_ApplyRightStickMotion, true).get();

    //melee camera
    pattern = hook::pattern("D9 59 10 88 41 19");
    struct SetOutput_Update_MeleeTarget
    {
        void operator()(injector::reg_pack& regs)
        {
            *(uint8_t*)(regs.ecx + 0x19) = *(uint8_t*)&regs.eax;
            *(uint8_t*)(regs.ecx + 0x18) = 0;

            SetMouseInput((float*)(regs.ecx + 0x0C), (float*)(regs.ecx + 0x10));
        }
    }; injector::MakeInline<SetOutput_Update_MeleeTarget>(pattern.get_first(3), pattern.get_first(10));

    pattern = hook::pattern("B9 ? ? ? ? 21 4C 24 10 D9 44 24 10 89 54 24 14");
    struct GamepadCheck
    {
        void operator()(injector::reg_pack& regs)
        {
            regs.ecx = 0x7FFFFFFF;
            OptionManager::bGamepadUsed = (*(float*)(regs.esp + 0x1C) + *(float*)(regs.esp + 0x18)) != 0.0f;
        }
    }; injector::MakeInline<GamepadCheck>(pattern.get_first(0));

    if (bScrollWeaponsWithMouseWheel)
    {
        static int nMouseWheelValue = 0;
        pattern = hook::pattern("8B B7 ? ? ? ? 85 F6 74 21 90");
        struct GetDeviceDataHook
        {
            void operator()(injector::reg_pack& regs)
            {
                regs.esi = *(uint32_t*)(regs.edi + 0x264);
                auto controller = std::string_view((char*)regs.edi + 0x40);

                if (controller.starts_with("Mouse"))
                {
                    auto rgdod = (LPDIDEVICEOBJECTDATA)(regs.esp + 0x10);
                    if (rgdod)
                    {
                        nMouseWheelValue = 0;
                        switch (rgdod->dwOfs)
                        {
                        case DIMOFS_Z:
                            nMouseWheelValue = rgdod->dwData;
                            break;
                        default:
                            break;
                        }
                    }
                }
            }
        }; injector::MakeInline<GetDeviceDataHook>(pattern.get_first(0), pattern.get_first(6));

        pattern = hook::pattern("0F BF 54 24 08 ? ? ? ? 03");
        if (pattern.empty()) pattern = hook::pattern("0F BF 54 24 ? E9");
        struct MouseScroll
        {
            void operator()(injector::reg_pack& regs)
            {
                *(int32_t*)&regs.edx = *(int16_t*)(regs.esp + 0x8);

                if (OptionManager::bGamepadUsed)
                    return;

                enum
                {
                    weaponleft = 0x9,
                    weaponright = 0xA
                };

                static auto counter = 0;
                if (nMouseWheelValue >= WHEEL_DELTA)
                    counter++;
                else if (nMouseWheelValue <= -WHEEL_DELTA)
                    counter--;
                else
                    counter = 0;

                static constexpr auto duration = 30;
                if (counter > 0 && counter < duration)
                    *(int16_t*)(regs.ecx + weaponleft * 2) = 1; // 1
                else if (counter < 0 && counter > -duration)
                    *(int16_t*)(regs.ecx + weaponright * 2) = 1; // 3

                if (counter < -duration || counter > duration)
                {
                    counter = 0;
                    nMouseWheelValue = 0;
                }
            }
        }; injector::MakeInline<MouseScroll>(pattern.get_first(0));
    }
}

void InitXidi()
{
    CIniReader iniReader("");
    auto bModernControlScheme = iniReader.ReadInteger("MAIN", "ModernControlScheme", 1) != 0;

    if (bModernControlScheme)
    {
        auto SetScarfaceData = (void (*)(uint32_t* menu, uint8_t* state))GetProcAddress(GetModuleHandleW(L"dinput8.dll"), "SetScarfaceData");
        if (SetScarfaceData)
        {
            auto nMenuCheck = *(uint32_t**)(injector::GetBranchDestination(hook::get_pattern("E8 ? ? ? ? 88 43 60")).as_int() + 1);
            auto bStateCheck = *hook::get_pattern<uint8_t*>("B9 ? ? ? ? E8 ? ? ? ? 5E C3", 1);
            SetScarfaceData(nMenuCheck, bStateCheck);
        }
    }
}

void InitScarfaceHook()
{
    OptionManager::pScarfaceHook_GetMenuActive = (bool (*)())GetProcAddress(GetModuleHandleW(L"ScarfaceHook.asi"), "ScarfaceHook_GetMenuActive");
}

CEXP void InitializeASI()
{
    std::call_once(CallbackHandler::flag, []()
    {
        CallbackHandler::RegisterCallback(Init, hook::pattern("B9 ? ? ? ? E8 ? ? ? ? 5E C3"));
        CallbackHandler::RegisterCallback(L"dinput8.dll", InitXidi);
        CallbackHandler::RegisterCallback(L"ScarfaceHook.asi", InitScarfaceHook);
    });
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        if (!IsUALPresent()) { InitializeASI(); }
    }
    return TRUE;
}<|endoftext|>