Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "stdafx.h"

#include "Headers/Localization.h"

#include "Core/Headers/ErrorCodes.h"
#include <SimpleINI/include/SimpleIni.h>

#include "Platform/File/Headers/FileManagement.h"
#include "Platform/File/Headers/FileUpdateMonitor.h"

namespace Divide {
namespace Locale {

namespace detail {
    /// Default language can be set at compile time
    stringImpl g_localeFile;

    std::unique_ptr<LanguageData> g_data = nullptr;

    /// External modification monitoring system
    std::unique_ptr<FW::FileWatcher> g_LanguageFileWatcher = nullptr;

    /// Callback for external file changes. 
    UpdateListener g_fileWatcherListener([](const char* languageFile, FileUpdateEvent evt) {
        if (evt == FileUpdateEvent::DELETE) {
            return;
        }

        // If we modify our currently active language, reinit the Locale system
        if (strcmp((g_localeFile + g_languageFileExtension).c_str(), languageFile) == 0) {
            changeLanguage(g_localeFile.c_str());
        }
    });

}; //detail

LanguageData::LanguageData()
{
}

LanguageData::~LanguageData()
{
}

void LanguageData::changeLanguage(const char* newLanguage) {
    _languageTable.clear();

    for (const DELEGATE_CBK<void, const char* /*new language*/>& languageChangeCbk : _languageChangeCallbacks) {
        languageChangeCbk(newLanguage);
    }
}

const char* LanguageData::get(U64 key, const char* defaultValue) {
    typedef hashMapImpl<U64, stringImpl>::const_iterator citer;
    // When we ask for a string for the given key, we check our language cache first
    citer entry = _languageTable.find(key);
    if (entry != std::cend(_languageTable)) {
        // Usually, the entire language table is loaded.
        return entry->second.c_str();
    }
    DIVIDE_UNEXPECTED_CALL("Locale error: INVALID STRING KEY!");

    return defaultValue;
}

void LanguageData::add(U64 key, const char* value) {
    hashAlg::emplace(_languageTable, key, value);
}

void LanguageData::addLanguageChangeCallback(const DELEGATE_CBK<void, const char* /*new language*/>& cbk) {
    _languageChangeCallbacks.push_back(cbk);
}

ErrorCode init(const char* newLanguage) {
    if (!Config::Build::IS_SHIPPING_BUILD) {
        if (!detail::g_LanguageFileWatcher) {
            detail::g_LanguageFileWatcher.reset(new FW::FileWatcher());
            detail::g_fileWatcherListener.addIgnoredEndCharacter('~');
            detail::g_fileWatcherListener.addIgnoredExtension("tmp");
            detail::g_LanguageFileWatcher->addWatch(Paths::g_exePath + Paths::g_localisationPath.c_str(), &detail::g_fileWatcherListener);
        }
    }

    if (!detail::g_data) {
        detail::g_data = std::make_unique<LanguageData>();
    }

    // Override old data
    detail::g_data->changeLanguage(newLanguage);

    // Use SimpleIni library for cross-platform INI parsing
    CSimpleIni languageFile(true, false, true);

    detail::g_localeFile = stringImpl(newLanguage);
    assert(!detail::g_localeFile.empty());

    stringImpl file = Paths::g_localisationPath + detail::g_localeFile + g_languageFileExtension;

    if (languageFile.LoadFile(file.c_str()) != SI_OK) {
        return ErrorCode::NO_LANGUAGE_INI;
    }

    // Load all key-value pairs for the "language" section
    const CSimpleIni::TKeyVal* keyValue = languageFile.GetSection("language");

    assert(keyValue != nullptr && "Locale::init error: No 'language' section found");
    // And add all pairs to the language table
    CSimpleIni::TKeyVal::const_iterator keyValuePairIt = keyValue->begin();
    for (; keyValuePairIt != keyValue->end(); ++keyValuePairIt) {
        detail::g_data->add(_ID_RT(keyValuePairIt->first.pItem), keyValuePairIt->second);
    }

    return ErrorCode::NO_ERR;
}

void clear() {
    detail::g_data.reset();
}

void idle() {
    if (detail::g_LanguageFileWatcher) {
        detail::g_LanguageFileWatcher->update();
    }
}

/// Although the language can be set at compile time, in-game options may support
/// language changes
void changeLanguage(const char* newLanguage) {
    /// Set the new language code
    init(newLanguage);
}

const char* get(U64 key, const char* defaultValue) {
    if (detail::g_data) {
        return detail::g_data->get(key, defaultValue);
    }

    return defaultValue;
}

const char* get(U64 key) {
    return get(key, "key not found");
}

void addChangeLanguageCallback(const DELEGATE_CBK<void, const char* /*new language*/>& cbk) {
    assert(detail::g_data);

    detail::g_data->addLanguageChangeCallback(cbk);
}

const stringImpl& currentLanguage() {
    return detail::g_localeFile;
}

};  // namespace Locale
};  // namespace Divide

Commits for Divide-Framework/trunk/Source Code/Utility/Localization.cpp

Diff revisions: vs.
Revision Author Commited Message
1021 Diff Diff IonutCava picture IonutCava Sun 21 Jan, 2018 22:19:16 +0000

[Ionut]
- Performance optimizations

941 Diff Diff IonutCava picture IonutCava Mon 04 Sep, 2017 20:55:02 +0000

[Ionut]
- Update CEGUI from static to dynamic config (some dlls might still be missing)
- Attempt to work around a weird string issue with the newest VS2017 update

923 Diff Diff IonutCava picture IonutCava Tue 01 Aug, 2017 22:23:24 +0000

[Ionut]
- Add (hack) new GL 4.6 KHR_NO_ERROR flag for non-GPU validated builds
- Disable GPU debug messages by default. Re-enabled only via a command line argument: “--enableGPUMessageGroups”.
- Cleanup GL texture and sampler binding
- Rework hash map insert and emplace
- Update SDL to 2.0.5

918 Diff Diff IonutCava picture IonutCava Fri 21 Jul, 2017 13:16:04 +0000

[Ionut]
- Platform code robustness tweaks

893 Diff Diff IonutCava picture IonutCava Sun 18 Jun, 2017 17:33:07 +0000

[Ionut]
- Initial implementation of a PipelineStateObject (holds shader program, rasterizer state, etc)
- Rework PCH implementation a bit because VS2017 no longer has a /ZM option

890 Diff Diff IonutCava picture IonutCava Sun 14 May, 2017 20:54:59 +0000

[Ionut]
- Add pre-compiled header support
- Initial code for per-stage tessellation computation

846 Diff Diff IonutCava picture IonutCava Fri 03 Feb, 2017 22:41:05 +0000

[IonutCava]
- More scripting work

845 Diff Diff IonutCava picture IonutCava Fri 03 Feb, 2017 14:36:26 +0000

[IonutCava]
- Hot reloading system cleanup
- More script system bug fixes

844 Diff Diff IonutCava picture IonutCava Thu 02 Feb, 2017 21:49:28 +0000

[IonutCava]
- More scripting prep work and experiments

842 IonutCava picture IonutCava Wed 01 Feb, 2017 17:25:15 +0000

[IonutCava]
- Start to implement scripting support via ChaiScript: http://chaiscript.com/
- Cleanup DELEGATE_CBK alias