Register for your free account! | Forgot your password?

Go Back   elitepvpers › Coders Den › C/C++
You last visited: Today at 10:44

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Event (Signal) Klasse

Discussion on Event (Signal) Klasse within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
Master674b's Avatar
 
elite*gold: 0
Join Date: Dec 2012
Posts: 255
Received Thanks: 110
Exclamation Event (Signal) Klasse

Hey, hatte mir als alternative zu boost::signal (da ich die irgendwie unbequem finde) eine eigene Event Klasse zusammengebaut.

Das ganze setzt voraus, dass euer Compiler variadische Templates unterstützt, ansonsten könnt ihr die Klasse mit mehreren Template Spezialisierungen überladen (hab da momentan 4 Überladungen drin, mehr Argumente brauch ich eigentlich nie).

Naja sieht jedenfalls so aus:

Code:
namespace Utils
{
	struct Minimum {
		template <typename T, typename InputIterator>
		static T Comp(InputIterator first, InputIterator last) {
			if (first == last)
				return T();

			T min_value = *first++;
			while (first != last) {
				if (min_value > *first)
					min_value = *first;
				++first;
			}

			return min_value;
		}
	};

	struct Maximum {
		template <typename T, typename InputIterator>
		static T Comp(InputIterator first, InputIterator last) {
			if (first == last)
				return T();

			T max_value = *first++;
			while (first != last) {
				if (max_value < *first)
					max_value = *first;
				++first;
			}

			return max_value;
		}
	};

	template <typename FuncT>
	struct SEventDelegate {
		uint64 token;
		std::function<FuncT> callback;
	};

	template <typename FuncT>
	class Event {};

#ifdef VARIADIC_TEMPLATES_SUPPORTED
	// Threadsafe
	template <typename R, typename... Args>
	class Event<R (Args...)>
	{
	public:
		typedef R fnconv_t(Args...);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()(const Args&... args) const {
			return _invoke_impl<R, Maximum>(args...);
		}

		template <typename CompT>
		R invoke(const Args&... args) const {
			return _invoke_impl<R, CompT>(args...);
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl(const Args&... args) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback(args...);
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl(const Args&... args) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback(args...));
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};
#else
	// [...] kein Variadic Template Support
	// Overloads von partiellen Template-Spezialisierungen benutzen.

	//////////// EVENT P0 //////////////

	// Threadsafe
	template <typename R>
	class Event<R (void)>
	{
	public:
		typedef R fnconv_t(void);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()() const {
			return _invoke_impl<R, Maximum>();
		}

		template <typename CompT>
		R invoke() const {
			return _invoke_impl<R, CompT>();
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl() const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback();
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl() const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback());
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};

	//////////// EVENT P1 //////////////

	// Threadsafe
	template <typename R, typename A0>
	class Event<R (A0)>
	{
	public:
		typedef R fnconv_t(A0);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()(const A0 &a0) const {
			return _invoke_impl<R, Maximum>(a0);
		}

		template <typename CompT>
		R invoke(const A0 &a0) const {
			return _invoke_impl<R, CompT>(a0);
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback(a0);
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback(a0));
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};

	//////////// EVENT P2 //////////////

	// Threadsafe
	template <typename R, typename A0, typename A1>
	class Event<R (A0, A1)>
	{
	public:
		typedef R fnconv_t(A0, A1);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()(const A0 &a0, const A1 &a1) const {
			return _invoke_impl<R, Maximum>(a0, a1);
		}

		template <typename CompT>
		R invoke(const A0 &a0, const A1 &a1) const {
			return _invoke_impl<R, CompT>(a0, a1);
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback(a0, a1);
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback(a0, a1));
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};

	//////////// EVENT P3 //////////////

	// Threadsafe
	template <typename R, typename A0, typename A1, typename A2>
	class Event<R (A0, A1, A2)>
	{
	public:
		typedef R fnconv_t(A0, A1, A2);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()(const A0 &a0, const A1 &a1, const A2 &a2) const {
			return _invoke_impl<R, Maximum>(a0, a1, a2);
		}

		template <typename CompT>
		R invoke(const A0 &a0, const A1 &a1, const A2 &a2) const {
			return _invoke_impl<R, CompT>(a0, a1, a2);
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1, const A2 &a2) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback(a0, a1, a2);
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1, const A2 &a2) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback(a0, a1, a2));
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};

	//////////// EVENT P4 //////////////

	// Threadsafe
	template <typename R, typename A0, typename A1, typename A2, typename A3>
	class Event<R (A0, A1, A2, A3)>
	{
	public:
		typedef R fnconv_t(A0, A1, A2, A3);
		Event() : m_mutex(), m_tokenMgr(), m_delegates() {}

		Event(const std::function<fnconv_t> &func) :
			m_mutex(), m_tokenMgr(), m_delegates() {
			connect(func);
		}

		Event(Event<fnconv_t> &&other) :
			m_tokenMgr(std::move(other.m_tokenMgr)),
			m_mutex(std::move(other.m_mutex)),
			m_delegates(std::move(other.m_delegates)) {}

		Event<fnconv_t>& operator=(Event<fnconv_t> &&other) {
			m_tokenMgr = std::move(other.m_tokenMgr);
			m_mutex = std::move(other.m_mutex);
			m_delegates = std::move(other.m_delegates);
			return *this;
		}

		R operator()(const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3) const {
			return _invoke_impl<R, Maximum>(a0, a1, a2, a3);
		}

		template <typename CompT>
		R invoke(const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3) const {
			return _invoke_impl<R, CompT>(a0, a1, a2, a3);
		}

		SEventDelegate<fnconv_t> operator+=(const std::function<fnconv_t> &func) {
			return connect(func);
		}

		Event<fnconv_t>& operator-=(const SEventDelegate<fnconv_t> &deleg) {
			remove(deleg.token);
			return *this;
		}

		SEventDelegate<fnconv_t> connect(const std::function<fnconv_t> &func) {
			std::lock_guard<std::mutex> g(m_mutex);
			SEventDelegate<fnconv_t> deleg = { m_tokenMgr.get(), func };
			m_delegates[deleg.token] = deleg;
			return deleg;
		}

		void remove(const uint64 &token) {
			std::lock_guard<std::mutex> g(m_mutex);
			auto itr = m_delegates.find(token);
			if (itr != m_delegates.end()) {
				m_tokenMgr.remove(token);
				m_delegates.erase(itr);
			}
		}

		void clear() {
			m_mutex.lock();
			m_delegates.clear();
			m_tokenMgr.reset();
			m_mutex.unlock();
		}

	protected:
		TokenManager m_tokenMgr;
		mutable std::mutex m_mutex;
		std::map<uint64, SEventDelegate<fnconv_t>> m_delegates;

		template <typename T, typename CompT>
		typename std::enable_if<std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			for (auto& pair: mDelegates)
				pair.second.callback(a0, a1, a2, a3);
		}

		template <typename T, typename CompT>
		typename std::enable_if<!std::is_same<void, T>::value, T>::type
			_invoke_impl(const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3) const {
			m_mutex.lock();
			auto mDelegates = m_delegates;
			m_mutex.unlock();

			std::vector<T> results;
			results.reserve(mDelegates.size());
			for (auto& pair: mDelegates)
				results.push_back(pair.second.callback(a0, a1, a2, a3));
			return CompT::Comp<T>(results.cbegin(), results.cend());
		}
	};
#endif
}
Anwendungsbeispiel:

Code:
// Event erstellen...
Utils::Event<uint32 (uint32, uint32)> someEvent;

// Multiply Event registrieren...
auto mulDelegate = someEvent +=
[] (uint32 a, uint32 b) {
    return a * b;
};

// Add-Event registrieren...
auto addDelegate = someEvent +=
[] (uint32 a, uint32 b) {
    return a + b;
};

// Event mit Standard-Comparer (Utils::Maximum) aufrufen...
std::cout << someEvent(3, 5) << std::endl;

// Event mit explizitem Comparer (Utils::Minimum) aufrufen...
std::cout << someEvent.invoke<Utils::Minimum>(3, 5) << std::endl;

// Multiply-Event löschen...
someEvent -= mulDelegate;

// Nochmals mit Standard-Comparer (Utils::Maximum) aufrufen...
std::cout << someEvent(3, 5) << std::endl;

// Ausgabe: 15, 8, 8
Benutze zum registrieren der Events noch meinen TokenManager, der sieht einfach so aus:

Code:
namespace Utils
{
	class TokenManager
	{
	public:
		TokenManager() : m_curMaxToken(0) {}

		TokenManager(TokenManager &&other) :
			m_curMaxToken(other.m_curMaxToken),
			m_freeTokens(std::move(other.m_freeTokens)) {
			other.m_curMaxToken = 0;
		}

		TokenManager& operator = (TokenManager &&other) {
			m_curMaxToken = other.m_curMaxToken;
			m_freeTokens = std::move(other.m_freeTokens);

			other.m_curMaxToken = 0;
			return *this;
		}

		uint64 get() {
			if (m_freeTokens.empty())
				return ++m_curMaxToken;

			auto itr = m_freeTokens.begin();
			uint64 curToken = *itr;
			m_freeTokens.erase(itr);
			return curToken;
		}

		void remove(const uint64 &token) {
			if (token != 0) {
				if (token == m_curMaxToken)
					--m_curMaxToken;

				else if (token < m_curMaxToken)
					m_freeTokens.insert(token);
			}
		}

		bool is_free(const uint64 &token) const {
			return token > m_curMaxToken ||
				m_freeTokens.find(token) != m_freeTokens.end();
		}

		void reset() {
			m_curMaxToken = 0;
			m_freeTokens.clear();
		}

	protected:
		uint64 m_curMaxToken;
		std::set<uint64> m_freeTokens;
	};
}
Master674b is offline  
Thanks
2 Users
Old   #2




 
Omdi's Avatar
 
elite*gold: 1371
Join Date: Apr 2010
Posts: 13,810
Received Thanks: 15,064
Sieht sehr hübsch aus, dankeschön kommt mir gerade gelegen
Omdi is offline  
Old   #3
 
Master674b's Avatar
 
elite*gold: 0
Join Date: Dec 2012
Posts: 255
Received Thanks: 110
Comparer Mechanik hinzugefügt. Anwendungsbeispiel oben.
Master674b is offline  
Old   #4
 
Schlüsselbein's Avatar
 
elite*gold: 0
Join Date: Feb 2013
Posts: 1,137
Received Thanks: 869
Darf ich fragen, warum du die Lösung aus den boost Bibliotheken unbequem findest?
Schlüsselbein is offline  
Old   #5
 
Master674b's Avatar
 
elite*gold: 0
Join Date: Dec 2012
Posts: 255
Received Thanks: 110
Quote:
Originally Posted by Schlüsselbein View Post
Darf ich fragen, warum du die Lösung aus den boost Bibliotheken unbequem findest?
Ich vermisse Lambda Support und rv-comparer beim Aufruf.
Außerdem wollte ich einfach mal was mit variadischen Templates und SFINAE gemacht haben.

boost::signal war früher außerdem nicht Thread sicher. Keine Ahnung ob das mittlerweile anders ist,
außerdem ist es non copyable.

Edit: Oh da fällt mir ein, das letzte mal als ich boost::signals verwendet hatte gab es dauernd einen Crash. Eben nochmal getestet:

Code:
boost::signal<void (uint32, uint32)> someSignal;
someSignal(1, 2);
Keine Ahnung was da los ist, müsste ich mal Debuggen aber interessiert mich eigentlich auch gar nicht.
Master674b is offline  
Reply


Similar Threads Similar Threads
Volkswechsel alte Klasse(Classic)->neue Klasse(Cata)
01/30/2011 - World of Warcraft - 13 Replies
Hi, Ich würde meinen Untoten Magier gerne zu einem Goblin Magier verändern. Ich weis auch, dass Goblins Magier sein können aber ich finde keine 100% sicheren Infos ob man auch Untoter->Goblin changen kann! Kennt sich da einer aus? Außerdem wird ja der Ruf der alten Heimatstadt auf die neue gewechselt, also sollte in meinem Fall doch nur von Unterstadt->Goblinstadt geändert werden oder? Was ist das langsame Goblinreittier(60%) und was das Schnelle(100%) zu dem meine Skelettpferde...
Gridlock Event <-- Klasse
08/22/2010 - WarRock - 10 Replies
Endlich war das Event mit 6 Stunden verspätung.. Egal hat sich gelohnt, naja zum Teil Gewinnerteam 25.000 Dinar Verliererteam 15.000 Dinar. Ratet mal wo ich war? Na klar im Verliererteam -.-
Kein Signal am Monitor / No signal on screen
09/23/2009 - Technical Support - 2 Replies
Also mein Problem ist das wenn ich den Pc hochfahre keinen Signal an meinem TFT Monitor bekomme. Ich habe erst ein DVI Kabel verwendet, und dachte es würde vl. daran liegen und daher meinen alten Monitor per VGA angeschlossen mit dem gleichen Ergebnis. Mein PC ist einige Monate gestanden, davor hat es eigentlich funktioniert. Was ich schon probiert habe: -1 Ram Riegel in anderen Slot gesteckt und hochgefahren -On Board Graka versucht zu verwenden -Die eingebaute Graka versucht zu...



All times are GMT +1. The time now is 10:44.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.