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