Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 26.11.2017, 17:14
ZergMaster вне форума Посмотреть профиль Отправить личное сообщение для ZergMaster Найти все сообщения от ZergMaster
  № 1  
Ответить с цитированием
ZergMaster
 
Аватар для ZergMaster

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
По умолчанию Синглтон в AS3

у меня для этой задачи служит такой классик:

Код AS3:
package src.utils 
{
	import com.greensock.TweenLite;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
 
	public class BubbleText
	{
		private static const BUBBLE_COLOR:uint = 0xffffcc;
		private static const TIMER_TIME:uint = 700;
 
		private var _bubbleTimeout:uint;
 
		private static var _instance:BubbleText;
		private static var _stage:DisplayObjectContainer;
 
		private var _bubbleObjects:Dictionary = new Dictionary();
 
		private var _textDescription:TextField = new TextField();;
		private var _textSprite:Sprite = new Sprite();
 
		public function BubbleText(itIsSingleton:PrivateSingleton) 
		{
			_textSprite.addChild(_textDescription);
		}
 
		public static function gi():BubbleText 
		{
			if (!_instance)
				_instance = new BubbleText(new PrivateSingleton());
 
			return _instance;
		}
 
		public static function init(s:DisplayObjectContainer):void 
		{
			_stage = s;
		}
 
		public function registerObject(object:Sprite, description:String):void 
		{
			_bubbleObjects[object] = {target:object, description:description};
 
			if (!_stage.hasEventListener(MouseEvent.MOUSE_OVER)) 
			{
				_stage.addEventListener(MouseEvent.MOUSE_OVER, mouseOverOutHandler, true);
				_stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOverOutHandler, true);
			}
		}
 
		private function mouseOverOutHandler(event:MouseEvent):void 
		{
			var target:Sprite;
 
			var check_mc:InteractiveObject = event.target as InteractiveObject;
			while (check_mc != event.currentTarget as InteractiveObject) 
			{
				var bubbleObject:Object = _bubbleObjects[check_mc as Sprite];
				if (bubbleObject) 
				{
					target = bubbleObject.target;
					break;
				}
 
				check_mc = check_mc.parent;
			}
 
			if (!target) return;
 
			switch(event.type) 
			{
				case MouseEvent.MOUSE_OVER:
					target.addEventListener(MouseEvent.MOUSE_MOVE, mouseOverOutHandler);
					_bubbleTimeout = setTimeout(displayBubble, TIMER_TIME, target);
					break;
 
				case MouseEvent.MOUSE_MOVE:
					removeBubble();
					_bubbleTimeout = setTimeout(displayBubble, TIMER_TIME, target);
					break;
 
				case MouseEvent.MOUSE_OUT:
					removeBubble();
					target.removeEventListener(MouseEvent.MOUSE_MOVE, mouseOverOutHandler);
					break;
			}
		}
 
		private function removeBubble():void 
		{
			clearTimeout(_bubbleTimeout);
 
			_textSprite.graphics.clear();
			_textDescription.text = '';
 
			if(_stage.getChildByName(_textSprite.name))
				_stage.removeChild(_textSprite);
		}
 
 
		private function displayBubble():void 
		{	
			var target:Sprite = arguments[0];
 
			_textDescription.defaultTextFormat = new TextFormat('Verdana');
			_textDescription.autoSize = TextFieldAutoSize.CENTER;
			_textDescription.text = _bubbleObjects[target].description;
			_textDescription.x = 0;
			_textDescription.y = 0;
 
			var gap:uint = 10;
			_textSprite.graphics.lineStyle(0, 0, 1, true);
			_textSprite.graphics.beginFill(BUBBLE_COLOR);
			_textSprite.graphics.drawRoundRect(_textDescription.x-gap, _textDescription.y-gap, _textDescription.width+gap*2, _textDescription.height+gap*2, 10);
 
			_textSprite.x = _stage.mouseX;
			_textSprite.y = _stage.mouseY + 40;
 
			if ((_textSprite.x + _textSprite.width) > _stage.stage.stageWidth)
			   _textSprite.x = _stage.mouseX - _textSprite.width + 30
 
			if ((_textSprite.y + _textSprite.height) > _stage.stage.stageHeight)
			   _textSprite.y = _stage.mouseY - _textSprite.height// + 30
 
			_stage.addChild(_textSprite);
			_textSprite.alpha = 0;
 
			TweenLite.to(_textSprite, 0.5, {alpha:1});
		}
	}
}
 
class PrivateSingleton
{
	public function PrivateSingleton() {}
}
класс, как можно увидеть, Singleton. Используется просто - сначала мы его инициализируем, передавая displayObjectContainer, в который будет добавлять всплывающее окошко. Это может быть stage, хотя я предпочитаю создавать отдельный слой в главной вьюхе. Второй шаг - это регистрация бабла на объекте, в которую передаем объект, над которым должен возникнуть бабл и текст, который будет отображаться. Вот собственно и все.
__________________
while(live()) { hope(); }

Старый 27.11.2017, 15:58
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 2  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
ну, получается. что данная конструкция, которую ты предлагаешь, не защищает от создания конструктора из вне класса. Смысл то в этом.
Позволяет, но в любом случае экземпляр будет только один, что через instance, что просто вызовом конструктора в первый раз. Как раз в этом и есть главный смысл синглтона
Цитата:
вот в java возможно создать приватный конструктор и поэтому там таких извращений не требуется...
Джава сама - одно сплошное извращение)
__________________
Ко мне можно и нужно обращаться на ты)

Старый 27.11.2017, 16:39
ZergMaster вне форума Посмотреть профиль Отправить личное сообщение для ZergMaster Найти все сообщения от ZergMaster
  № 3  
Ответить с цитированием
ZergMaster
 
Аватар для ZergMaster

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Цитата:
Сообщение от caseyryan Посмотреть сообщение
в любом случае экземпляр будет только один, что через instance, что просто вызовом конструктора в первый раз
это да. Не нравится мне так, непорядок. Я не гонюсь за коротким кодом с некоторых пор... ) А вот аккуратненько все должно быть и по полочкам - это желательно по возможности.
Если уж на то пошло, тогда мне больше нравится такой вариант:

Код AS3:
package {
 
	public class MySingleton {
 
		private static var _instance:MySingleton;
                //Переменная доступа
		private static var _isConstructing:Boolean;
 
		public function MySingleton() {
			if (!_isConstructing) throw new Error("Singleton, use MySingleton.instance");
		}
 
		public static function get instance():MySingleton {
			if (_instance == null)  {
				_isConstructing = true;
				_instance = new MySingleton();
				_isConstructing = false;
			}
			return _instance;
		}
	}
}
Хоть, как завещал дедушка Мартин, это и не тру, конечно, пользоваться флагами, но зато тут не создать, опять же, экземпляр из вне.

Цитата:
Сообщение от caseyryan Посмотреть сообщение
Джава сама - одно сплошное извращение)
А что такое? Детская травма?)
__________________
while(live()) { hope(); }

Старый 27.11.2017, 16:56
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 4  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 483
Цитата:
Сообщение от ZergMaster Посмотреть сообщение
Хоть, как завещал дедушка Мартин, это и не тру, конечно, пользоваться флагами, но зато тут не создать, опять же, экземпляр из вне.
Поясните для чайника, плиз, что это за ситуация создания экземпляра извне? Мне представлялось, что откуда бы не создавался экземпляр, нельзя не запустить его конструктор. Или я ошибаюсь?

И ещё вопрос по теме для всех. Какой кайф создавать синглтоны и инстансы, когда можно обращаться непосредственно к паблик методам статического класса из любого места программы? Что мешает написать 'Имя класса'.'имя публичного статического метода'() и получить всё, что нужно?

Старый 27.11.2017, 17:15
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 5  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Сообщение от ZergMaster Посмотреть сообщение
это да. Не нравится мне так, непорядок. Я не гонюсь за коротким кодом с некоторых пор... ) А вот аккуратненько все должно быть и по полочкам - это желательно по возможности.
Если уж на то пошло, тогда мне больше нравится такой вариант:

Код AS3:
package {
 
	public class MySingleton {
 
		private static var _instance:MySingleton;
                //Переменная доступа
		private static var _isConstructing:Boolean;
 
		public function MySingleton() {
			if (!_isConstructing) throw new Error("Singleton, use MySingleton.instance");
		}
 
		public static function get instance():MySingleton {
			if (_instance == null)  {
				_isConstructing = true;
				_instance = new MySingleton();
				_isConstructing = false;
			}
			return _instance;
		}
	}
}
Хоть, как завещал дедушка Мартин, это и не тру, конечно, пользоваться флагами, но зато тут не создать, опять же, экземпляр из вне.


А что такое? Детская травма?)
Ну тогда этот вариант тоже надо доделать. Потому что сейчас он позволяет сделать так:
Код AS3:
MySingleton.instance;
new MySingleton();
new MySingleton();
new MySingleton();
Если дополнить конструктор вот так:
Код AS3:
public function MySingleton() {
	if (!_isConstructing || _instance) throw new Error("Singleton, use MySingleton.instance");
	_instance = this;
}
То будет уже лучше
__________________
Ко мне можно и нужно обращаться на ты)

Старый 27.11.2017, 16:53
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 6  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,283
Код AS3:
_isConstructing = true;
_instance = new MySingleton();
_isConstructing = false;
Это что защита для многопоточности?

Старый 27.11.2017, 17:19
ZergMaster вне форума Посмотреть профиль Отправить личное сообщение для ZergMaster Найти все сообщения от ZergMaster
  № 7  
Ответить с цитированием
ZergMaster
 
Аватар для ZergMaster

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Цитата:
Сообщение от undefined Посмотреть сообщение
Это что защита для многопоточности?
Это как раз приватизация конструктора так сказать)

Цитата:
Сообщение от Appleman Посмотреть сообщение
Какой кайф создавать синглтоны
кайф, чтобы у тебя был объектик.=) Так и на сердце спокойней, и диспатчить можно из него, и интерфейсы применять к нему, и удалять. И в целом приятнее.

Добавлено через 2 минуты
caseyryan
пожалуй! Хотя кем жеж это надо быть, чтобы изнутри этого класса пытаться создавать множество инстансов)) Эдак себя бить себя по рукам постоянно надо. )
А извне то все равно больше одного не создашь.
__________________
while(live()) { hope(); }

Старый 27.11.2017, 20:26
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 8  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Сообщение от ZergMaster Посмотреть сообщение
пожалуй! Хотя кем жеж это надо быть, чтобы изнутри этого класса пытаться создавать множество инстансов)) Эдак себя бить себя по рукам постоянно надо. )
А извне то все равно больше одного не создашь.
Да почему изнутри то? Я же написал как можно создать сколько угодно таких экземлпяров. И сделал это извне. Сначала вызывается MySinglton.instance; Этот вызов ставит флаг isConstructring в true, а дальше создавай как обычные экземпляры его сколько угодно, он уже не синглтон
Туплю. Я не обратил внимание, что там флаг снова ставится в false сразу же после создания.
Да, способ хороший.
п.с. Малость офтоп, но мне нравится реализация синглтона в C# в Unity
Код AS3:
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
	private static T _instance;
 
	private static object _lockObject = new object();
 
	public static T Instance {
		get {
			if (applicationIsQuitting) {
				return null;
			}
 
			lock(_lockObject)
			{
				if (_instance == null) {
					_instance = (T) FindObjectOfType(typeof(T));
 
					if ( FindObjectsOfType(typeof(T)).Length > 1 ) {
						return _instance;
					}
 
					if (_instance == null) {
						GameObject singleton = new GameObject();
						_instance = singleton.AddComponent<T>();
						singleton.name = "(singleton) "+ typeof(T).ToString();
						DontDestroyOnLoad(singleton);
					} 
				}
 
				return _instance;
			}
		}
	}
 
	private static bool applicationIsQuitting = false;
 
	public void OnDestroy () {
		applicationIsQuitting = true;
	}
}
А дальше по этому шаблону создаем сколько угодно разных синглтонов всего лишь создав такой класс
Код AS3:
using UnityEngine;
 
public class SomeSinglton: Singleton<SoundManager> {
 
}
И можно уже обращаться к нему
Код AS3:
SomeSinglton.Instance;
Очень удобная штука, и мне ее катастрофически нехватает в as3 теперь)
__________________
Ко мне можно и нужно обращаться на ты)

Старый 27.11.2017, 17:02
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 9  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,283
статичный класс будет жить все время, пока работает приложение, а синглтоны можно создавать и удалять когда угодно.
Цитата:
Поясните для чайника, плиз, что это за ситуация создания экземпляра извне? Мне представлялось, что откуда бы не создавался экземпляр, нельзя не запустить его конструктор. Или я ошибаюсь?
Имеется в виду извне класса синглтона.Каноническая реализация сама создает экземпляр себя и предоставляет его всем желающим.Повторное создание со стороны блокируется модификатором private у конструктора синглтона.

Старый 27.11.2017, 17:08
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 10  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Класс не может диспатчить события.
__________________
Reality.getBounds(this);

Создать новую тему Ответ Часовой пояс GMT +4, время: 16:57.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 16:57.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.