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