Brunot
Loading...
Searching...
No Matches
Path.h
Go to the documentation of this file.
1
11// ____ __ __ __
12// /\__ _\/\ \ /\ \/\ \
13// \/_/\ \/\ \ \___ __ \ \ \_\ \ ___ __ __ ____ __
14// \ \ \ \ \ _ `\ /'__`\ \ \ _ \ / __`\/\ \/\ \ /',__\ /'__`\
15// \ \ \ \ \ \ \ \/\ __/ \ \ \ \ \/\ \L\ \ \ \_\ \/\__, `\/\ __/
16// \ \_\ \ \_\ \_\ \____\ \ \_\ \_\ \____/\ \____/\/\____/\ \____\
17// \/_/ \/_/\/_/\/____/ \/_/\/_/\/___/ \/___/ \/___/ \/____/
18
19
20#pragma once
21#include <string>
22
23#include "Framework/Engine.h"
25
26#include "System/SceneManager.h"
27
36
37
38namespace gobj
39{
40
324template <typename Gobj = GameObject>
325class Path
326{
327public:
334 explicit Path(std::string pathString)
335 : path(std::make_unique<PathRoot>())
336 {
337 switch (pathString[0])
338 {
339 case '~':
340 {
341 path = std::make_shared<PathBase>(*Engine::getSystem<sys::SceneManager>()->getCurrentScene());
342 pathString = pathString.substr(1);
343 break;
344 }
345 case '^':
346 {
348 pathString = pathString.substr(1);
349 break;
350 }
351 case '/':
352 {
353 path = std::make_shared<PathRoot>();
354 break;
355 }
356 case '.':
357 {
358 // do nothing
359 assert(false && "Cannot create a path that starts with . without passing a gameObject as base");
360 break;
361 }
362 default:
363 {
364 break;
365 }
366 }
367
368 // parse path, getting rid of the first 2 characters
369 parsePath(pathString);
370
371
372 }
373
374
382 Path(std::string pathString, GameObject& rootObject)
383 {
384 assert(pathString[0] == '.');
385 path = std::make_shared<PathBase>(rootObject);
386 // remove the first character, so we don't have an extra directory marker
387 // (the other dir marker will be removed at the end of this function)
388 pathString = pathString.substr(1);
389
390 parsePath(pathString);
391 }
392
393
397 operator Gobj&()
398 {
399 return *begin();
400 }
401
405 operator Gobj*()
406 {
407 return get();
408 }
409
413 operator const Gobj&()
414 {
415 return *begin();
416 }
417
418private:
419 // path objects
420
421 // possibly cache begin and end to optimize
422 // begin_
423 // end_
424
426 std::shared_ptr<PathNode> path;
427
428public:
434 {
435
441 : itr(std::move(itr))
442 {
443 }
444
445 public:
446 friend Path;
447
448 // Part of making iterators stl compliant is declaring public types
449 using difference_type = std::ptrdiff_t;
450 using value_type = Gobj;
451
455 iterator() = default;
456
461 auto get() const -> Gobj*
462 {
463 auto result = dynamic_cast<Gobj*>(itr.get());
464 if (!result)
465 {
466 throw PathException("Path iterator called get() on GameObject that isn't same type as iterator");
467 }
468 return result;
469 }
470
478 {
479 ++itr;
480 return *this;
481 }
482
488 auto operator++(int) -> iterator
489 {
490 auto copy = *this;
491 ++*this;
492 return copy;
493 }
494
500 auto operator==(iterator other) const -> bool
501 {
502 return itr == other.itr;
503 }
504
510 auto operator*() const -> std::add_lvalue_reference_t<Gobj>
511 {
512 auto result = dynamic_cast<Gobj*>(itr.get());
513 if (result == nullptr)
514 {
515 throw PathException("Path iterator dereferenced GameObject that isn't same type as iterator");
516 }
517 return *result;
518 }
519
524 auto operator->() const -> Gobj*
525 {
526 return get();
527 }
528
529 private:
532
533 };
534
535 // Check to make sure Path::iterator is stl compliant
536 static_assert(std::input_iterator<iterator>);
537 static_assert(std::sentinel_for<iterator, iterator>);
538
539
545 auto begin() const -> iterator
546 {
547 return static_cast<iterator>(path->begin());
548 }
549
550
555 auto end() const -> iterator
556 {
557 return static_cast<iterator>(path->end());
558 }
559
565 auto get() const -> Gobj*
566 {
567 return begin().get();
568 }
569
574 auto operator->() const -> Gobj*
575 {
576 return get();
577 }
578
579 // helper functions
580private:
587 static auto splitString(const std::string& fullString, const std::string& delimiter) -> std::vector<std::string>
588 {
589 size_t start = 0;
590 auto end = delimiter.length();
591 auto delimiterLength = delimiter.length();
592 std::string token;
593 std::vector<std::string> result;
594
595 while ((end = fullString.find(delimiter, start)) != std::string::npos)
596 {
597 token = fullString.substr(start, end - start);
598 start = end + delimiterLength;
599 result.push_back(token);
600 }
601
602 result.push_back(fullString.substr(start));
603 return result;
604 }
605
610 auto parsePath(const std::string& pathString) -> void
611 {
612 // get rid of first token
613 std::string dir = "/";
614
615 auto nodes = splitString(pathString, dir);
616
617 for (auto itr = nodes.begin(); itr != nodes.end(); ++itr)
618 {
619 // don't do this the first time, or if we are going to add an Up
620 if (itr != nodes.begin() && *itr != "..")
621 {
622 path->appendPathNode(std::make_shared<PathDir>());
623
624 }
625 if (*itr == "..")
626 {
627 path->appendPathNode(std::make_shared<PathUp>());
628 }
629 else if (*itr == "")
630 {
631 continue;
632 }
633 else
634 {
635 path->appendPathNode(std::make_shared<PathName>(*itr));
636 }
637 }
638
639 // add a filter to the end to only look at the objects we care about
640 // if we have a range, ie a `/` at the end
641 if (nodes.back().empty())
642 {
643 if (std::is_same_v<Gobj, Component>)
644 {
645 path->appendPathNode(std::make_shared<PathFilter>(
646 [](const GameObject& g)
647 {
648 return g.isType(Type::Component);
649 }
650 ));
651 }
652 else if (std::is_same_v<Gobj, Entity>)
653 {
654 path->appendPathNode(std::make_shared<PathFilter>(
655 [](const GameObject& g)
656 {
657 return g.isType(Type::Entity);
658 }
659 ));
660 }
661 else if (!std::is_same_v<Gobj, GameObject> && !std::is_same_v<Gobj, System>)
662 {
663 path->appendPathNode(std::make_shared<PathFilter>(
664 [](const GameObject& g)
665 {
666 return !!(dynamic_cast<const Gobj*>(&g));
667 }
668 ));
669 }
670 }
671 }
672
673};
674
675
681
682}
static FMOD_RESULT result
Definition AudioObject.cpp:27
The class that holds the top node, and manages the main game loop, as well as startup and shutdown.
the base class for the engine, most things inherit from this.
One of the beginnings of a Path, where the Path starts at an arbitrary GameObject.
Given a range of GameObjects, generates a range of all of those GameObjects children.
excption emittited by Path s and their associated classes
Internal PathNode that takes a range of GameObjects on the left, and filters the range to only GameOb...
Internal PathNode that takes a range of GameObjects on the left, and filters the range to only GameOb...
Base class for a linked list of Path sections, which altogether represent the logic of a Path,...
Path Node that represents the Root object in the Engine, and provides a starting point for a Path.
Internal Path Node that takes a range of GameObjects on the left, and transforms the range into the p...
static auto getSystem() -> system *
A function to get a system.
Definition Engine.h:43
the base class for the engine, most things inherit from this.
Definition GameObject.h:77
auto isType(gobj::Type otherType) const -> bool
check whether the GameObject is the same as a given type.
Definition GameObject.cpp:260
Definition PathException.h:24
iterator type, refers to a GameObject, and holds onto a reference to a PathNode to determine its rang...
Definition PathNode.h:45
iterator member class for Path.
Definition Path.h:434
PathNode::path_iterator itr
Internal iterator type that is used by PathNode, and only refers to GameObjects as GameObjects.
Definition Path.h:531
auto operator*() const -> std::add_lvalue_reference_t< Gobj >
Gets a reference to the GameObject the iterator refers to, and casts it to Gobj as well.
Definition Path.h:510
iterator(PathNode::path_iterator itr)
constructs a Path::iterator from a PathNode::path_iterator, which is an internal type used for logic
Definition Path.h:440
auto get() const -> Gobj *
Definition Path.h:461
iterator()=default
defaults initializes iterator as a sentinel "Past the End" iterator
friend Path
Definition Path.h:446
auto operator++(int) -> iterator
post-increments the iterator, getting the next GameObject in the range
Definition Path.h:488
Gobj value_type
Definition Path.h:450
auto operator==(iterator other) const -> bool
compares if two iterators point to the same object.
Definition Path.h:500
std::ptrdiff_t difference_type
Definition Path.h:449
auto operator->() const -> Gobj *
allows for calling functions on the objects an iterator refers to.
Definition Path.h:524
auto operator++() -> iterator &
pre-increments the iterator, getting the next GameObject in the range.
Definition Path.h:477
Path(std::string pathString)
constructs a Path by parsing a string
Definition Path.h:334
auto begin() const -> iterator
Definition Path.h:545
auto end() const -> iterator
Definition Path.h:555
std::shared_ptr< PathNode > path
a pointer to the linked list of PathNodes that handles the logic for Path deduction
Definition Path.h:426
auto parsePath(const std::string &pathString) -> void
parses a Path, constructing the linked list of PathNodes, which calculate the range that a Path refer...
Definition Path.h:610
static auto splitString(const std::string &fullString, const std::string &delimiter) -> std::vector< std::string >
splits a string into many smaller strings.
Definition Path.h:587
Path(std::string pathString, GameObject &rootObject)
constructs a Path by parsing a string
Definition Path.h:382
auto operator->() const -> Gobj *
Definition Path.h:574
auto get() const -> Gobj *
Definition Path.h:565
namespace for things relating to GameObject, other than GameObject itself
Definition Entity.h:229
@ Entity
Definition GameObject.h:53
@ Component
Definition GameObject.h:54
Path Node that represents the Root object in the Engine, and provides a starting point for a Path.
Definition PathRoot.h:28