1/*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: ut_Signal.ih 4 5 Copyright (C)2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 - Auto generated code - 14 *---------------------------------------------------------------------------*/ 15 16//--------------------------------------------------------------------------- 17//! @brief シグナルを受け取るためのインターフェースです。(引数は 0 個です) 18//! 19//! @tparam TResult 返り値の型です。 20//! @tparam TAllocator アロケータの型です。 21//--------------------------------------------------------------------------- 22template< 23 typename TResult, 24 typename TAllocator = os::IAllocator 25> 26class Slot0 27{ 28public: 29 typedef TResult ResultType; 30 typedef TAllocator AllocatorType; 31 32 //! @brief コンストラクタです。 33 explicit Slot0(AllocatorType* allocator) : m_Allocator(allocator) {} 34 35 //! @brief 自らを破棄します。 36 void Destroy() 37 { 38 AllocatorType* allocator = this->GetAllocator(); 39 if (allocator) 40 { 41 this->~Slot0(); 42 allocator->Free(this); 43 } 44 } 45 46 //! @brief 自らを破棄します。 47 void Destroy(AllocatorType* allocator) 48 { 49 NW_NULL_ASSERT(allocator); 50 this->~Slot0(); 51 allocator->Free(this); 52 } 53 54 //! @brief スロットにシグナルを送信します。 55 virtual ResultType Invoke() = 0; 56 57 AllocatorType* GetAllocator() { return m_Allocator; } 58 59protected: 60 //! デストラクタです。 61 virtual ~Slot0() {} 62 63private: 64 AllocatorType* m_Allocator; 65}; 66 67//--------------------------------------------------------------------------- 68//! @brief シグナルを受け取るためのクラスです。(引数は 0 個です) 69//! 70//! @tparam TResult 返り値の型です。 71//! @tparam TFunction 関数か関数オブジェクトの型です。 72//! @tparam TAllocator アロケータの型です。 73//--------------------------------------------------------------------------- 74template< 75 typename TResult, 76 typename TFunction, 77 typename TAllocator = os::IAllocator 78> 79class FunctionSlot0 : public Slot0<TResult, TAllocator> 80{ 81public: 82 typedef TResult ResultType; 83 typedef TFunction FunctionType; 84 typedef TAllocator AllocatorType; 85 86 //! コンストラクタです。 87 FunctionSlot0(AllocatorType* allocator, FunctionType function) 88 : Slot0<TResult, TAllocator>(allocator), m_Function(function) {} 89 90 //! @brief スロットにシグナルを送信します。 91 virtual ResultType Invoke() 92 { 93 return m_Function(); 94 } 95 96private: 97 TFunction m_Function; 98}; 99 100//--------------------------------------------------------------------------- 101//! @brief スロットに合図を送るためのクラスです。(引数は 0 個です) 102//! 103//! @tparam TResult 返り値の型です。 104//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 105//! @tparam TAllocator アロケータの型です。 106//! @tparam TSlot スロットの型です。 107//--------------------------------------------------------------------------- 108template< 109 typename TResult, 110 typename TResultCombiner = LastValueResult<TResult>, 111 typename TAllocator = os::IAllocator, 112 typename TSlot = Slot0<TResult, TAllocator> 113> 114class Signal0 115{ 116 NW_DISALLOW_COPY_AND_ASSIGN(Signal0); 117 118public: 119 typedef Signal0<TResult, TResultCombiner, TAllocator, TSlot> SelfType; 120 typedef TSlot SlotType; 121 typedef TResult ResultType; 122 typedef ut::MoveArray<SlotType*> SlotList; 123 typedef TResultCombiner ResultCombinerType; 124 typedef TAllocator AllocatorType; 125 126#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 127 //! @brief スロット実行用関数オブジェクトです。 128 struct Invoker 129 { 130 Invoker() {} 131 ResultType operator()(SlotType* slot) const 132 { 133 return slot->Invoke(); 134 } 135 ; 136 }; 137#endif 138 139 //---------------------------------------- 140 //! @name 作成/破棄 141 //@{ 142 143 //! @brief 無効なシグナルを生成します。 144 //! 145 //! @param[in] allocator アロケータです。 146 //! 147 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 148 { 149 void* memory = allocator->Alloc(sizeof(SelfType)); 150 if (memory) 151 { 152#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 153 return new(memory) SelfType(NULL, 0, allocator); 154#else 155 return new(memory) SelfType(allocator); 156#endif 157 } 158 else 159 { 160 return NULL; 161 } 162 } 163 164 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 165 //! 166 //! @param[in] maxSlots スロットを追加できる最大数です。 167 //! @param[in] allocator アロケータです。 168 //! 169 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 170 { 171 void* memory = allocator->Alloc(sizeof(SelfType)); 172 if (memory) 173 { 174#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 175 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 176 if (elements != NULL) 177 { 178 return new(memory) SelfType(elements, maxSlots, allocator); 179 } 180 else 181 { 182 allocator->Free(memory); 183 return NULL; 184 } 185#else 186 NW_UNUSED_VARIABLE(maxSlots); 187 return new(memory) SelfType(allocator); 188#endif 189 } 190 else 191 { 192 return NULL; 193 } 194 } 195 196 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 197 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 198 { 199 void* memory = allocator->Alloc(sizeof(SelfType)); 200 if (memory) 201 { 202 return new(memory) SelfType(allocator); 203 } 204 else 205 { 206 return NULL; 207 } 208 } 209 210 //! オブジェクトを破棄します。 211 void Destroy() { this->~Signal0(); this->m_Allocator->Free(this); } 212 213 //@} 214 215 //---------------------------------------- 216 //! @name スロット 217 //@{ 218 219 //! @brief スロットと接続し、シグナルが送られるようにする。 220 //! 221 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 222 //! シグナルに接続できるスロット数は1つになります。 223 //! 224 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 225 //! Connect する前に必ず Disconnect するようにしてください。 226 //! Disconnect していない場合は、アサートで停止します。 227 //! 228 //! @param[in] slot スロットです。 229 //! 230 void Connect(SlotType* slot) 231 { 232#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 233 bool pushed = this->m_Slots.push_back(slot); 234 NW_ASSERT(pushed); 235#else 236 NW_ASSERT(this->m_Slot == NULL); 237 this->m_Slot = slot; 238#endif 239 } 240 241 //! @brief スロットを作成し、接続します。 242 //! 243 //! 内部でメモリを確保します。 244 //! 245 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 246 //! シグナルに接続できるスロット数は1つになります。 247 //! 248 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 249 //! Connect する前に必ず Disconnect するようにしてください。 250 //! Disconnect していない場合は、アサートで停止します。 251 //! 252 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 253 //! 254 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 255 //! @param[in] allocator アロケータです。 256 //! 257 //! @return 生成されたスロットです。 258 //! 259 template<typename TFunction> 260 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 261 { 262 typedef FunctionSlot0<ResultType, TFunction, AllocatorType> FunctionSlotType; 263 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 264 265 this->Connect(slot); 266 return slot; 267 } 268 269 //! @brief スロットを作成し、接続します。 270 //! 271 //! 内部でメモリを確保します。 272 //! 273 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 274 //! シグナルに接続できるスロット数は1つになります。 275 //! 276 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 277 //! Connect する前に必ず Disconnect するようにしてください。 278 //! Disconnect していない場合は、アサートで停止します。 279 //! 280 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 281 //! 282 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 283 //! 284 //! @return 生成されたスロットです。 285 //! 286 template<typename TFunction> 287 SlotType* CreateAndConnect(TFunction function) 288 { 289 return CreateAndConnect(function, this->m_Allocator); 290 } 291 292 //! @brief スロットを切断します。 293 //! 294 //! @param[in] slot 切断するスロットです。 295 //! 296 void Disconnect(SlotType* slot) 297 { 298#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 299 this->m_Slots.erase_find(slot); 300#else 301 if (this->m_Slot == slot) 302 { 303 this->m_Slot = NULL; 304 } 305#endif 306 } 307 308 //! @brief スロットを切断して、破棄します。 309 //! 310 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 311 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 312 //! 313 //! @param[in] slot 切断するスロットです。 314 //! 315 void DisconnectAndDestroy(SlotType* slot) 316 { 317#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 318 this->m_Slots.erase_find(slot); 319 slot->Destroy(); 320#else 321 if (this->m_Slot == slot) 322 { 323 this->m_Slot = NULL; 324 } 325 if (slot) 326 { 327 slot->Destroy(); 328 } 329#endif 330 } 331 //@} 332 333 //! @brief シグナルを送信します。 334 ResultType operator()() 335 { 336#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 337 ResultCombinerType combiner; 338 return combiner(m_Slots.begin(), m_Slots.end(), Invoker()); 339#else 340 if (this->m_Slot) 341 { 342 return this->m_Slot->Invoke(); 343 } 344 else 345 { 346 return ResultType(); 347 } 348#endif 349 } 350 351 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 352 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 353 { 354 os::MemorySizeCalculator size(alignment); 355 356 GetMemorySizeForInvalidateSignalInternal(&size); 357 358 return size.GetSizeWithPadding(alignment); 359 } 360 361 //! @details :private 362 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 363 { 364 os::MemorySizeCalculator& size = *pSize; 365 366 size += sizeof(SelfType); 367 } 368 369 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 370 //! 371 //! @param[in] maxSlots スロットを追加できる最大数です。 372 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 373 { 374 os::MemorySizeCalculator size(alignment); 375 376 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 377 378 return size.GetSizeWithPadding(alignment); 379 } 380 381 //! @details :private 382 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 383 { 384 os::MemorySizeCalculator& size = *pSize; 385 386 size += sizeof(SelfType); 387 388#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 389 size += sizeof(SlotType*) * maxSlots; 390#else 391 NW_UNUSED_VARIABLE(maxSlots); 392#endif 393 } 394 395private: 396#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 397 //! @brief コンストラクタです。 398 Signal0(void* elements, size_t maxSlots, AllocatorType* allocator) 399 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 400 //! @brief コンストラクタです。 401 explicit Signal0(AllocatorType* allocator) 402 : m_Allocator(allocator), m_Slots(allocator) {} 403 //! @brief デストラクタです。 404 ~Signal0() { DestroyAllSlots(m_Slots); } 405#else 406 //! @brief コンストラクタです。 407 explicit Signal0(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 408 //! @brief デストラクタです。 409 ~Signal0() { SafeDestroy(this->m_Slot); } 410#endif 411 412 AllocatorType* m_Allocator; 413 414#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 415 SlotList m_Slots; 416#else 417 SlotType* m_Slot; 418#endif 419}; 420 421//--------------------------------------------------------------------------- 422//! @brief シグナルを受け取るためのインターフェースです。(引数は 1 個です) 423//! 424//! @tparam TResult 返り値の型です。 425//! @tparam TAllocator アロケータの型です。 426//--------------------------------------------------------------------------- 427template< 428 typename TResult, 429 typename TArg0, 430 typename TAllocator = os::IAllocator 431> 432class Slot1 433{ 434public: 435 typedef TResult ResultType; 436 typedef TAllocator AllocatorType; 437 438 //! @brief コンストラクタです。 439 explicit Slot1(AllocatorType* allocator) : m_Allocator(allocator) {} 440 441 //! @brief 自らを破棄します。 442 void Destroy() 443 { 444 AllocatorType* allocator = this->GetAllocator(); 445 if (allocator) 446 { 447 this->~Slot1(); 448 allocator->Free(this); 449 } 450 } 451 452 //! @brief 自らを破棄します。 453 void Destroy(AllocatorType* allocator) 454 { 455 NW_NULL_ASSERT(allocator); 456 this->~Slot1(); 457 allocator->Free(this); 458 } 459 460 //! @brief スロットにシグナルを送信します。 461 virtual ResultType Invoke(TArg0 arg0) = 0; 462 463 AllocatorType* GetAllocator() { return m_Allocator; } 464 465protected: 466 //! デストラクタです。 467 virtual ~Slot1() {} 468 469private: 470 AllocatorType* m_Allocator; 471}; 472 473//--------------------------------------------------------------------------- 474//! @brief シグナルを受け取るためのクラスです。(引数は 1 個です) 475//! 476//! @tparam TResult 返り値の型です。 477//! @tparam TFunction 関数か関数オブジェクトの型です。 478//! @tparam TAllocator アロケータの型です。 479//--------------------------------------------------------------------------- 480template< 481 typename TResult, 482 typename TArg0, 483 typename TFunction, 484 typename TAllocator = os::IAllocator 485> 486class FunctionSlot1 : public Slot1<TResult, TArg0, TAllocator> 487{ 488public: 489 typedef TResult ResultType; 490 typedef TFunction FunctionType; 491 typedef TAllocator AllocatorType; 492 493 //! コンストラクタです。 494 FunctionSlot1(AllocatorType* allocator, FunctionType function) 495 : Slot1<TResult, TArg0, TAllocator>(allocator), m_Function(function) {} 496 497 //! @brief スロットにシグナルを送信します。 498 virtual ResultType Invoke(TArg0 arg0) 499 { 500 return m_Function(arg0); 501 } 502 503private: 504 TFunction m_Function; 505}; 506 507//--------------------------------------------------------------------------- 508//! @brief スロットに合図を送るためのクラスです。(引数は 1 個です) 509//! 510//! @tparam TResult 返り値の型です。 511//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 512//! @tparam TAllocator アロケータの型です。 513//! @tparam TSlot スロットの型です。 514//--------------------------------------------------------------------------- 515template< 516 typename TResult, 517 typename TArg0, 518 typename TResultCombiner = LastValueResult<TResult>, 519 typename TAllocator = os::IAllocator, 520 typename TSlot = Slot1<TResult, TArg0, TAllocator> 521> 522class Signal1 523{ 524 NW_DISALLOW_COPY_AND_ASSIGN(Signal1); 525 526public: 527 typedef Signal1<TResult, TArg0, TResultCombiner, TAllocator, TSlot> SelfType; 528 typedef TSlot SlotType; 529 typedef TResult ResultType; 530 typedef ut::MoveArray<SlotType*> SlotList; 531 typedef TResultCombiner ResultCombinerType; 532 typedef TAllocator AllocatorType; 533 534#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 535 //! @brief スロット実行用関数オブジェクトです。 536 struct Invoker 537 { 538 Invoker(TArg0 arg0) : m_arg0(arg0) {} 539 ResultType operator()(SlotType* slot) const 540 { 541 return slot->Invoke(m_arg0); 542 } 543 TArg0 m_arg0; 544 }; 545#endif 546 547 //---------------------------------------- 548 //! @name 作成/破棄 549 //@{ 550 551 //! @brief 無効なシグナルを生成します。 552 //! 553 //! @param[in] allocator アロケータです。 554 //! 555 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 556 { 557 void* memory = allocator->Alloc(sizeof(SelfType)); 558 if (memory) 559 { 560#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 561 return new(memory) SelfType(NULL, 0, allocator); 562#else 563 return new(memory) SelfType(allocator); 564#endif 565 } 566 else 567 { 568 return NULL; 569 } 570 } 571 572 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 573 //! 574 //! @param[in] maxSlots スロットを追加できる最大数です。 575 //! @param[in] allocator アロケータです。 576 //! 577 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 578 { 579 void* memory = allocator->Alloc(sizeof(SelfType)); 580 if (memory) 581 { 582#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 583 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 584 if (elements != NULL) 585 { 586 return new(memory) SelfType(elements, maxSlots, allocator); 587 } 588 else 589 { 590 allocator->Free(memory); 591 return NULL; 592 } 593#else 594 NW_UNUSED_VARIABLE(maxSlots); 595 return new(memory) SelfType(allocator); 596#endif 597 } 598 else 599 { 600 return NULL; 601 } 602 } 603 604 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 605 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 606 { 607 void* memory = allocator->Alloc(sizeof(SelfType)); 608 if (memory) 609 { 610 return new(memory) SelfType(allocator); 611 } 612 else 613 { 614 return NULL; 615 } 616 } 617 618 //! オブジェクトを破棄します。 619 void Destroy() { this->~Signal1(); this->m_Allocator->Free(this); } 620 621 //@} 622 623 //---------------------------------------- 624 //! @name スロット 625 //@{ 626 627 //! @brief スロットと接続し、シグナルが送られるようにする。 628 //! 629 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 630 //! シグナルに接続できるスロット数は1つになります。 631 //! 632 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 633 //! Connect する前に必ず Disconnect するようにしてください。 634 //! Disconnect していない場合は、アサートで停止します。 635 //! 636 //! @param[in] slot スロットです。 637 //! 638 void Connect(SlotType* slot) 639 { 640#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 641 bool pushed = this->m_Slots.push_back(slot); 642 NW_ASSERT(pushed); 643#else 644 NW_ASSERT(this->m_Slot == NULL); 645 this->m_Slot = slot; 646#endif 647 } 648 649 //! @brief スロットを作成し、接続します。 650 //! 651 //! 内部でメモリを確保します。 652 //! 653 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 654 //! シグナルに接続できるスロット数は1つになります。 655 //! 656 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 657 //! Connect する前に必ず Disconnect するようにしてください。 658 //! Disconnect していない場合は、アサートで停止します。 659 //! 660 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 661 //! 662 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 663 //! @param[in] allocator アロケータです。 664 //! 665 //! @return 生成されたスロットです。 666 //! 667 template<typename TFunction> 668 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 669 { 670 typedef FunctionSlot1<ResultType, TArg0, TFunction, AllocatorType> FunctionSlotType; 671 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 672 673 this->Connect(slot); 674 return slot; 675 } 676 677 //! @brief スロットを作成し、接続します。 678 //! 679 //! 内部でメモリを確保します。 680 //! 681 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 682 //! シグナルに接続できるスロット数は1つになります。 683 //! 684 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 685 //! Connect する前に必ず Disconnect するようにしてください。 686 //! Disconnect していない場合は、アサートで停止します。 687 //! 688 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 689 //! 690 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 691 //! 692 //! @return 生成されたスロットです。 693 //! 694 template<typename TFunction> 695 SlotType* CreateAndConnect(TFunction function) 696 { 697 return CreateAndConnect(function, this->m_Allocator); 698 } 699 700 //! @brief スロットを切断します。 701 //! 702 //! @param[in] slot 切断するスロットです。 703 //! 704 void Disconnect(SlotType* slot) 705 { 706#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 707 this->m_Slots.erase_find(slot); 708#else 709 if (this->m_Slot == slot) 710 { 711 this->m_Slot = NULL; 712 } 713#endif 714 } 715 716 //! @brief スロットを切断して、破棄します。 717 //! 718 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 719 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 720 //! 721 //! @param[in] slot 切断するスロットです。 722 //! 723 void DisconnectAndDestroy(SlotType* slot) 724 { 725#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 726 this->m_Slots.erase_find(slot); 727 slot->Destroy(); 728#else 729 if (this->m_Slot == slot) 730 { 731 this->m_Slot = NULL; 732 } 733 if (slot) 734 { 735 slot->Destroy(); 736 } 737#endif 738 } 739 //@} 740 741 //! @brief シグナルを送信します。 742 ResultType operator()(TArg0 arg0) 743 { 744#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 745 ResultCombinerType combiner; 746 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0)); 747#else 748 if (this->m_Slot) 749 { 750 return this->m_Slot->Invoke(arg0); 751 } 752 else 753 { 754 return ResultType(); 755 } 756#endif 757 } 758 759 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 760 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 761 { 762 os::MemorySizeCalculator size(alignment); 763 764 GetMemorySizeForInvalidateSignalInternal(&size); 765 766 return size.GetSizeWithPadding(alignment); 767 } 768 769 //! @details :private 770 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 771 { 772 os::MemorySizeCalculator& size = *pSize; 773 774 size += sizeof(SelfType); 775 } 776 777 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 778 //! 779 //! @param[in] maxSlots スロットを追加できる最大数です。 780 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 781 { 782 os::MemorySizeCalculator size(alignment); 783 784 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 785 786 return size.GetSizeWithPadding(alignment); 787 } 788 789 //! @details :private 790 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 791 { 792 os::MemorySizeCalculator& size = *pSize; 793 794 size += sizeof(SelfType); 795 796#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 797 size += sizeof(SlotType*) * maxSlots; 798#else 799 NW_UNUSED_VARIABLE(maxSlots); 800#endif 801 } 802 803private: 804#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 805 //! @brief コンストラクタです。 806 Signal1(void* elements, size_t maxSlots, AllocatorType* allocator) 807 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 808 //! @brief コンストラクタです。 809 explicit Signal1(AllocatorType* allocator) 810 : m_Allocator(allocator), m_Slots(allocator) {} 811 //! @brief デストラクタです。 812 ~Signal1() { DestroyAllSlots(m_Slots); } 813#else 814 //! @brief コンストラクタです。 815 explicit Signal1(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 816 //! @brief デストラクタです。 817 ~Signal1() { SafeDestroy(this->m_Slot); } 818#endif 819 820 AllocatorType* m_Allocator; 821 822#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 823 SlotList m_Slots; 824#else 825 SlotType* m_Slot; 826#endif 827}; 828 829//--------------------------------------------------------------------------- 830//! @brief シグナルを受け取るためのインターフェースです。(引数は 2 個です) 831//! 832//! @tparam TResult 返り値の型です。 833//! @tparam TAllocator アロケータの型です。 834//--------------------------------------------------------------------------- 835template< 836 typename TResult, 837 typename TArg0, typename TArg1, 838 typename TAllocator = os::IAllocator 839> 840class Slot2 841{ 842public: 843 typedef TResult ResultType; 844 typedef TAllocator AllocatorType; 845 846 //! @brief コンストラクタです。 847 explicit Slot2(AllocatorType* allocator) : m_Allocator(allocator) {} 848 849 //! @brief 自らを破棄します。 850 void Destroy() 851 { 852 AllocatorType* allocator = this->GetAllocator(); 853 if (allocator) 854 { 855 this->~Slot2(); 856 allocator->Free(this); 857 } 858 } 859 860 //! @brief 自らを破棄します。 861 void Destroy(AllocatorType* allocator) 862 { 863 NW_NULL_ASSERT(allocator); 864 this->~Slot2(); 865 allocator->Free(this); 866 } 867 868 //! @brief スロットにシグナルを送信します。 869 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1) = 0; 870 871 AllocatorType* GetAllocator() { return m_Allocator; } 872 873protected: 874 //! デストラクタです。 875 virtual ~Slot2() {} 876 877private: 878 AllocatorType* m_Allocator; 879}; 880 881//--------------------------------------------------------------------------- 882//! @brief シグナルを受け取るためのクラスです。(引数は 2 個です) 883//! 884//! @tparam TResult 返り値の型です。 885//! @tparam TFunction 関数か関数オブジェクトの型です。 886//! @tparam TAllocator アロケータの型です。 887//--------------------------------------------------------------------------- 888template< 889 typename TResult, 890 typename TArg0, typename TArg1, 891 typename TFunction, 892 typename TAllocator = os::IAllocator 893> 894class FunctionSlot2 : public Slot2<TResult, TArg0, TArg1, TAllocator> 895{ 896public: 897 typedef TResult ResultType; 898 typedef TFunction FunctionType; 899 typedef TAllocator AllocatorType; 900 901 //! コンストラクタです。 902 FunctionSlot2(AllocatorType* allocator, FunctionType function) 903 : Slot2<TResult, TArg0, TArg1, TAllocator>(allocator), m_Function(function) {} 904 905 //! @brief スロットにシグナルを送信します。 906 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1) 907 { 908 return m_Function(arg0, arg1); 909 } 910 911private: 912 TFunction m_Function; 913}; 914 915//--------------------------------------------------------------------------- 916//! @brief スロットに合図を送るためのクラスです。(引数は 2 個です) 917//! 918//! @tparam TResult 返り値の型です。 919//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 920//! @tparam TAllocator アロケータの型です。 921//! @tparam TSlot スロットの型です。 922//--------------------------------------------------------------------------- 923template< 924 typename TResult, 925 typename TArg0, typename TArg1, 926 typename TResultCombiner = LastValueResult<TResult>, 927 typename TAllocator = os::IAllocator, 928 typename TSlot = Slot2<TResult, TArg0, TArg1, TAllocator> 929> 930class Signal2 931{ 932 NW_DISALLOW_COPY_AND_ASSIGN(Signal2); 933 934public: 935 typedef Signal2<TResult, TArg0, TArg1, TResultCombiner, TAllocator, TSlot> SelfType; 936 typedef TSlot SlotType; 937 typedef TResult ResultType; 938 typedef ut::MoveArray<SlotType*> SlotList; 939 typedef TResultCombiner ResultCombinerType; 940 typedef TAllocator AllocatorType; 941 942#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 943 //! @brief スロット実行用関数オブジェクトです。 944 struct Invoker 945 { 946 Invoker(TArg0 arg0, TArg1 arg1) : m_arg0(arg0), m_arg1(arg1) {} 947 ResultType operator()(SlotType* slot) const 948 { 949 return slot->Invoke(m_arg0, m_arg1); 950 } 951 TArg0 m_arg0; 952 TArg1 m_arg1; 953 }; 954#endif 955 956 //---------------------------------------- 957 //! @name 作成/破棄 958 //@{ 959 960 //! @brief 無効なシグナルを生成します。 961 //! 962 //! @param[in] allocator アロケータです。 963 //! 964 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 965 { 966 void* memory = allocator->Alloc(sizeof(SelfType)); 967 if (memory) 968 { 969#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 970 return new(memory) SelfType(NULL, 0, allocator); 971#else 972 return new(memory) SelfType(allocator); 973#endif 974 } 975 else 976 { 977 return NULL; 978 } 979 } 980 981 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 982 //! 983 //! @param[in] maxSlots スロットを追加できる最大数です。 984 //! @param[in] allocator アロケータです。 985 //! 986 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 987 { 988 void* memory = allocator->Alloc(sizeof(SelfType)); 989 if (memory) 990 { 991#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 992 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 993 if (elements != NULL) 994 { 995 return new(memory) SelfType(elements, maxSlots, allocator); 996 } 997 else 998 { 999 allocator->Free(memory); 1000 return NULL; 1001 } 1002#else 1003 NW_UNUSED_VARIABLE(maxSlots); 1004 return new(memory) SelfType(allocator); 1005#endif 1006 } 1007 else 1008 { 1009 return NULL; 1010 } 1011 } 1012 1013 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 1014 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 1015 { 1016 void* memory = allocator->Alloc(sizeof(SelfType)); 1017 if (memory) 1018 { 1019 return new(memory) SelfType(allocator); 1020 } 1021 else 1022 { 1023 return NULL; 1024 } 1025 } 1026 1027 //! オブジェクトを破棄します。 1028 void Destroy() { this->~Signal2(); this->m_Allocator->Free(this); } 1029 1030 //@} 1031 1032 //---------------------------------------- 1033 //! @name スロット 1034 //@{ 1035 1036 //! @brief スロットと接続し、シグナルが送られるようにする。 1037 //! 1038 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1039 //! シグナルに接続できるスロット数は1つになります。 1040 //! 1041 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1042 //! Connect する前に必ず Disconnect するようにしてください。 1043 //! Disconnect していない場合は、アサートで停止します。 1044 //! 1045 //! @param[in] slot スロットです。 1046 //! 1047 void Connect(SlotType* slot) 1048 { 1049#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1050 bool pushed = this->m_Slots.push_back(slot); 1051 NW_ASSERT(pushed); 1052#else 1053 NW_ASSERT(this->m_Slot == NULL); 1054 this->m_Slot = slot; 1055#endif 1056 } 1057 1058 //! @brief スロットを作成し、接続します。 1059 //! 1060 //! 内部でメモリを確保します。 1061 //! 1062 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1063 //! シグナルに接続できるスロット数は1つになります。 1064 //! 1065 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1066 //! Connect する前に必ず Disconnect するようにしてください。 1067 //! Disconnect していない場合は、アサートで停止します。 1068 //! 1069 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1070 //! 1071 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1072 //! @param[in] allocator アロケータです。 1073 //! 1074 //! @return 生成されたスロットです。 1075 //! 1076 template<typename TFunction> 1077 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 1078 { 1079 typedef FunctionSlot2<ResultType, TArg0, TArg1, TFunction, AllocatorType> FunctionSlotType; 1080 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 1081 1082 this->Connect(slot); 1083 return slot; 1084 } 1085 1086 //! @brief スロットを作成し、接続します。 1087 //! 1088 //! 内部でメモリを確保します。 1089 //! 1090 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1091 //! シグナルに接続できるスロット数は1つになります。 1092 //! 1093 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1094 //! Connect する前に必ず Disconnect するようにしてください。 1095 //! Disconnect していない場合は、アサートで停止します。 1096 //! 1097 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1098 //! 1099 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1100 //! 1101 //! @return 生成されたスロットです。 1102 //! 1103 template<typename TFunction> 1104 SlotType* CreateAndConnect(TFunction function) 1105 { 1106 return CreateAndConnect(function, this->m_Allocator); 1107 } 1108 1109 //! @brief スロットを切断します。 1110 //! 1111 //! @param[in] slot 切断するスロットです。 1112 //! 1113 void Disconnect(SlotType* slot) 1114 { 1115#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1116 this->m_Slots.erase_find(slot); 1117#else 1118 if (this->m_Slot == slot) 1119 { 1120 this->m_Slot = NULL; 1121 } 1122#endif 1123 } 1124 1125 //! @brief スロットを切断して、破棄します。 1126 //! 1127 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 1128 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 1129 //! 1130 //! @param[in] slot 切断するスロットです。 1131 //! 1132 void DisconnectAndDestroy(SlotType* slot) 1133 { 1134#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1135 this->m_Slots.erase_find(slot); 1136 slot->Destroy(); 1137#else 1138 if (this->m_Slot == slot) 1139 { 1140 this->m_Slot = NULL; 1141 } 1142 if (slot) 1143 { 1144 slot->Destroy(); 1145 } 1146#endif 1147 } 1148 //@} 1149 1150 //! @brief シグナルを送信します。 1151 ResultType operator()(TArg0 arg0, TArg1 arg1) 1152 { 1153#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1154 ResultCombinerType combiner; 1155 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1)); 1156#else 1157 if (this->m_Slot) 1158 { 1159 return this->m_Slot->Invoke(arg0, arg1); 1160 } 1161 else 1162 { 1163 return ResultType(); 1164 } 1165#endif 1166 } 1167 1168 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 1169 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 1170 { 1171 os::MemorySizeCalculator size(alignment); 1172 1173 GetMemorySizeForInvalidateSignalInternal(&size); 1174 1175 return size.GetSizeWithPadding(alignment); 1176 } 1177 1178 //! @details :private 1179 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 1180 { 1181 os::MemorySizeCalculator& size = *pSize; 1182 1183 size += sizeof(SelfType); 1184 } 1185 1186 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 1187 //! 1188 //! @param[in] maxSlots スロットを追加できる最大数です。 1189 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 1190 { 1191 os::MemorySizeCalculator size(alignment); 1192 1193 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 1194 1195 return size.GetSizeWithPadding(alignment); 1196 } 1197 1198 //! @details :private 1199 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 1200 { 1201 os::MemorySizeCalculator& size = *pSize; 1202 1203 size += sizeof(SelfType); 1204 1205#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1206 size += sizeof(SlotType*) * maxSlots; 1207#else 1208 NW_UNUSED_VARIABLE(maxSlots); 1209#endif 1210 } 1211 1212private: 1213#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1214 //! @brief コンストラクタです。 1215 Signal2(void* elements, size_t maxSlots, AllocatorType* allocator) 1216 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 1217 //! @brief コンストラクタです。 1218 explicit Signal2(AllocatorType* allocator) 1219 : m_Allocator(allocator), m_Slots(allocator) {} 1220 //! @brief デストラクタです。 1221 ~Signal2() { DestroyAllSlots(m_Slots); } 1222#else 1223 //! @brief コンストラクタです。 1224 explicit Signal2(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 1225 //! @brief デストラクタです。 1226 ~Signal2() { SafeDestroy(this->m_Slot); } 1227#endif 1228 1229 AllocatorType* m_Allocator; 1230 1231#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1232 SlotList m_Slots; 1233#else 1234 SlotType* m_Slot; 1235#endif 1236}; 1237 1238//--------------------------------------------------------------------------- 1239//! @brief シグナルを受け取るためのインターフェースです。(引数は 3 個です) 1240//! 1241//! @tparam TResult 返り値の型です。 1242//! @tparam TAllocator アロケータの型です。 1243//--------------------------------------------------------------------------- 1244template< 1245 typename TResult, 1246 typename TArg0, typename TArg1, typename TArg2, 1247 typename TAllocator = os::IAllocator 1248> 1249class Slot3 1250{ 1251public: 1252 typedef TResult ResultType; 1253 typedef TAllocator AllocatorType; 1254 1255 //! @brief コンストラクタです。 1256 explicit Slot3(AllocatorType* allocator) : m_Allocator(allocator) {} 1257 1258 //! @brief 自らを破棄します。 1259 void Destroy() 1260 { 1261 AllocatorType* allocator = this->GetAllocator(); 1262 if (allocator) 1263 { 1264 this->~Slot3(); 1265 allocator->Free(this); 1266 } 1267 } 1268 1269 //! @brief 自らを破棄します。 1270 void Destroy(AllocatorType* allocator) 1271 { 1272 NW_NULL_ASSERT(allocator); 1273 this->~Slot3(); 1274 allocator->Free(this); 1275 } 1276 1277 //! @brief スロットにシグナルを送信します。 1278 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2) = 0; 1279 1280 AllocatorType* GetAllocator() { return m_Allocator; } 1281 1282protected: 1283 //! デストラクタです。 1284 virtual ~Slot3() {} 1285 1286private: 1287 AllocatorType* m_Allocator; 1288}; 1289 1290//--------------------------------------------------------------------------- 1291//! @brief シグナルを受け取るためのクラスです。(引数は 3 個です) 1292//! 1293//! @tparam TResult 返り値の型です。 1294//! @tparam TFunction 関数か関数オブジェクトの型です。 1295//! @tparam TAllocator アロケータの型です。 1296//--------------------------------------------------------------------------- 1297template< 1298 typename TResult, 1299 typename TArg0, typename TArg1, typename TArg2, 1300 typename TFunction, 1301 typename TAllocator = os::IAllocator 1302> 1303class FunctionSlot3 : public Slot3<TResult, TArg0, TArg1, TArg2, TAllocator> 1304{ 1305public: 1306 typedef TResult ResultType; 1307 typedef TFunction FunctionType; 1308 typedef TAllocator AllocatorType; 1309 1310 //! コンストラクタです。 1311 FunctionSlot3(AllocatorType* allocator, FunctionType function) 1312 : Slot3<TResult, TArg0, TArg1, TArg2, TAllocator>(allocator), m_Function(function) {} 1313 1314 //! @brief スロットにシグナルを送信します。 1315 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2) 1316 { 1317 return m_Function(arg0, arg1, arg2); 1318 } 1319 1320private: 1321 TFunction m_Function; 1322}; 1323 1324//--------------------------------------------------------------------------- 1325//! @brief スロットに合図を送るためのクラスです。(引数は 3 個です) 1326//! 1327//! @tparam TResult 返り値の型です。 1328//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 1329//! @tparam TAllocator アロケータの型です。 1330//! @tparam TSlot スロットの型です。 1331//--------------------------------------------------------------------------- 1332template< 1333 typename TResult, 1334 typename TArg0, typename TArg1, typename TArg2, 1335 typename TResultCombiner = LastValueResult<TResult>, 1336 typename TAllocator = os::IAllocator, 1337 typename TSlot = Slot3<TResult, TArg0, TArg1, TArg2, TAllocator> 1338> 1339class Signal3 1340{ 1341 NW_DISALLOW_COPY_AND_ASSIGN(Signal3); 1342 1343public: 1344 typedef Signal3<TResult, TArg0, TArg1, TArg2, TResultCombiner, TAllocator, TSlot> SelfType; 1345 typedef TSlot SlotType; 1346 typedef TResult ResultType; 1347 typedef ut::MoveArray<SlotType*> SlotList; 1348 typedef TResultCombiner ResultCombinerType; 1349 typedef TAllocator AllocatorType; 1350 1351#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1352 //! @brief スロット実行用関数オブジェクトです。 1353 struct Invoker 1354 { 1355 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2) {} 1356 ResultType operator()(SlotType* slot) const 1357 { 1358 return slot->Invoke(m_arg0, m_arg1, m_arg2); 1359 } 1360 TArg0 m_arg0; 1361 TArg1 m_arg1; 1362 TArg2 m_arg2; 1363 }; 1364#endif 1365 1366 //---------------------------------------- 1367 //! @name 作成/破棄 1368 //@{ 1369 1370 //! @brief 無効なシグナルを生成します。 1371 //! 1372 //! @param[in] allocator アロケータです。 1373 //! 1374 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 1375 { 1376 void* memory = allocator->Alloc(sizeof(SelfType)); 1377 if (memory) 1378 { 1379#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1380 return new(memory) SelfType(NULL, 0, allocator); 1381#else 1382 return new(memory) SelfType(allocator); 1383#endif 1384 } 1385 else 1386 { 1387 return NULL; 1388 } 1389 } 1390 1391 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 1392 //! 1393 //! @param[in] maxSlots スロットを追加できる最大数です。 1394 //! @param[in] allocator アロケータです。 1395 //! 1396 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 1397 { 1398 void* memory = allocator->Alloc(sizeof(SelfType)); 1399 if (memory) 1400 { 1401#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1402 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 1403 if (elements != NULL) 1404 { 1405 return new(memory) SelfType(elements, maxSlots, allocator); 1406 } 1407 else 1408 { 1409 allocator->Free(memory); 1410 return NULL; 1411 } 1412#else 1413 NW_UNUSED_VARIABLE(maxSlots); 1414 return new(memory) SelfType(allocator); 1415#endif 1416 } 1417 else 1418 { 1419 return NULL; 1420 } 1421 } 1422 1423 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 1424 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 1425 { 1426 void* memory = allocator->Alloc(sizeof(SelfType)); 1427 if (memory) 1428 { 1429 return new(memory) SelfType(allocator); 1430 } 1431 else 1432 { 1433 return NULL; 1434 } 1435 } 1436 1437 //! オブジェクトを破棄します。 1438 void Destroy() { this->~Signal3(); this->m_Allocator->Free(this); } 1439 1440 //@} 1441 1442 //---------------------------------------- 1443 //! @name スロット 1444 //@{ 1445 1446 //! @brief スロットと接続し、シグナルが送られるようにする。 1447 //! 1448 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1449 //! シグナルに接続できるスロット数は1つになります。 1450 //! 1451 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1452 //! Connect する前に必ず Disconnect するようにしてください。 1453 //! Disconnect していない場合は、アサートで停止します。 1454 //! 1455 //! @param[in] slot スロットです。 1456 //! 1457 void Connect(SlotType* slot) 1458 { 1459#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1460 bool pushed = this->m_Slots.push_back(slot); 1461 NW_ASSERT(pushed); 1462#else 1463 NW_ASSERT(this->m_Slot == NULL); 1464 this->m_Slot = slot; 1465#endif 1466 } 1467 1468 //! @brief スロットを作成し、接続します。 1469 //! 1470 //! 内部でメモリを確保します。 1471 //! 1472 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1473 //! シグナルに接続できるスロット数は1つになります。 1474 //! 1475 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1476 //! Connect する前に必ず Disconnect するようにしてください。 1477 //! Disconnect していない場合は、アサートで停止します。 1478 //! 1479 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1480 //! 1481 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1482 //! @param[in] allocator アロケータです。 1483 //! 1484 //! @return 生成されたスロットです。 1485 //! 1486 template<typename TFunction> 1487 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 1488 { 1489 typedef FunctionSlot3<ResultType, TArg0, TArg1, TArg2, TFunction, AllocatorType> FunctionSlotType; 1490 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 1491 1492 this->Connect(slot); 1493 return slot; 1494 } 1495 1496 //! @brief スロットを作成し、接続します。 1497 //! 1498 //! 内部でメモリを確保します。 1499 //! 1500 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1501 //! シグナルに接続できるスロット数は1つになります。 1502 //! 1503 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1504 //! Connect する前に必ず Disconnect するようにしてください。 1505 //! Disconnect していない場合は、アサートで停止します。 1506 //! 1507 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1508 //! 1509 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1510 //! 1511 //! @return 生成されたスロットです。 1512 //! 1513 template<typename TFunction> 1514 SlotType* CreateAndConnect(TFunction function) 1515 { 1516 return CreateAndConnect(function, this->m_Allocator); 1517 } 1518 1519 //! @brief スロットを切断します。 1520 //! 1521 //! @param[in] slot 切断するスロットです。 1522 //! 1523 void Disconnect(SlotType* slot) 1524 { 1525#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1526 this->m_Slots.erase_find(slot); 1527#else 1528 if (this->m_Slot == slot) 1529 { 1530 this->m_Slot = NULL; 1531 } 1532#endif 1533 } 1534 1535 //! @brief スロットを切断して、破棄します。 1536 //! 1537 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 1538 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 1539 //! 1540 //! @param[in] slot 切断するスロットです。 1541 //! 1542 void DisconnectAndDestroy(SlotType* slot) 1543 { 1544#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1545 this->m_Slots.erase_find(slot); 1546 slot->Destroy(); 1547#else 1548 if (this->m_Slot == slot) 1549 { 1550 this->m_Slot = NULL; 1551 } 1552 if (slot) 1553 { 1554 slot->Destroy(); 1555 } 1556#endif 1557 } 1558 //@} 1559 1560 //! @brief シグナルを送信します。 1561 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2) 1562 { 1563#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1564 ResultCombinerType combiner; 1565 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2)); 1566#else 1567 if (this->m_Slot) 1568 { 1569 return this->m_Slot->Invoke(arg0, arg1, arg2); 1570 } 1571 else 1572 { 1573 return ResultType(); 1574 } 1575#endif 1576 } 1577 1578 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 1579 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 1580 { 1581 os::MemorySizeCalculator size(alignment); 1582 1583 GetMemorySizeForInvalidateSignalInternal(&size); 1584 1585 return size.GetSizeWithPadding(alignment); 1586 } 1587 1588 //! @details :private 1589 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 1590 { 1591 os::MemorySizeCalculator& size = *pSize; 1592 1593 size += sizeof(SelfType); 1594 } 1595 1596 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 1597 //! 1598 //! @param[in] maxSlots スロットを追加できる最大数です。 1599 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 1600 { 1601 os::MemorySizeCalculator size(alignment); 1602 1603 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 1604 1605 return size.GetSizeWithPadding(alignment); 1606 } 1607 1608 //! @details :private 1609 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 1610 { 1611 os::MemorySizeCalculator& size = *pSize; 1612 1613 size += sizeof(SelfType); 1614 1615#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1616 size += sizeof(SlotType*) * maxSlots; 1617#else 1618 NW_UNUSED_VARIABLE(maxSlots); 1619#endif 1620 } 1621 1622private: 1623#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1624 //! @brief コンストラクタです。 1625 Signal3(void* elements, size_t maxSlots, AllocatorType* allocator) 1626 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 1627 //! @brief コンストラクタです。 1628 explicit Signal3(AllocatorType* allocator) 1629 : m_Allocator(allocator), m_Slots(allocator) {} 1630 //! @brief デストラクタです。 1631 ~Signal3() { DestroyAllSlots(m_Slots); } 1632#else 1633 //! @brief コンストラクタです。 1634 explicit Signal3(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 1635 //! @brief デストラクタです。 1636 ~Signal3() { SafeDestroy(this->m_Slot); } 1637#endif 1638 1639 AllocatorType* m_Allocator; 1640 1641#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1642 SlotList m_Slots; 1643#else 1644 SlotType* m_Slot; 1645#endif 1646}; 1647 1648//--------------------------------------------------------------------------- 1649//! @brief シグナルを受け取るためのインターフェースです。(引数は 4 個です) 1650//! 1651//! @tparam TResult 返り値の型です。 1652//! @tparam TAllocator アロケータの型です。 1653//--------------------------------------------------------------------------- 1654template< 1655 typename TResult, 1656 typename TArg0, typename TArg1, typename TArg2, typename TArg3, 1657 typename TAllocator = os::IAllocator 1658> 1659class Slot4 1660{ 1661public: 1662 typedef TResult ResultType; 1663 typedef TAllocator AllocatorType; 1664 1665 //! @brief コンストラクタです。 1666 explicit Slot4(AllocatorType* allocator) : m_Allocator(allocator) {} 1667 1668 //! @brief 自らを破棄します。 1669 void Destroy() 1670 { 1671 AllocatorType* allocator = this->GetAllocator(); 1672 if (allocator) 1673 { 1674 this->~Slot4(); 1675 allocator->Free(this); 1676 } 1677 } 1678 1679 //! @brief 自らを破棄します。 1680 void Destroy(AllocatorType* allocator) 1681 { 1682 NW_NULL_ASSERT(allocator); 1683 this->~Slot4(); 1684 allocator->Free(this); 1685 } 1686 1687 //! @brief スロットにシグナルを送信します。 1688 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3) = 0; 1689 1690 AllocatorType* GetAllocator() { return m_Allocator; } 1691 1692protected: 1693 //! デストラクタです。 1694 virtual ~Slot4() {} 1695 1696private: 1697 AllocatorType* m_Allocator; 1698}; 1699 1700//--------------------------------------------------------------------------- 1701//! @brief シグナルを受け取るためのクラスです。(引数は 4 個です) 1702//! 1703//! @tparam TResult 返り値の型です。 1704//! @tparam TFunction 関数か関数オブジェクトの型です。 1705//! @tparam TAllocator アロケータの型です。 1706//--------------------------------------------------------------------------- 1707template< 1708 typename TResult, 1709 typename TArg0, typename TArg1, typename TArg2, typename TArg3, 1710 typename TFunction, 1711 typename TAllocator = os::IAllocator 1712> 1713class FunctionSlot4 : public Slot4<TResult, TArg0, TArg1, TArg2, TArg3, TAllocator> 1714{ 1715public: 1716 typedef TResult ResultType; 1717 typedef TFunction FunctionType; 1718 typedef TAllocator AllocatorType; 1719 1720 //! コンストラクタです。 1721 FunctionSlot4(AllocatorType* allocator, FunctionType function) 1722 : Slot4<TResult, TArg0, TArg1, TArg2, TArg3, TAllocator>(allocator), m_Function(function) {} 1723 1724 //! @brief スロットにシグナルを送信します。 1725 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3) 1726 { 1727 return m_Function(arg0, arg1, arg2, arg3); 1728 } 1729 1730private: 1731 TFunction m_Function; 1732}; 1733 1734//--------------------------------------------------------------------------- 1735//! @brief スロットに合図を送るためのクラスです。(引数は 4 個です) 1736//! 1737//! @tparam TResult 返り値の型です。 1738//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 1739//! @tparam TAllocator アロケータの型です。 1740//! @tparam TSlot スロットの型です。 1741//--------------------------------------------------------------------------- 1742template< 1743 typename TResult, 1744 typename TArg0, typename TArg1, typename TArg2, typename TArg3, 1745 typename TResultCombiner = LastValueResult<TResult>, 1746 typename TAllocator = os::IAllocator, 1747 typename TSlot = Slot4<TResult, TArg0, TArg1, TArg2, TArg3, TAllocator> 1748> 1749class Signal4 1750{ 1751 NW_DISALLOW_COPY_AND_ASSIGN(Signal4); 1752 1753public: 1754 typedef Signal4<TResult, TArg0, TArg1, TArg2, TArg3, TResultCombiner, TAllocator, TSlot> SelfType; 1755 typedef TSlot SlotType; 1756 typedef TResult ResultType; 1757 typedef ut::MoveArray<SlotType*> SlotList; 1758 typedef TResultCombiner ResultCombinerType; 1759 typedef TAllocator AllocatorType; 1760 1761#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1762 //! @brief スロット実行用関数オブジェクトです。 1763 struct Invoker 1764 { 1765 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3) {} 1766 ResultType operator()(SlotType* slot) const 1767 { 1768 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3); 1769 } 1770 TArg0 m_arg0; 1771 TArg1 m_arg1; 1772 TArg2 m_arg2; 1773 TArg3 m_arg3; 1774 }; 1775#endif 1776 1777 //---------------------------------------- 1778 //! @name 作成/破棄 1779 //@{ 1780 1781 //! @brief 無効なシグナルを生成します。 1782 //! 1783 //! @param[in] allocator アロケータです。 1784 //! 1785 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 1786 { 1787 void* memory = allocator->Alloc(sizeof(SelfType)); 1788 if (memory) 1789 { 1790#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1791 return new(memory) SelfType(NULL, 0, allocator); 1792#else 1793 return new(memory) SelfType(allocator); 1794#endif 1795 } 1796 else 1797 { 1798 return NULL; 1799 } 1800 } 1801 1802 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 1803 //! 1804 //! @param[in] maxSlots スロットを追加できる最大数です。 1805 //! @param[in] allocator アロケータです。 1806 //! 1807 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 1808 { 1809 void* memory = allocator->Alloc(sizeof(SelfType)); 1810 if (memory) 1811 { 1812#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1813 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 1814 if (elements != NULL) 1815 { 1816 return new(memory) SelfType(elements, maxSlots, allocator); 1817 } 1818 else 1819 { 1820 allocator->Free(memory); 1821 return NULL; 1822 } 1823#else 1824 NW_UNUSED_VARIABLE(maxSlots); 1825 return new(memory) SelfType(allocator); 1826#endif 1827 } 1828 else 1829 { 1830 return NULL; 1831 } 1832 } 1833 1834 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 1835 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 1836 { 1837 void* memory = allocator->Alloc(sizeof(SelfType)); 1838 if (memory) 1839 { 1840 return new(memory) SelfType(allocator); 1841 } 1842 else 1843 { 1844 return NULL; 1845 } 1846 } 1847 1848 //! オブジェクトを破棄します。 1849 void Destroy() { this->~Signal4(); this->m_Allocator->Free(this); } 1850 1851 //@} 1852 1853 //---------------------------------------- 1854 //! @name スロット 1855 //@{ 1856 1857 //! @brief スロットと接続し、シグナルが送られるようにする。 1858 //! 1859 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1860 //! シグナルに接続できるスロット数は1つになります。 1861 //! 1862 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1863 //! Connect する前に必ず Disconnect するようにしてください。 1864 //! Disconnect していない場合は、アサートで停止します。 1865 //! 1866 //! @param[in] slot スロットです。 1867 //! 1868 void Connect(SlotType* slot) 1869 { 1870#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1871 bool pushed = this->m_Slots.push_back(slot); 1872 NW_ASSERT(pushed); 1873#else 1874 NW_ASSERT(this->m_Slot == NULL); 1875 this->m_Slot = slot; 1876#endif 1877 } 1878 1879 //! @brief スロットを作成し、接続します。 1880 //! 1881 //! 内部でメモリを確保します。 1882 //! 1883 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1884 //! シグナルに接続できるスロット数は1つになります。 1885 //! 1886 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1887 //! Connect する前に必ず Disconnect するようにしてください。 1888 //! Disconnect していない場合は、アサートで停止します。 1889 //! 1890 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1891 //! 1892 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1893 //! @param[in] allocator アロケータです。 1894 //! 1895 //! @return 生成されたスロットです。 1896 //! 1897 template<typename TFunction> 1898 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 1899 { 1900 typedef FunctionSlot4<ResultType, TArg0, TArg1, TArg2, TArg3, TFunction, AllocatorType> FunctionSlotType; 1901 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 1902 1903 this->Connect(slot); 1904 return slot; 1905 } 1906 1907 //! @brief スロットを作成し、接続します。 1908 //! 1909 //! 内部でメモリを確保します。 1910 //! 1911 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1912 //! シグナルに接続できるスロット数は1つになります。 1913 //! 1914 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 1915 //! Connect する前に必ず Disconnect するようにしてください。 1916 //! Disconnect していない場合は、アサートで停止します。 1917 //! 1918 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 1919 //! 1920 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 1921 //! 1922 //! @return 生成されたスロットです。 1923 //! 1924 template<typename TFunction> 1925 SlotType* CreateAndConnect(TFunction function) 1926 { 1927 return CreateAndConnect(function, this->m_Allocator); 1928 } 1929 1930 //! @brief スロットを切断します。 1931 //! 1932 //! @param[in] slot 切断するスロットです。 1933 //! 1934 void Disconnect(SlotType* slot) 1935 { 1936#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1937 this->m_Slots.erase_find(slot); 1938#else 1939 if (this->m_Slot == slot) 1940 { 1941 this->m_Slot = NULL; 1942 } 1943#endif 1944 } 1945 1946 //! @brief スロットを切断して、破棄します。 1947 //! 1948 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 1949 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 1950 //! 1951 //! @param[in] slot 切断するスロットです。 1952 //! 1953 void DisconnectAndDestroy(SlotType* slot) 1954 { 1955#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1956 this->m_Slots.erase_find(slot); 1957 slot->Destroy(); 1958#else 1959 if (this->m_Slot == slot) 1960 { 1961 this->m_Slot = NULL; 1962 } 1963 if (slot) 1964 { 1965 slot->Destroy(); 1966 } 1967#endif 1968 } 1969 //@} 1970 1971 //! @brief シグナルを送信します。 1972 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3) 1973 { 1974#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 1975 ResultCombinerType combiner; 1976 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3)); 1977#else 1978 if (this->m_Slot) 1979 { 1980 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3); 1981 } 1982 else 1983 { 1984 return ResultType(); 1985 } 1986#endif 1987 } 1988 1989 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 1990 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 1991 { 1992 os::MemorySizeCalculator size(alignment); 1993 1994 GetMemorySizeForInvalidateSignalInternal(&size); 1995 1996 return size.GetSizeWithPadding(alignment); 1997 } 1998 1999 //! @details :private 2000 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 2001 { 2002 os::MemorySizeCalculator& size = *pSize; 2003 2004 size += sizeof(SelfType); 2005 } 2006 2007 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 2008 //! 2009 //! @param[in] maxSlots スロットを追加できる最大数です。 2010 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 2011 { 2012 os::MemorySizeCalculator size(alignment); 2013 2014 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 2015 2016 return size.GetSizeWithPadding(alignment); 2017 } 2018 2019 //! @details :private 2020 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 2021 { 2022 os::MemorySizeCalculator& size = *pSize; 2023 2024 size += sizeof(SelfType); 2025 2026#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2027 size += sizeof(SlotType*) * maxSlots; 2028#else 2029 NW_UNUSED_VARIABLE(maxSlots); 2030#endif 2031 } 2032 2033private: 2034#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2035 //! @brief コンストラクタです。 2036 Signal4(void* elements, size_t maxSlots, AllocatorType* allocator) 2037 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 2038 //! @brief コンストラクタです。 2039 explicit Signal4(AllocatorType* allocator) 2040 : m_Allocator(allocator), m_Slots(allocator) {} 2041 //! @brief デストラクタです。 2042 ~Signal4() { DestroyAllSlots(m_Slots); } 2043#else 2044 //! @brief コンストラクタです。 2045 explicit Signal4(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 2046 //! @brief デストラクタです。 2047 ~Signal4() { SafeDestroy(this->m_Slot); } 2048#endif 2049 2050 AllocatorType* m_Allocator; 2051 2052#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2053 SlotList m_Slots; 2054#else 2055 SlotType* m_Slot; 2056#endif 2057}; 2058 2059//--------------------------------------------------------------------------- 2060//! @brief シグナルを受け取るためのインターフェースです。(引数は 5 個です) 2061//! 2062//! @tparam TResult 返り値の型です。 2063//! @tparam TAllocator アロケータの型です。 2064//--------------------------------------------------------------------------- 2065template< 2066 typename TResult, 2067 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, 2068 typename TAllocator = os::IAllocator 2069> 2070class Slot5 2071{ 2072public: 2073 typedef TResult ResultType; 2074 typedef TAllocator AllocatorType; 2075 2076 //! @brief コンストラクタです。 2077 explicit Slot5(AllocatorType* allocator) : m_Allocator(allocator) {} 2078 2079 //! @brief 自らを破棄します。 2080 void Destroy() 2081 { 2082 AllocatorType* allocator = this->GetAllocator(); 2083 if (allocator) 2084 { 2085 this->~Slot5(); 2086 allocator->Free(this); 2087 } 2088 } 2089 2090 //! @brief 自らを破棄します。 2091 void Destroy(AllocatorType* allocator) 2092 { 2093 NW_NULL_ASSERT(allocator); 2094 this->~Slot5(); 2095 allocator->Free(this); 2096 } 2097 2098 //! @brief スロットにシグナルを送信します。 2099 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) = 0; 2100 2101 AllocatorType* GetAllocator() { return m_Allocator; } 2102 2103protected: 2104 //! デストラクタです。 2105 virtual ~Slot5() {} 2106 2107private: 2108 AllocatorType* m_Allocator; 2109}; 2110 2111//--------------------------------------------------------------------------- 2112//! @brief シグナルを受け取るためのクラスです。(引数は 5 個です) 2113//! 2114//! @tparam TResult 返り値の型です。 2115//! @tparam TFunction 関数か関数オブジェクトの型です。 2116//! @tparam TAllocator アロケータの型です。 2117//--------------------------------------------------------------------------- 2118template< 2119 typename TResult, 2120 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, 2121 typename TFunction, 2122 typename TAllocator = os::IAllocator 2123> 2124class FunctionSlot5 : public Slot5<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TAllocator> 2125{ 2126public: 2127 typedef TResult ResultType; 2128 typedef TFunction FunctionType; 2129 typedef TAllocator AllocatorType; 2130 2131 //! コンストラクタです。 2132 FunctionSlot5(AllocatorType* allocator, FunctionType function) 2133 : Slot5<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TAllocator>(allocator), m_Function(function) {} 2134 2135 //! @brief スロットにシグナルを送信します。 2136 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) 2137 { 2138 return m_Function(arg0, arg1, arg2, arg3, arg4); 2139 } 2140 2141private: 2142 TFunction m_Function; 2143}; 2144 2145//--------------------------------------------------------------------------- 2146//! @brief スロットに合図を送るためのクラスです。(引数は 5 個です) 2147//! 2148//! @tparam TResult 返り値の型です。 2149//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 2150//! @tparam TAllocator アロケータの型です。 2151//! @tparam TSlot スロットの型です。 2152//--------------------------------------------------------------------------- 2153template< 2154 typename TResult, 2155 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, 2156 typename TResultCombiner = LastValueResult<TResult>, 2157 typename TAllocator = os::IAllocator, 2158 typename TSlot = Slot5<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TAllocator> 2159> 2160class Signal5 2161{ 2162 NW_DISALLOW_COPY_AND_ASSIGN(Signal5); 2163 2164public: 2165 typedef Signal5<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TResultCombiner, TAllocator, TSlot> SelfType; 2166 typedef TSlot SlotType; 2167 typedef TResult ResultType; 2168 typedef ut::MoveArray<SlotType*> SlotList; 2169 typedef TResultCombiner ResultCombinerType; 2170 typedef TAllocator AllocatorType; 2171 2172#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2173 //! @brief スロット実行用関数オブジェクトです。 2174 struct Invoker 2175 { 2176 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4) {} 2177 ResultType operator()(SlotType* slot) const 2178 { 2179 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4); 2180 } 2181 TArg0 m_arg0; 2182 TArg1 m_arg1; 2183 TArg2 m_arg2; 2184 TArg3 m_arg3; 2185 TArg4 m_arg4; 2186 }; 2187#endif 2188 2189 //---------------------------------------- 2190 //! @name 作成/破棄 2191 //@{ 2192 2193 //! @brief 無効なシグナルを生成します。 2194 //! 2195 //! @param[in] allocator アロケータです。 2196 //! 2197 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 2198 { 2199 void* memory = allocator->Alloc(sizeof(SelfType)); 2200 if (memory) 2201 { 2202#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2203 return new(memory) SelfType(NULL, 0, allocator); 2204#else 2205 return new(memory) SelfType(allocator); 2206#endif 2207 } 2208 else 2209 { 2210 return NULL; 2211 } 2212 } 2213 2214 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 2215 //! 2216 //! @param[in] maxSlots スロットを追加できる最大数です。 2217 //! @param[in] allocator アロケータです。 2218 //! 2219 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 2220 { 2221 void* memory = allocator->Alloc(sizeof(SelfType)); 2222 if (memory) 2223 { 2224#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2225 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 2226 if (elements != NULL) 2227 { 2228 return new(memory) SelfType(elements, maxSlots, allocator); 2229 } 2230 else 2231 { 2232 allocator->Free(memory); 2233 return NULL; 2234 } 2235#else 2236 NW_UNUSED_VARIABLE(maxSlots); 2237 return new(memory) SelfType(allocator); 2238#endif 2239 } 2240 else 2241 { 2242 return NULL; 2243 } 2244 } 2245 2246 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 2247 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 2248 { 2249 void* memory = allocator->Alloc(sizeof(SelfType)); 2250 if (memory) 2251 { 2252 return new(memory) SelfType(allocator); 2253 } 2254 else 2255 { 2256 return NULL; 2257 } 2258 } 2259 2260 //! オブジェクトを破棄します。 2261 void Destroy() { this->~Signal5(); this->m_Allocator->Free(this); } 2262 2263 //@} 2264 2265 //---------------------------------------- 2266 //! @name スロット 2267 //@{ 2268 2269 //! @brief スロットと接続し、シグナルが送られるようにする。 2270 //! 2271 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2272 //! シグナルに接続できるスロット数は1つになります。 2273 //! 2274 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2275 //! Connect する前に必ず Disconnect するようにしてください。 2276 //! Disconnect していない場合は、アサートで停止します。 2277 //! 2278 //! @param[in] slot スロットです。 2279 //! 2280 void Connect(SlotType* slot) 2281 { 2282#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2283 bool pushed = this->m_Slots.push_back(slot); 2284 NW_ASSERT(pushed); 2285#else 2286 NW_ASSERT(this->m_Slot == NULL); 2287 this->m_Slot = slot; 2288#endif 2289 } 2290 2291 //! @brief スロットを作成し、接続します。 2292 //! 2293 //! 内部でメモリを確保します。 2294 //! 2295 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2296 //! シグナルに接続できるスロット数は1つになります。 2297 //! 2298 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2299 //! Connect する前に必ず Disconnect するようにしてください。 2300 //! Disconnect していない場合は、アサートで停止します。 2301 //! 2302 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 2303 //! 2304 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 2305 //! @param[in] allocator アロケータです。 2306 //! 2307 //! @return 生成されたスロットです。 2308 //! 2309 template<typename TFunction> 2310 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 2311 { 2312 typedef FunctionSlot5<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TFunction, AllocatorType> FunctionSlotType; 2313 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 2314 2315 this->Connect(slot); 2316 return slot; 2317 } 2318 2319 //! @brief スロットを作成し、接続します。 2320 //! 2321 //! 内部でメモリを確保します。 2322 //! 2323 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2324 //! シグナルに接続できるスロット数は1つになります。 2325 //! 2326 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2327 //! Connect する前に必ず Disconnect するようにしてください。 2328 //! Disconnect していない場合は、アサートで停止します。 2329 //! 2330 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 2331 //! 2332 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 2333 //! 2334 //! @return 生成されたスロットです。 2335 //! 2336 template<typename TFunction> 2337 SlotType* CreateAndConnect(TFunction function) 2338 { 2339 return CreateAndConnect(function, this->m_Allocator); 2340 } 2341 2342 //! @brief スロットを切断します。 2343 //! 2344 //! @param[in] slot 切断するスロットです。 2345 //! 2346 void Disconnect(SlotType* slot) 2347 { 2348#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2349 this->m_Slots.erase_find(slot); 2350#else 2351 if (this->m_Slot == slot) 2352 { 2353 this->m_Slot = NULL; 2354 } 2355#endif 2356 } 2357 2358 //! @brief スロットを切断して、破棄します。 2359 //! 2360 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 2361 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 2362 //! 2363 //! @param[in] slot 切断するスロットです。 2364 //! 2365 void DisconnectAndDestroy(SlotType* slot) 2366 { 2367#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2368 this->m_Slots.erase_find(slot); 2369 slot->Destroy(); 2370#else 2371 if (this->m_Slot == slot) 2372 { 2373 this->m_Slot = NULL; 2374 } 2375 if (slot) 2376 { 2377 slot->Destroy(); 2378 } 2379#endif 2380 } 2381 //@} 2382 2383 //! @brief シグナルを送信します。 2384 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) 2385 { 2386#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2387 ResultCombinerType combiner; 2388 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4)); 2389#else 2390 if (this->m_Slot) 2391 { 2392 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4); 2393 } 2394 else 2395 { 2396 return ResultType(); 2397 } 2398#endif 2399 } 2400 2401 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 2402 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 2403 { 2404 os::MemorySizeCalculator size(alignment); 2405 2406 GetMemorySizeForInvalidateSignalInternal(&size); 2407 2408 return size.GetSizeWithPadding(alignment); 2409 } 2410 2411 //! @details :private 2412 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 2413 { 2414 os::MemorySizeCalculator& size = *pSize; 2415 2416 size += sizeof(SelfType); 2417 } 2418 2419 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 2420 //! 2421 //! @param[in] maxSlots スロットを追加できる最大数です。 2422 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 2423 { 2424 os::MemorySizeCalculator size(alignment); 2425 2426 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 2427 2428 return size.GetSizeWithPadding(alignment); 2429 } 2430 2431 //! @details :private 2432 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 2433 { 2434 os::MemorySizeCalculator& size = *pSize; 2435 2436 size += sizeof(SelfType); 2437 2438#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2439 size += sizeof(SlotType*) * maxSlots; 2440#else 2441 NW_UNUSED_VARIABLE(maxSlots); 2442#endif 2443 } 2444 2445private: 2446#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2447 //! @brief コンストラクタです。 2448 Signal5(void* elements, size_t maxSlots, AllocatorType* allocator) 2449 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 2450 //! @brief コンストラクタです。 2451 explicit Signal5(AllocatorType* allocator) 2452 : m_Allocator(allocator), m_Slots(allocator) {} 2453 //! @brief デストラクタです。 2454 ~Signal5() { DestroyAllSlots(m_Slots); } 2455#else 2456 //! @brief コンストラクタです。 2457 explicit Signal5(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 2458 //! @brief デストラクタです。 2459 ~Signal5() { SafeDestroy(this->m_Slot); } 2460#endif 2461 2462 AllocatorType* m_Allocator; 2463 2464#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2465 SlotList m_Slots; 2466#else 2467 SlotType* m_Slot; 2468#endif 2469}; 2470 2471//--------------------------------------------------------------------------- 2472//! @brief シグナルを受け取るためのインターフェースです。(引数は 6 個です) 2473//! 2474//! @tparam TResult 返り値の型です。 2475//! @tparam TAllocator アロケータの型です。 2476//--------------------------------------------------------------------------- 2477template< 2478 typename TResult, 2479 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, 2480 typename TAllocator = os::IAllocator 2481> 2482class Slot6 2483{ 2484public: 2485 typedef TResult ResultType; 2486 typedef TAllocator AllocatorType; 2487 2488 //! @brief コンストラクタです。 2489 explicit Slot6(AllocatorType* allocator) : m_Allocator(allocator) {} 2490 2491 //! @brief 自らを破棄します。 2492 void Destroy() 2493 { 2494 AllocatorType* allocator = this->GetAllocator(); 2495 if (allocator) 2496 { 2497 this->~Slot6(); 2498 allocator->Free(this); 2499 } 2500 } 2501 2502 //! @brief 自らを破棄します。 2503 void Destroy(AllocatorType* allocator) 2504 { 2505 NW_NULL_ASSERT(allocator); 2506 this->~Slot6(); 2507 allocator->Free(this); 2508 } 2509 2510 //! @brief スロットにシグナルを送信します。 2511 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) = 0; 2512 2513 AllocatorType* GetAllocator() { return m_Allocator; } 2514 2515protected: 2516 //! デストラクタです。 2517 virtual ~Slot6() {} 2518 2519private: 2520 AllocatorType* m_Allocator; 2521}; 2522 2523//--------------------------------------------------------------------------- 2524//! @brief シグナルを受け取るためのクラスです。(引数は 6 個です) 2525//! 2526//! @tparam TResult 返り値の型です。 2527//! @tparam TFunction 関数か関数オブジェクトの型です。 2528//! @tparam TAllocator アロケータの型です。 2529//--------------------------------------------------------------------------- 2530template< 2531 typename TResult, 2532 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, 2533 typename TFunction, 2534 typename TAllocator = os::IAllocator 2535> 2536class FunctionSlot6 : public Slot6<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TAllocator> 2537{ 2538public: 2539 typedef TResult ResultType; 2540 typedef TFunction FunctionType; 2541 typedef TAllocator AllocatorType; 2542 2543 //! コンストラクタです。 2544 FunctionSlot6(AllocatorType* allocator, FunctionType function) 2545 : Slot6<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TAllocator>(allocator), m_Function(function) {} 2546 2547 //! @brief スロットにシグナルを送信します。 2548 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) 2549 { 2550 return m_Function(arg0, arg1, arg2, arg3, arg4, arg5); 2551 } 2552 2553private: 2554 TFunction m_Function; 2555}; 2556 2557//--------------------------------------------------------------------------- 2558//! @brief スロットに合図を送るためのクラスです。(引数は 6 個です) 2559//! 2560//! @tparam TResult 返り値の型です。 2561//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 2562//! @tparam TAllocator アロケータの型です。 2563//! @tparam TSlot スロットの型です。 2564//--------------------------------------------------------------------------- 2565template< 2566 typename TResult, 2567 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, 2568 typename TResultCombiner = LastValueResult<TResult>, 2569 typename TAllocator = os::IAllocator, 2570 typename TSlot = Slot6<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TAllocator> 2571> 2572class Signal6 2573{ 2574 NW_DISALLOW_COPY_AND_ASSIGN(Signal6); 2575 2576public: 2577 typedef Signal6<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResultCombiner, TAllocator, TSlot> SelfType; 2578 typedef TSlot SlotType; 2579 typedef TResult ResultType; 2580 typedef ut::MoveArray<SlotType*> SlotList; 2581 typedef TResultCombiner ResultCombinerType; 2582 typedef TAllocator AllocatorType; 2583 2584#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2585 //! @brief スロット実行用関数オブジェクトです。 2586 struct Invoker 2587 { 2588 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4), m_arg5(arg5) {} 2589 ResultType operator()(SlotType* slot) const 2590 { 2591 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5); 2592 } 2593 TArg0 m_arg0; 2594 TArg1 m_arg1; 2595 TArg2 m_arg2; 2596 TArg3 m_arg3; 2597 TArg4 m_arg4; 2598 TArg5 m_arg5; 2599 }; 2600#endif 2601 2602 //---------------------------------------- 2603 //! @name 作成/破棄 2604 //@{ 2605 2606 //! @brief 無効なシグナルを生成します。 2607 //! 2608 //! @param[in] allocator アロケータです。 2609 //! 2610 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 2611 { 2612 void* memory = allocator->Alloc(sizeof(SelfType)); 2613 if (memory) 2614 { 2615#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2616 return new(memory) SelfType(NULL, 0, allocator); 2617#else 2618 return new(memory) SelfType(allocator); 2619#endif 2620 } 2621 else 2622 { 2623 return NULL; 2624 } 2625 } 2626 2627 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 2628 //! 2629 //! @param[in] maxSlots スロットを追加できる最大数です。 2630 //! @param[in] allocator アロケータです。 2631 //! 2632 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 2633 { 2634 void* memory = allocator->Alloc(sizeof(SelfType)); 2635 if (memory) 2636 { 2637#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2638 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 2639 if (elements != NULL) 2640 { 2641 return new(memory) SelfType(elements, maxSlots, allocator); 2642 } 2643 else 2644 { 2645 allocator->Free(memory); 2646 return NULL; 2647 } 2648#else 2649 NW_UNUSED_VARIABLE(maxSlots); 2650 return new(memory) SelfType(allocator); 2651#endif 2652 } 2653 else 2654 { 2655 return NULL; 2656 } 2657 } 2658 2659 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 2660 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 2661 { 2662 void* memory = allocator->Alloc(sizeof(SelfType)); 2663 if (memory) 2664 { 2665 return new(memory) SelfType(allocator); 2666 } 2667 else 2668 { 2669 return NULL; 2670 } 2671 } 2672 2673 //! オブジェクトを破棄します。 2674 void Destroy() { this->~Signal6(); this->m_Allocator->Free(this); } 2675 2676 //@} 2677 2678 //---------------------------------------- 2679 //! @name スロット 2680 //@{ 2681 2682 //! @brief スロットと接続し、シグナルが送られるようにする。 2683 //! 2684 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2685 //! シグナルに接続できるスロット数は1つになります。 2686 //! 2687 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2688 //! Connect する前に必ず Disconnect するようにしてください。 2689 //! Disconnect していない場合は、アサートで停止します。 2690 //! 2691 //! @param[in] slot スロットです。 2692 //! 2693 void Connect(SlotType* slot) 2694 { 2695#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2696 bool pushed = this->m_Slots.push_back(slot); 2697 NW_ASSERT(pushed); 2698#else 2699 NW_ASSERT(this->m_Slot == NULL); 2700 this->m_Slot = slot; 2701#endif 2702 } 2703 2704 //! @brief スロットを作成し、接続します。 2705 //! 2706 //! 内部でメモリを確保します。 2707 //! 2708 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2709 //! シグナルに接続できるスロット数は1つになります。 2710 //! 2711 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2712 //! Connect する前に必ず Disconnect するようにしてください。 2713 //! Disconnect していない場合は、アサートで停止します。 2714 //! 2715 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 2716 //! 2717 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 2718 //! @param[in] allocator アロケータです。 2719 //! 2720 //! @return 生成されたスロットです。 2721 //! 2722 template<typename TFunction> 2723 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 2724 { 2725 typedef FunctionSlot6<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TFunction, AllocatorType> FunctionSlotType; 2726 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 2727 2728 this->Connect(slot); 2729 return slot; 2730 } 2731 2732 //! @brief スロットを作成し、接続します。 2733 //! 2734 //! 内部でメモリを確保します。 2735 //! 2736 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2737 //! シグナルに接続できるスロット数は1つになります。 2738 //! 2739 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 2740 //! Connect する前に必ず Disconnect するようにしてください。 2741 //! Disconnect していない場合は、アサートで停止します。 2742 //! 2743 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 2744 //! 2745 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 2746 //! 2747 //! @return 生成されたスロットです。 2748 //! 2749 template<typename TFunction> 2750 SlotType* CreateAndConnect(TFunction function) 2751 { 2752 return CreateAndConnect(function, this->m_Allocator); 2753 } 2754 2755 //! @brief スロットを切断します。 2756 //! 2757 //! @param[in] slot 切断するスロットです。 2758 //! 2759 void Disconnect(SlotType* slot) 2760 { 2761#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2762 this->m_Slots.erase_find(slot); 2763#else 2764 if (this->m_Slot == slot) 2765 { 2766 this->m_Slot = NULL; 2767 } 2768#endif 2769 } 2770 2771 //! @brief スロットを切断して、破棄します。 2772 //! 2773 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 2774 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 2775 //! 2776 //! @param[in] slot 切断するスロットです。 2777 //! 2778 void DisconnectAndDestroy(SlotType* slot) 2779 { 2780#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2781 this->m_Slots.erase_find(slot); 2782 slot->Destroy(); 2783#else 2784 if (this->m_Slot == slot) 2785 { 2786 this->m_Slot = NULL; 2787 } 2788 if (slot) 2789 { 2790 slot->Destroy(); 2791 } 2792#endif 2793 } 2794 //@} 2795 2796 //! @brief シグナルを送信します。 2797 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) 2798 { 2799#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2800 ResultCombinerType combiner; 2801 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4, arg5)); 2802#else 2803 if (this->m_Slot) 2804 { 2805 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4, arg5); 2806 } 2807 else 2808 { 2809 return ResultType(); 2810 } 2811#endif 2812 } 2813 2814 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 2815 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 2816 { 2817 os::MemorySizeCalculator size(alignment); 2818 2819 GetMemorySizeForInvalidateSignalInternal(&size); 2820 2821 return size.GetSizeWithPadding(alignment); 2822 } 2823 2824 //! @details :private 2825 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 2826 { 2827 os::MemorySizeCalculator& size = *pSize; 2828 2829 size += sizeof(SelfType); 2830 } 2831 2832 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 2833 //! 2834 //! @param[in] maxSlots スロットを追加できる最大数です。 2835 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 2836 { 2837 os::MemorySizeCalculator size(alignment); 2838 2839 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 2840 2841 return size.GetSizeWithPadding(alignment); 2842 } 2843 2844 //! @details :private 2845 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 2846 { 2847 os::MemorySizeCalculator& size = *pSize; 2848 2849 size += sizeof(SelfType); 2850 2851#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2852 size += sizeof(SlotType*) * maxSlots; 2853#else 2854 NW_UNUSED_VARIABLE(maxSlots); 2855#endif 2856 } 2857 2858private: 2859#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2860 //! @brief コンストラクタです。 2861 Signal6(void* elements, size_t maxSlots, AllocatorType* allocator) 2862 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 2863 //! @brief コンストラクタです。 2864 explicit Signal6(AllocatorType* allocator) 2865 : m_Allocator(allocator), m_Slots(allocator) {} 2866 //! @brief デストラクタです。 2867 ~Signal6() { DestroyAllSlots(m_Slots); } 2868#else 2869 //! @brief コンストラクタです。 2870 explicit Signal6(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 2871 //! @brief デストラクタです。 2872 ~Signal6() { SafeDestroy(this->m_Slot); } 2873#endif 2874 2875 AllocatorType* m_Allocator; 2876 2877#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2878 SlotList m_Slots; 2879#else 2880 SlotType* m_Slot; 2881#endif 2882}; 2883 2884//--------------------------------------------------------------------------- 2885//! @brief シグナルを受け取るためのインターフェースです。(引数は 7 個です) 2886//! 2887//! @tparam TResult 返り値の型です。 2888//! @tparam TAllocator アロケータの型です。 2889//--------------------------------------------------------------------------- 2890template< 2891 typename TResult, 2892 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, 2893 typename TAllocator = os::IAllocator 2894> 2895class Slot7 2896{ 2897public: 2898 typedef TResult ResultType; 2899 typedef TAllocator AllocatorType; 2900 2901 //! @brief コンストラクタです。 2902 explicit Slot7(AllocatorType* allocator) : m_Allocator(allocator) {} 2903 2904 //! @brief 自らを破棄します。 2905 void Destroy() 2906 { 2907 AllocatorType* allocator = this->GetAllocator(); 2908 if (allocator) 2909 { 2910 this->~Slot7(); 2911 allocator->Free(this); 2912 } 2913 } 2914 2915 //! @brief 自らを破棄します。 2916 void Destroy(AllocatorType* allocator) 2917 { 2918 NW_NULL_ASSERT(allocator); 2919 this->~Slot7(); 2920 allocator->Free(this); 2921 } 2922 2923 //! @brief スロットにシグナルを送信します。 2924 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) = 0; 2925 2926 AllocatorType* GetAllocator() { return m_Allocator; } 2927 2928protected: 2929 //! デストラクタです。 2930 virtual ~Slot7() {} 2931 2932private: 2933 AllocatorType* m_Allocator; 2934}; 2935 2936//--------------------------------------------------------------------------- 2937//! @brief シグナルを受け取るためのクラスです。(引数は 7 個です) 2938//! 2939//! @tparam TResult 返り値の型です。 2940//! @tparam TFunction 関数か関数オブジェクトの型です。 2941//! @tparam TAllocator アロケータの型です。 2942//--------------------------------------------------------------------------- 2943template< 2944 typename TResult, 2945 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, 2946 typename TFunction, 2947 typename TAllocator = os::IAllocator 2948> 2949class FunctionSlot7 : public Slot7<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TAllocator> 2950{ 2951public: 2952 typedef TResult ResultType; 2953 typedef TFunction FunctionType; 2954 typedef TAllocator AllocatorType; 2955 2956 //! コンストラクタです。 2957 FunctionSlot7(AllocatorType* allocator, FunctionType function) 2958 : Slot7<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TAllocator>(allocator), m_Function(function) {} 2959 2960 //! @brief スロットにシグナルを送信します。 2961 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) 2962 { 2963 return m_Function(arg0, arg1, arg2, arg3, arg4, arg5, arg6); 2964 } 2965 2966private: 2967 TFunction m_Function; 2968}; 2969 2970//--------------------------------------------------------------------------- 2971//! @brief スロットに合図を送るためのクラスです。(引数は 7 個です) 2972//! 2973//! @tparam TResult 返り値の型です。 2974//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 2975//! @tparam TAllocator アロケータの型です。 2976//! @tparam TSlot スロットの型です。 2977//--------------------------------------------------------------------------- 2978template< 2979 typename TResult, 2980 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, 2981 typename TResultCombiner = LastValueResult<TResult>, 2982 typename TAllocator = os::IAllocator, 2983 typename TSlot = Slot7<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TAllocator> 2984> 2985class Signal7 2986{ 2987 NW_DISALLOW_COPY_AND_ASSIGN(Signal7); 2988 2989public: 2990 typedef Signal7<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResultCombiner, TAllocator, TSlot> SelfType; 2991 typedef TSlot SlotType; 2992 typedef TResult ResultType; 2993 typedef ut::MoveArray<SlotType*> SlotList; 2994 typedef TResultCombiner ResultCombinerType; 2995 typedef TAllocator AllocatorType; 2996 2997#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 2998 //! @brief スロット実行用関数オブジェクトです。 2999 struct Invoker 3000 { 3001 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4), m_arg5(arg5), m_arg6(arg6) {} 3002 ResultType operator()(SlotType* slot) const 3003 { 3004 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6); 3005 } 3006 TArg0 m_arg0; 3007 TArg1 m_arg1; 3008 TArg2 m_arg2; 3009 TArg3 m_arg3; 3010 TArg4 m_arg4; 3011 TArg5 m_arg5; 3012 TArg6 m_arg6; 3013 }; 3014#endif 3015 3016 //---------------------------------------- 3017 //! @name 作成/破棄 3018 //@{ 3019 3020 //! @brief 無効なシグナルを生成します。 3021 //! 3022 //! @param[in] allocator アロケータです。 3023 //! 3024 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 3025 { 3026 void* memory = allocator->Alloc(sizeof(SelfType)); 3027 if (memory) 3028 { 3029#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3030 return new(memory) SelfType(NULL, 0, allocator); 3031#else 3032 return new(memory) SelfType(allocator); 3033#endif 3034 } 3035 else 3036 { 3037 return NULL; 3038 } 3039 } 3040 3041 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 3042 //! 3043 //! @param[in] maxSlots スロットを追加できる最大数です。 3044 //! @param[in] allocator アロケータです。 3045 //! 3046 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 3047 { 3048 void* memory = allocator->Alloc(sizeof(SelfType)); 3049 if (memory) 3050 { 3051#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3052 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 3053 if (elements != NULL) 3054 { 3055 return new(memory) SelfType(elements, maxSlots, allocator); 3056 } 3057 else 3058 { 3059 allocator->Free(memory); 3060 return NULL; 3061 } 3062#else 3063 NW_UNUSED_VARIABLE(maxSlots); 3064 return new(memory) SelfType(allocator); 3065#endif 3066 } 3067 else 3068 { 3069 return NULL; 3070 } 3071 } 3072 3073 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 3074 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 3075 { 3076 void* memory = allocator->Alloc(sizeof(SelfType)); 3077 if (memory) 3078 { 3079 return new(memory) SelfType(allocator); 3080 } 3081 else 3082 { 3083 return NULL; 3084 } 3085 } 3086 3087 //! オブジェクトを破棄します。 3088 void Destroy() { this->~Signal7(); this->m_Allocator->Free(this); } 3089 3090 //@} 3091 3092 //---------------------------------------- 3093 //! @name スロット 3094 //@{ 3095 3096 //! @brief スロットと接続し、シグナルが送られるようにする。 3097 //! 3098 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3099 //! シグナルに接続できるスロット数は1つになります。 3100 //! 3101 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3102 //! Connect する前に必ず Disconnect するようにしてください。 3103 //! Disconnect していない場合は、アサートで停止します。 3104 //! 3105 //! @param[in] slot スロットです。 3106 //! 3107 void Connect(SlotType* slot) 3108 { 3109#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3110 bool pushed = this->m_Slots.push_back(slot); 3111 NW_ASSERT(pushed); 3112#else 3113 NW_ASSERT(this->m_Slot == NULL); 3114 this->m_Slot = slot; 3115#endif 3116 } 3117 3118 //! @brief スロットを作成し、接続します。 3119 //! 3120 //! 内部でメモリを確保します。 3121 //! 3122 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3123 //! シグナルに接続できるスロット数は1つになります。 3124 //! 3125 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3126 //! Connect する前に必ず Disconnect するようにしてください。 3127 //! Disconnect していない場合は、アサートで停止します。 3128 //! 3129 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3130 //! 3131 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3132 //! @param[in] allocator アロケータです。 3133 //! 3134 //! @return 生成されたスロットです。 3135 //! 3136 template<typename TFunction> 3137 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 3138 { 3139 typedef FunctionSlot7<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TFunction, AllocatorType> FunctionSlotType; 3140 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 3141 3142 this->Connect(slot); 3143 return slot; 3144 } 3145 3146 //! @brief スロットを作成し、接続します。 3147 //! 3148 //! 内部でメモリを確保します。 3149 //! 3150 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3151 //! シグナルに接続できるスロット数は1つになります。 3152 //! 3153 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3154 //! Connect する前に必ず Disconnect するようにしてください。 3155 //! Disconnect していない場合は、アサートで停止します。 3156 //! 3157 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3158 //! 3159 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3160 //! 3161 //! @return 生成されたスロットです。 3162 //! 3163 template<typename TFunction> 3164 SlotType* CreateAndConnect(TFunction function) 3165 { 3166 return CreateAndConnect(function, this->m_Allocator); 3167 } 3168 3169 //! @brief スロットを切断します。 3170 //! 3171 //! @param[in] slot 切断するスロットです。 3172 //! 3173 void Disconnect(SlotType* slot) 3174 { 3175#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3176 this->m_Slots.erase_find(slot); 3177#else 3178 if (this->m_Slot == slot) 3179 { 3180 this->m_Slot = NULL; 3181 } 3182#endif 3183 } 3184 3185 //! @brief スロットを切断して、破棄します。 3186 //! 3187 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 3188 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 3189 //! 3190 //! @param[in] slot 切断するスロットです。 3191 //! 3192 void DisconnectAndDestroy(SlotType* slot) 3193 { 3194#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3195 this->m_Slots.erase_find(slot); 3196 slot->Destroy(); 3197#else 3198 if (this->m_Slot == slot) 3199 { 3200 this->m_Slot = NULL; 3201 } 3202 if (slot) 3203 { 3204 slot->Destroy(); 3205 } 3206#endif 3207 } 3208 //@} 3209 3210 //! @brief シグナルを送信します。 3211 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) 3212 { 3213#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3214 ResultCombinerType combiner; 3215 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4, arg5, arg6)); 3216#else 3217 if (this->m_Slot) 3218 { 3219 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4, arg5, arg6); 3220 } 3221 else 3222 { 3223 return ResultType(); 3224 } 3225#endif 3226 } 3227 3228 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 3229 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 3230 { 3231 os::MemorySizeCalculator size(alignment); 3232 3233 GetMemorySizeForInvalidateSignalInternal(&size); 3234 3235 return size.GetSizeWithPadding(alignment); 3236 } 3237 3238 //! @details :private 3239 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 3240 { 3241 os::MemorySizeCalculator& size = *pSize; 3242 3243 size += sizeof(SelfType); 3244 } 3245 3246 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 3247 //! 3248 //! @param[in] maxSlots スロットを追加できる最大数です。 3249 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 3250 { 3251 os::MemorySizeCalculator size(alignment); 3252 3253 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 3254 3255 return size.GetSizeWithPadding(alignment); 3256 } 3257 3258 //! @details :private 3259 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 3260 { 3261 os::MemorySizeCalculator& size = *pSize; 3262 3263 size += sizeof(SelfType); 3264 3265#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3266 size += sizeof(SlotType*) * maxSlots; 3267#else 3268 NW_UNUSED_VARIABLE(maxSlots); 3269#endif 3270 } 3271 3272private: 3273#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3274 //! @brief コンストラクタです。 3275 Signal7(void* elements, size_t maxSlots, AllocatorType* allocator) 3276 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 3277 //! @brief コンストラクタです。 3278 explicit Signal7(AllocatorType* allocator) 3279 : m_Allocator(allocator), m_Slots(allocator) {} 3280 //! @brief デストラクタです。 3281 ~Signal7() { DestroyAllSlots(m_Slots); } 3282#else 3283 //! @brief コンストラクタです。 3284 explicit Signal7(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 3285 //! @brief デストラクタです。 3286 ~Signal7() { SafeDestroy(this->m_Slot); } 3287#endif 3288 3289 AllocatorType* m_Allocator; 3290 3291#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3292 SlotList m_Slots; 3293#else 3294 SlotType* m_Slot; 3295#endif 3296}; 3297 3298//--------------------------------------------------------------------------- 3299//! @brief シグナルを受け取るためのインターフェースです。(引数は 8 個です) 3300//! 3301//! @tparam TResult 返り値の型です。 3302//! @tparam TAllocator アロケータの型です。 3303//--------------------------------------------------------------------------- 3304template< 3305 typename TResult, 3306 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, 3307 typename TAllocator = os::IAllocator 3308> 3309class Slot8 3310{ 3311public: 3312 typedef TResult ResultType; 3313 typedef TAllocator AllocatorType; 3314 3315 //! @brief コンストラクタです。 3316 explicit Slot8(AllocatorType* allocator) : m_Allocator(allocator) {} 3317 3318 //! @brief 自らを破棄します。 3319 void Destroy() 3320 { 3321 AllocatorType* allocator = this->GetAllocator(); 3322 if (allocator) 3323 { 3324 this->~Slot8(); 3325 allocator->Free(this); 3326 } 3327 } 3328 3329 //! @brief 自らを破棄します。 3330 void Destroy(AllocatorType* allocator) 3331 { 3332 NW_NULL_ASSERT(allocator); 3333 this->~Slot8(); 3334 allocator->Free(this); 3335 } 3336 3337 //! @brief スロットにシグナルを送信します。 3338 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) = 0; 3339 3340 AllocatorType* GetAllocator() { return m_Allocator; } 3341 3342protected: 3343 //! デストラクタです。 3344 virtual ~Slot8() {} 3345 3346private: 3347 AllocatorType* m_Allocator; 3348}; 3349 3350//--------------------------------------------------------------------------- 3351//! @brief シグナルを受け取るためのクラスです。(引数は 8 個です) 3352//! 3353//! @tparam TResult 返り値の型です。 3354//! @tparam TFunction 関数か関数オブジェクトの型です。 3355//! @tparam TAllocator アロケータの型です。 3356//--------------------------------------------------------------------------- 3357template< 3358 typename TResult, 3359 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, 3360 typename TFunction, 3361 typename TAllocator = os::IAllocator 3362> 3363class FunctionSlot8 : public Slot8<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TAllocator> 3364{ 3365public: 3366 typedef TResult ResultType; 3367 typedef TFunction FunctionType; 3368 typedef TAllocator AllocatorType; 3369 3370 //! コンストラクタです。 3371 FunctionSlot8(AllocatorType* allocator, FunctionType function) 3372 : Slot8<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TAllocator>(allocator), m_Function(function) {} 3373 3374 //! @brief スロットにシグナルを送信します。 3375 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) 3376 { 3377 return m_Function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); 3378 } 3379 3380private: 3381 TFunction m_Function; 3382}; 3383 3384//--------------------------------------------------------------------------- 3385//! @brief スロットに合図を送るためのクラスです。(引数は 8 個です) 3386//! 3387//! @tparam TResult 返り値の型です。 3388//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 3389//! @tparam TAllocator アロケータの型です。 3390//! @tparam TSlot スロットの型です。 3391//--------------------------------------------------------------------------- 3392template< 3393 typename TResult, 3394 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, 3395 typename TResultCombiner = LastValueResult<TResult>, 3396 typename TAllocator = os::IAllocator, 3397 typename TSlot = Slot8<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TAllocator> 3398> 3399class Signal8 3400{ 3401 NW_DISALLOW_COPY_AND_ASSIGN(Signal8); 3402 3403public: 3404 typedef Signal8<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResultCombiner, TAllocator, TSlot> SelfType; 3405 typedef TSlot SlotType; 3406 typedef TResult ResultType; 3407 typedef ut::MoveArray<SlotType*> SlotList; 3408 typedef TResultCombiner ResultCombinerType; 3409 typedef TAllocator AllocatorType; 3410 3411#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3412 //! @brief スロット実行用関数オブジェクトです。 3413 struct Invoker 3414 { 3415 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4), m_arg5(arg5), m_arg6(arg6), m_arg7(arg7) {} 3416 ResultType operator()(SlotType* slot) const 3417 { 3418 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7); 3419 } 3420 TArg0 m_arg0; 3421 TArg1 m_arg1; 3422 TArg2 m_arg2; 3423 TArg3 m_arg3; 3424 TArg4 m_arg4; 3425 TArg5 m_arg5; 3426 TArg6 m_arg6; 3427 TArg7 m_arg7; 3428 }; 3429#endif 3430 3431 //---------------------------------------- 3432 //! @name 作成/破棄 3433 //@{ 3434 3435 //! @brief 無効なシグナルを生成します。 3436 //! 3437 //! @param[in] allocator アロケータです。 3438 //! 3439 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 3440 { 3441 void* memory = allocator->Alloc(sizeof(SelfType)); 3442 if (memory) 3443 { 3444#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3445 return new(memory) SelfType(NULL, 0, allocator); 3446#else 3447 return new(memory) SelfType(allocator); 3448#endif 3449 } 3450 else 3451 { 3452 return NULL; 3453 } 3454 } 3455 3456 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 3457 //! 3458 //! @param[in] maxSlots スロットを追加できる最大数です。 3459 //! @param[in] allocator アロケータです。 3460 //! 3461 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 3462 { 3463 void* memory = allocator->Alloc(sizeof(SelfType)); 3464 if (memory) 3465 { 3466#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3467 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 3468 if (elements != NULL) 3469 { 3470 return new(memory) SelfType(elements, maxSlots, allocator); 3471 } 3472 else 3473 { 3474 allocator->Free(memory); 3475 return NULL; 3476 } 3477#else 3478 NW_UNUSED_VARIABLE(maxSlots); 3479 return new(memory) SelfType(allocator); 3480#endif 3481 } 3482 else 3483 { 3484 return NULL; 3485 } 3486 } 3487 3488 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 3489 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 3490 { 3491 void* memory = allocator->Alloc(sizeof(SelfType)); 3492 if (memory) 3493 { 3494 return new(memory) SelfType(allocator); 3495 } 3496 else 3497 { 3498 return NULL; 3499 } 3500 } 3501 3502 //! オブジェクトを破棄します。 3503 void Destroy() { this->~Signal8(); this->m_Allocator->Free(this); } 3504 3505 //@} 3506 3507 //---------------------------------------- 3508 //! @name スロット 3509 //@{ 3510 3511 //! @brief スロットと接続し、シグナルが送られるようにする。 3512 //! 3513 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3514 //! シグナルに接続できるスロット数は1つになります。 3515 //! 3516 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3517 //! Connect する前に必ず Disconnect するようにしてください。 3518 //! Disconnect していない場合は、アサートで停止します。 3519 //! 3520 //! @param[in] slot スロットです。 3521 //! 3522 void Connect(SlotType* slot) 3523 { 3524#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3525 bool pushed = this->m_Slots.push_back(slot); 3526 NW_ASSERT(pushed); 3527#else 3528 NW_ASSERT(this->m_Slot == NULL); 3529 this->m_Slot = slot; 3530#endif 3531 } 3532 3533 //! @brief スロットを作成し、接続します。 3534 //! 3535 //! 内部でメモリを確保します。 3536 //! 3537 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3538 //! シグナルに接続できるスロット数は1つになります。 3539 //! 3540 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3541 //! Connect する前に必ず Disconnect するようにしてください。 3542 //! Disconnect していない場合は、アサートで停止します。 3543 //! 3544 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3545 //! 3546 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3547 //! @param[in] allocator アロケータです。 3548 //! 3549 //! @return 生成されたスロットです。 3550 //! 3551 template<typename TFunction> 3552 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 3553 { 3554 typedef FunctionSlot8<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TFunction, AllocatorType> FunctionSlotType; 3555 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 3556 3557 this->Connect(slot); 3558 return slot; 3559 } 3560 3561 //! @brief スロットを作成し、接続します。 3562 //! 3563 //! 内部でメモリを確保します。 3564 //! 3565 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3566 //! シグナルに接続できるスロット数は1つになります。 3567 //! 3568 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3569 //! Connect する前に必ず Disconnect するようにしてください。 3570 //! Disconnect していない場合は、アサートで停止します。 3571 //! 3572 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3573 //! 3574 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3575 //! 3576 //! @return 生成されたスロットです。 3577 //! 3578 template<typename TFunction> 3579 SlotType* CreateAndConnect(TFunction function) 3580 { 3581 return CreateAndConnect(function, this->m_Allocator); 3582 } 3583 3584 //! @brief スロットを切断します。 3585 //! 3586 //! @param[in] slot 切断するスロットです。 3587 //! 3588 void Disconnect(SlotType* slot) 3589 { 3590#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3591 this->m_Slots.erase_find(slot); 3592#else 3593 if (this->m_Slot == slot) 3594 { 3595 this->m_Slot = NULL; 3596 } 3597#endif 3598 } 3599 3600 //! @brief スロットを切断して、破棄します。 3601 //! 3602 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 3603 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 3604 //! 3605 //! @param[in] slot 切断するスロットです。 3606 //! 3607 void DisconnectAndDestroy(SlotType* slot) 3608 { 3609#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3610 this->m_Slots.erase_find(slot); 3611 slot->Destroy(); 3612#else 3613 if (this->m_Slot == slot) 3614 { 3615 this->m_Slot = NULL; 3616 } 3617 if (slot) 3618 { 3619 slot->Destroy(); 3620 } 3621#endif 3622 } 3623 //@} 3624 3625 //! @brief シグナルを送信します。 3626 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) 3627 { 3628#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3629 ResultCombinerType combiner; 3630 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); 3631#else 3632 if (this->m_Slot) 3633 { 3634 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); 3635 } 3636 else 3637 { 3638 return ResultType(); 3639 } 3640#endif 3641 } 3642 3643 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 3644 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 3645 { 3646 os::MemorySizeCalculator size(alignment); 3647 3648 GetMemorySizeForInvalidateSignalInternal(&size); 3649 3650 return size.GetSizeWithPadding(alignment); 3651 } 3652 3653 //! @details :private 3654 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 3655 { 3656 os::MemorySizeCalculator& size = *pSize; 3657 3658 size += sizeof(SelfType); 3659 } 3660 3661 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 3662 //! 3663 //! @param[in] maxSlots スロットを追加できる最大数です。 3664 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 3665 { 3666 os::MemorySizeCalculator size(alignment); 3667 3668 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 3669 3670 return size.GetSizeWithPadding(alignment); 3671 } 3672 3673 //! @details :private 3674 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 3675 { 3676 os::MemorySizeCalculator& size = *pSize; 3677 3678 size += sizeof(SelfType); 3679 3680#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3681 size += sizeof(SlotType*) * maxSlots; 3682#else 3683 NW_UNUSED_VARIABLE(maxSlots); 3684#endif 3685 } 3686 3687private: 3688#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3689 //! @brief コンストラクタです。 3690 Signal8(void* elements, size_t maxSlots, AllocatorType* allocator) 3691 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 3692 //! @brief コンストラクタです。 3693 explicit Signal8(AllocatorType* allocator) 3694 : m_Allocator(allocator), m_Slots(allocator) {} 3695 //! @brief デストラクタです。 3696 ~Signal8() { DestroyAllSlots(m_Slots); } 3697#else 3698 //! @brief コンストラクタです。 3699 explicit Signal8(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 3700 //! @brief デストラクタです。 3701 ~Signal8() { SafeDestroy(this->m_Slot); } 3702#endif 3703 3704 AllocatorType* m_Allocator; 3705 3706#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3707 SlotList m_Slots; 3708#else 3709 SlotType* m_Slot; 3710#endif 3711}; 3712 3713//--------------------------------------------------------------------------- 3714//! @brief シグナルを受け取るためのインターフェースです。(引数は 9 個です) 3715//! 3716//! @tparam TResult 返り値の型です。 3717//! @tparam TAllocator アロケータの型です。 3718//--------------------------------------------------------------------------- 3719template< 3720 typename TResult, 3721 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, 3722 typename TAllocator = os::IAllocator 3723> 3724class Slot9 3725{ 3726public: 3727 typedef TResult ResultType; 3728 typedef TAllocator AllocatorType; 3729 3730 //! @brief コンストラクタです。 3731 explicit Slot9(AllocatorType* allocator) : m_Allocator(allocator) {} 3732 3733 //! @brief 自らを破棄します。 3734 void Destroy() 3735 { 3736 AllocatorType* allocator = this->GetAllocator(); 3737 if (allocator) 3738 { 3739 this->~Slot9(); 3740 allocator->Free(this); 3741 } 3742 } 3743 3744 //! @brief 自らを破棄します。 3745 void Destroy(AllocatorType* allocator) 3746 { 3747 NW_NULL_ASSERT(allocator); 3748 this->~Slot9(); 3749 allocator->Free(this); 3750 } 3751 3752 //! @brief スロットにシグナルを送信します。 3753 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) = 0; 3754 3755 AllocatorType* GetAllocator() { return m_Allocator; } 3756 3757protected: 3758 //! デストラクタです。 3759 virtual ~Slot9() {} 3760 3761private: 3762 AllocatorType* m_Allocator; 3763}; 3764 3765//--------------------------------------------------------------------------- 3766//! @brief シグナルを受け取るためのクラスです。(引数は 9 個です) 3767//! 3768//! @tparam TResult 返り値の型です。 3769//! @tparam TFunction 関数か関数オブジェクトの型です。 3770//! @tparam TAllocator アロケータの型です。 3771//--------------------------------------------------------------------------- 3772template< 3773 typename TResult, 3774 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, 3775 typename TFunction, 3776 typename TAllocator = os::IAllocator 3777> 3778class FunctionSlot9 : public Slot9<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TAllocator> 3779{ 3780public: 3781 typedef TResult ResultType; 3782 typedef TFunction FunctionType; 3783 typedef TAllocator AllocatorType; 3784 3785 //! コンストラクタです。 3786 FunctionSlot9(AllocatorType* allocator, FunctionType function) 3787 : Slot9<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TAllocator>(allocator), m_Function(function) {} 3788 3789 //! @brief スロットにシグナルを送信します。 3790 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) 3791 { 3792 return m_Function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); 3793 } 3794 3795private: 3796 TFunction m_Function; 3797}; 3798 3799//--------------------------------------------------------------------------- 3800//! @brief スロットに合図を送るためのクラスです。(引数は 9 個です) 3801//! 3802//! @tparam TResult 返り値の型です。 3803//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 3804//! @tparam TAllocator アロケータの型です。 3805//! @tparam TSlot スロットの型です。 3806//--------------------------------------------------------------------------- 3807template< 3808 typename TResult, 3809 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, 3810 typename TResultCombiner = LastValueResult<TResult>, 3811 typename TAllocator = os::IAllocator, 3812 typename TSlot = Slot9<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TAllocator> 3813> 3814class Signal9 3815{ 3816 NW_DISALLOW_COPY_AND_ASSIGN(Signal9); 3817 3818public: 3819 typedef Signal9<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResultCombiner, TAllocator, TSlot> SelfType; 3820 typedef TSlot SlotType; 3821 typedef TResult ResultType; 3822 typedef ut::MoveArray<SlotType*> SlotList; 3823 typedef TResultCombiner ResultCombinerType; 3824 typedef TAllocator AllocatorType; 3825 3826#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3827 //! @brief スロット実行用関数オブジェクトです。 3828 struct Invoker 3829 { 3830 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4), m_arg5(arg5), m_arg6(arg6), m_arg7(arg7), m_arg8(arg8) {} 3831 ResultType operator()(SlotType* slot) const 3832 { 3833 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8); 3834 } 3835 TArg0 m_arg0; 3836 TArg1 m_arg1; 3837 TArg2 m_arg2; 3838 TArg3 m_arg3; 3839 TArg4 m_arg4; 3840 TArg5 m_arg5; 3841 TArg6 m_arg6; 3842 TArg7 m_arg7; 3843 TArg8 m_arg8; 3844 }; 3845#endif 3846 3847 //---------------------------------------- 3848 //! @name 作成/破棄 3849 //@{ 3850 3851 //! @brief 無効なシグナルを生成します。 3852 //! 3853 //! @param[in] allocator アロケータです。 3854 //! 3855 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 3856 { 3857 void* memory = allocator->Alloc(sizeof(SelfType)); 3858 if (memory) 3859 { 3860#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3861 return new(memory) SelfType(NULL, 0, allocator); 3862#else 3863 return new(memory) SelfType(allocator); 3864#endif 3865 } 3866 else 3867 { 3868 return NULL; 3869 } 3870 } 3871 3872 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 3873 //! 3874 //! @param[in] maxSlots スロットを追加できる最大数です。 3875 //! @param[in] allocator アロケータです。 3876 //! 3877 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 3878 { 3879 void* memory = allocator->Alloc(sizeof(SelfType)); 3880 if (memory) 3881 { 3882#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3883 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 3884 if (elements != NULL) 3885 { 3886 return new(memory) SelfType(elements, maxSlots, allocator); 3887 } 3888 else 3889 { 3890 allocator->Free(memory); 3891 return NULL; 3892 } 3893#else 3894 NW_UNUSED_VARIABLE(maxSlots); 3895 return new(memory) SelfType(allocator); 3896#endif 3897 } 3898 else 3899 { 3900 return NULL; 3901 } 3902 } 3903 3904 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 3905 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 3906 { 3907 void* memory = allocator->Alloc(sizeof(SelfType)); 3908 if (memory) 3909 { 3910 return new(memory) SelfType(allocator); 3911 } 3912 else 3913 { 3914 return NULL; 3915 } 3916 } 3917 3918 //! オブジェクトを破棄します。 3919 void Destroy() { this->~Signal9(); this->m_Allocator->Free(this); } 3920 3921 //@} 3922 3923 //---------------------------------------- 3924 //! @name スロット 3925 //@{ 3926 3927 //! @brief スロットと接続し、シグナルが送られるようにする。 3928 //! 3929 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3930 //! シグナルに接続できるスロット数は1つになります。 3931 //! 3932 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3933 //! Connect する前に必ず Disconnect するようにしてください。 3934 //! Disconnect していない場合は、アサートで停止します。 3935 //! 3936 //! @param[in] slot スロットです。 3937 //! 3938 void Connect(SlotType* slot) 3939 { 3940#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 3941 bool pushed = this->m_Slots.push_back(slot); 3942 NW_ASSERT(pushed); 3943#else 3944 NW_ASSERT(this->m_Slot == NULL); 3945 this->m_Slot = slot; 3946#endif 3947 } 3948 3949 //! @brief スロットを作成し、接続します。 3950 //! 3951 //! 内部でメモリを確保します。 3952 //! 3953 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3954 //! シグナルに接続できるスロット数は1つになります。 3955 //! 3956 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3957 //! Connect する前に必ず Disconnect するようにしてください。 3958 //! Disconnect していない場合は、アサートで停止します。 3959 //! 3960 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3961 //! 3962 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3963 //! @param[in] allocator アロケータです。 3964 //! 3965 //! @return 生成されたスロットです。 3966 //! 3967 template<typename TFunction> 3968 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 3969 { 3970 typedef FunctionSlot9<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TFunction, AllocatorType> FunctionSlotType; 3971 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 3972 3973 this->Connect(slot); 3974 return slot; 3975 } 3976 3977 //! @brief スロットを作成し、接続します。 3978 //! 3979 //! 内部でメモリを確保します。 3980 //! 3981 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3982 //! シグナルに接続できるスロット数は1つになります。 3983 //! 3984 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 3985 //! Connect する前に必ず Disconnect するようにしてください。 3986 //! Disconnect していない場合は、アサートで停止します。 3987 //! 3988 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 3989 //! 3990 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 3991 //! 3992 //! @return 生成されたスロットです。 3993 //! 3994 template<typename TFunction> 3995 SlotType* CreateAndConnect(TFunction function) 3996 { 3997 return CreateAndConnect(function, this->m_Allocator); 3998 } 3999 4000 //! @brief スロットを切断します。 4001 //! 4002 //! @param[in] slot 切断するスロットです。 4003 //! 4004 void Disconnect(SlotType* slot) 4005 { 4006#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4007 this->m_Slots.erase_find(slot); 4008#else 4009 if (this->m_Slot == slot) 4010 { 4011 this->m_Slot = NULL; 4012 } 4013#endif 4014 } 4015 4016 //! @brief スロットを切断して、破棄します。 4017 //! 4018 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 4019 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 4020 //! 4021 //! @param[in] slot 切断するスロットです。 4022 //! 4023 void DisconnectAndDestroy(SlotType* slot) 4024 { 4025#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4026 this->m_Slots.erase_find(slot); 4027 slot->Destroy(); 4028#else 4029 if (this->m_Slot == slot) 4030 { 4031 this->m_Slot = NULL; 4032 } 4033 if (slot) 4034 { 4035 slot->Destroy(); 4036 } 4037#endif 4038 } 4039 //@} 4040 4041 //! @brief シグナルを送信します。 4042 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) 4043 { 4044#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4045 ResultCombinerType combiner; 4046 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); 4047#else 4048 if (this->m_Slot) 4049 { 4050 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); 4051 } 4052 else 4053 { 4054 return ResultType(); 4055 } 4056#endif 4057 } 4058 4059 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 4060 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 4061 { 4062 os::MemorySizeCalculator size(alignment); 4063 4064 GetMemorySizeForInvalidateSignalInternal(&size); 4065 4066 return size.GetSizeWithPadding(alignment); 4067 } 4068 4069 //! @details :private 4070 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 4071 { 4072 os::MemorySizeCalculator& size = *pSize; 4073 4074 size += sizeof(SelfType); 4075 } 4076 4077 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 4078 //! 4079 //! @param[in] maxSlots スロットを追加できる最大数です。 4080 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 4081 { 4082 os::MemorySizeCalculator size(alignment); 4083 4084 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 4085 4086 return size.GetSizeWithPadding(alignment); 4087 } 4088 4089 //! @details :private 4090 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 4091 { 4092 os::MemorySizeCalculator& size = *pSize; 4093 4094 size += sizeof(SelfType); 4095 4096#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4097 size += sizeof(SlotType*) * maxSlots; 4098#else 4099 NW_UNUSED_VARIABLE(maxSlots); 4100#endif 4101 } 4102 4103private: 4104#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4105 //! @brief コンストラクタです。 4106 Signal9(void* elements, size_t maxSlots, AllocatorType* allocator) 4107 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 4108 //! @brief コンストラクタです。 4109 explicit Signal9(AllocatorType* allocator) 4110 : m_Allocator(allocator), m_Slots(allocator) {} 4111 //! @brief デストラクタです。 4112 ~Signal9() { DestroyAllSlots(m_Slots); } 4113#else 4114 //! @brief コンストラクタです。 4115 explicit Signal9(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 4116 //! @brief デストラクタです。 4117 ~Signal9() { SafeDestroy(this->m_Slot); } 4118#endif 4119 4120 AllocatorType* m_Allocator; 4121 4122#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4123 SlotList m_Slots; 4124#else 4125 SlotType* m_Slot; 4126#endif 4127}; 4128 4129//--------------------------------------------------------------------------- 4130//! @brief シグナルを受け取るためのインターフェースです。(引数は 10 個です) 4131//! 4132//! @tparam TResult 返り値の型です。 4133//! @tparam TAllocator アロケータの型です。 4134//--------------------------------------------------------------------------- 4135template< 4136 typename TResult, 4137 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, typename TArg9, 4138 typename TAllocator = os::IAllocator 4139> 4140class Slot10 4141{ 4142public: 4143 typedef TResult ResultType; 4144 typedef TAllocator AllocatorType; 4145 4146 //! @brief コンストラクタです。 4147 explicit Slot10(AllocatorType* allocator) : m_Allocator(allocator) {} 4148 4149 //! @brief 自らを破棄します。 4150 void Destroy() 4151 { 4152 AllocatorType* allocator = this->GetAllocator(); 4153 if (allocator) 4154 { 4155 this->~Slot10(); 4156 allocator->Free(this); 4157 } 4158 } 4159 4160 //! @brief 自らを破棄します。 4161 void Destroy(AllocatorType* allocator) 4162 { 4163 NW_NULL_ASSERT(allocator); 4164 this->~Slot10(); 4165 allocator->Free(this); 4166 } 4167 4168 //! @brief スロットにシグナルを送信します。 4169 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) = 0; 4170 4171 AllocatorType* GetAllocator() { return m_Allocator; } 4172 4173protected: 4174 //! デストラクタです。 4175 virtual ~Slot10() {} 4176 4177private: 4178 AllocatorType* m_Allocator; 4179}; 4180 4181//--------------------------------------------------------------------------- 4182//! @brief シグナルを受け取るためのクラスです。(引数は 10 個です) 4183//! 4184//! @tparam TResult 返り値の型です。 4185//! @tparam TFunction 関数か関数オブジェクトの型です。 4186//! @tparam TAllocator アロケータの型です。 4187//--------------------------------------------------------------------------- 4188template< 4189 typename TResult, 4190 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, typename TArg9, 4191 typename TFunction, 4192 typename TAllocator = os::IAllocator 4193> 4194class FunctionSlot10 : public Slot10<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TAllocator> 4195{ 4196public: 4197 typedef TResult ResultType; 4198 typedef TFunction FunctionType; 4199 typedef TAllocator AllocatorType; 4200 4201 //! コンストラクタです。 4202 FunctionSlot10(AllocatorType* allocator, FunctionType function) 4203 : Slot10<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TAllocator>(allocator), m_Function(function) {} 4204 4205 //! @brief スロットにシグナルを送信します。 4206 virtual ResultType Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) 4207 { 4208 return m_Function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); 4209 } 4210 4211private: 4212 TFunction m_Function; 4213}; 4214 4215//--------------------------------------------------------------------------- 4216//! @brief スロットに合図を送るためのクラスです。(引数は 10 個です) 4217//! 4218//! @tparam TResult 返り値の型です。 4219//! @tparam TResultCombiner スロットの返り値をまとめて返してくれるコンバイナの型です。 4220//! @tparam TAllocator アロケータの型です。 4221//! @tparam TSlot スロットの型です。 4222//--------------------------------------------------------------------------- 4223template< 4224 typename TResult, 4225 typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TArg5, typename TArg6, typename TArg7, typename TArg8, typename TArg9, 4226 typename TResultCombiner = LastValueResult<TResult>, 4227 typename TAllocator = os::IAllocator, 4228 typename TSlot = Slot10<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TAllocator> 4229> 4230class Signal10 4231{ 4232 NW_DISALLOW_COPY_AND_ASSIGN(Signal10); 4233 4234public: 4235 typedef Signal10<TResult, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResultCombiner, TAllocator, TSlot> SelfType; 4236 typedef TSlot SlotType; 4237 typedef TResult ResultType; 4238 typedef ut::MoveArray<SlotType*> SlotList; 4239 typedef TResultCombiner ResultCombinerType; 4240 typedef TAllocator AllocatorType; 4241 4242#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4243 //! @brief スロット実行用関数オブジェクトです。 4244 struct Invoker 4245 { 4246 Invoker(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3), m_arg4(arg4), m_arg5(arg5), m_arg6(arg6), m_arg7(arg7), m_arg8(arg8), m_arg9(arg9) {} 4247 ResultType operator()(SlotType* slot) const 4248 { 4249 return slot->Invoke(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9); 4250 } 4251 TArg0 m_arg0; 4252 TArg1 m_arg1; 4253 TArg2 m_arg2; 4254 TArg3 m_arg3; 4255 TArg4 m_arg4; 4256 TArg5 m_arg5; 4257 TArg6 m_arg6; 4258 TArg7 m_arg7; 4259 TArg8 m_arg8; 4260 TArg9 m_arg9; 4261 }; 4262#endif 4263 4264 //---------------------------------------- 4265 //! @name 作成/破棄 4266 //@{ 4267 4268 //! @brief 無効なシグナルを生成します。 4269 //! 4270 //! @param[in] allocator アロケータです。 4271 //! 4272 static SelfType* CreateInvalidateSignal(AllocatorType* allocator) 4273 { 4274 void* memory = allocator->Alloc(sizeof(SelfType)); 4275 if (memory) 4276 { 4277#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4278 return new(memory) SelfType(NULL, 0, allocator); 4279#else 4280 return new(memory) SelfType(allocator); 4281#endif 4282 } 4283 else 4284 { 4285 return NULL; 4286 } 4287 } 4288 4289 //! @brief 必要なメモリを事前に確保してシグナルを生成します。 4290 //! 4291 //! @param[in] maxSlots スロットを追加できる最大数です。 4292 //! @param[in] allocator アロケータです。 4293 //! 4294 static SelfType* CreateFixedSizedSignal(size_t maxSlots, AllocatorType* allocator) 4295 { 4296 void* memory = allocator->Alloc(sizeof(SelfType)); 4297 if (memory) 4298 { 4299#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4300 void* elements = allocator->Alloc(sizeof(SlotType*) * maxSlots); 4301 if (elements != NULL) 4302 { 4303 return new(memory) SelfType(elements, maxSlots, allocator); 4304 } 4305 else 4306 { 4307 allocator->Free(memory); 4308 return NULL; 4309 } 4310#else 4311 NW_UNUSED_VARIABLE(maxSlots); 4312 return new(memory) SelfType(allocator); 4313#endif 4314 } 4315 else 4316 { 4317 return NULL; 4318 } 4319 } 4320 4321 //! @brief 必要になるごとにメモリを確保するシグナルを生成します。 4322 static SelfType* CreateVariableSizeSignal(AllocatorType* allocator) 4323 { 4324 void* memory = allocator->Alloc(sizeof(SelfType)); 4325 if (memory) 4326 { 4327 return new(memory) SelfType(allocator); 4328 } 4329 else 4330 { 4331 return NULL; 4332 } 4333 } 4334 4335 //! オブジェクトを破棄します。 4336 void Destroy() { this->~Signal10(); this->m_Allocator->Free(this); } 4337 4338 //@} 4339 4340 //---------------------------------------- 4341 //! @name スロット 4342 //@{ 4343 4344 //! @brief スロットと接続し、シグナルが送られるようにする。 4345 //! 4346 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4347 //! シグナルに接続できるスロット数は1つになります。 4348 //! 4349 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4350 //! Connect する前に必ず Disconnect するようにしてください。 4351 //! Disconnect していない場合は、アサートで停止します。 4352 //! 4353 //! @param[in] slot スロットです。 4354 //! 4355 void Connect(SlotType* slot) 4356 { 4357#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4358 bool pushed = this->m_Slots.push_back(slot); 4359 NW_ASSERT(pushed); 4360#else 4361 NW_ASSERT(this->m_Slot == NULL); 4362 this->m_Slot = slot; 4363#endif 4364 } 4365 4366 //! @brief スロットを作成し、接続します。 4367 //! 4368 //! 内部でメモリを確保します。 4369 //! 4370 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4371 //! シグナルに接続できるスロット数は1つになります。 4372 //! 4373 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4374 //! Connect する前に必ず Disconnect するようにしてください。 4375 //! Disconnect していない場合は、アサートで停止します。 4376 //! 4377 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 4378 //! 4379 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 4380 //! @param[in] allocator アロケータです。 4381 //! 4382 //! @return 生成されたスロットです。 4383 //! 4384 template<typename TFunction> 4385 SlotType* CreateAndConnect(TFunction function, AllocatorType* allocator) 4386 { 4387 typedef FunctionSlot10<ResultType, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TFunction, AllocatorType> FunctionSlotType; 4388 FunctionSlotType* slot = CreateSlot<FunctionSlotType>(allocator, function); 4389 4390 this->Connect(slot); 4391 return slot; 4392 } 4393 4394 //! @brief スロットを作成し、接続します。 4395 //! 4396 //! 内部でメモリを確保します。 4397 //! 4398 //! "nw/ut/ut_Config.h"の"NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4399 //! シグナルに接続できるスロット数は1つになります。 4400 //! 4401 //! "NW_SIGNAL_MULTI_SLOT_ENABLED"定義が無効の場合、 4402 //! Connect する前に必ず Disconnect するようにしてください。 4403 //! Disconnect していない場合は、アサートで停止します。 4404 //! 4405 //! @tparam TFunction 関数ポインタまたは、関数オブジェクトの型です。 4406 //! 4407 //! @param[in] function 関数ポインタまたは、関数オブジェクトです。 4408 //! 4409 //! @return 生成されたスロットです。 4410 //! 4411 template<typename TFunction> 4412 SlotType* CreateAndConnect(TFunction function) 4413 { 4414 return CreateAndConnect(function, this->m_Allocator); 4415 } 4416 4417 //! @brief スロットを切断します。 4418 //! 4419 //! @param[in] slot 切断するスロットです。 4420 //! 4421 void Disconnect(SlotType* slot) 4422 { 4423#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4424 this->m_Slots.erase_find(slot); 4425#else 4426 if (this->m_Slot == slot) 4427 { 4428 this->m_Slot = NULL; 4429 } 4430#endif 4431 } 4432 4433 //! @brief スロットを切断して、破棄します。 4434 //! 4435 //! 関数オブジェクトにアロケータが設定されていると、オブジェクトを破棄します。 4436 //! アロケータが設定されていないと、登録を解除して破棄は行いません。 4437 //! 4438 //! @param[in] slot 切断するスロットです。 4439 //! 4440 void DisconnectAndDestroy(SlotType* slot) 4441 { 4442#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4443 this->m_Slots.erase_find(slot); 4444 slot->Destroy(); 4445#else 4446 if (this->m_Slot == slot) 4447 { 4448 this->m_Slot = NULL; 4449 } 4450 if (slot) 4451 { 4452 slot->Destroy(); 4453 } 4454#endif 4455 } 4456 //@} 4457 4458 //! @brief シグナルを送信します。 4459 ResultType operator()(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) 4460 { 4461#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4462 ResultCombinerType combiner; 4463 return combiner(m_Slots.begin(), m_Slots.end(), Invoker(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)); 4464#else 4465 if (this->m_Slot) 4466 { 4467 return this->m_Slot->Invoke(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); 4468 } 4469 else 4470 { 4471 return ResultType(); 4472 } 4473#endif 4474 } 4475 4476 //! @brief CreateInvalidateSignal() の実行に必要なメモリサイズを取得します。 4477 static size_t GetMemorySizeForInvalidateSignal(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 4478 { 4479 os::MemorySizeCalculator size(alignment); 4480 4481 GetMemorySizeForInvalidateSignalInternal(&size); 4482 4483 return size.GetSizeWithPadding(alignment); 4484 } 4485 4486 //! @details :private 4487 static void GetMemorySizeForInvalidateSignalInternal(os::MemorySizeCalculator* pSize) 4488 { 4489 os::MemorySizeCalculator& size = *pSize; 4490 4491 size += sizeof(SelfType); 4492 } 4493 4494 //! @brief CreateFixedSizedSignal() の実行に必要なメモリサイズを取得します。 4495 //! 4496 //! @param[in] maxSlots スロットを追加できる最大数です。 4497 static size_t GetMemorySizeForFixedSizedSignal(size_t maxSlots, size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) 4498 { 4499 os::MemorySizeCalculator size(alignment); 4500 4501 GetMemorySizeForFixedSizedSignalInternal(&size, maxSlots); 4502 4503 return size.GetSizeWithPadding(alignment); 4504 } 4505 4506 //! @details :private 4507 static void GetMemorySizeForFixedSizedSignalInternal(os::MemorySizeCalculator* pSize, size_t maxSlots) 4508 { 4509 os::MemorySizeCalculator& size = *pSize; 4510 4511 size += sizeof(SelfType); 4512 4513#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4514 size += sizeof(SlotType*) * maxSlots; 4515#else 4516 NW_UNUSED_VARIABLE(maxSlots); 4517#endif 4518 } 4519 4520private: 4521#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4522 //! @brief コンストラクタです。 4523 Signal10(void* elements, size_t maxSlots, AllocatorType* allocator) 4524 : m_Allocator(allocator), m_Slots(elements, maxSlots, allocator) {} 4525 //! @brief コンストラクタです。 4526 explicit Signal10(AllocatorType* allocator) 4527 : m_Allocator(allocator), m_Slots(allocator) {} 4528 //! @brief デストラクタです。 4529 ~Signal10() { DestroyAllSlots(m_Slots); } 4530#else 4531 //! @brief コンストラクタです。 4532 explicit Signal10(AllocatorType* allocator) : m_Allocator(allocator), m_Slot(NULL) {} 4533 //! @brief デストラクタです。 4534 ~Signal10() { SafeDestroy(this->m_Slot); } 4535#endif 4536 4537 AllocatorType* m_Allocator; 4538 4539#ifdef NW_SIGNAL_MULTI_SLOT_ENABLED 4540 SlotList m_Slots; 4541#else 4542 SlotType* m_Slot; 4543#endif 4544}; 4545 4546